As per draft-ietf-bess-evpn-inter-subnet-forwarding-01, chapter 6.1,
a new extended community called router's MAC Extended Community is
provided. This community is appended to extended community list.
Note that a show API has been changed in order to be able to not
display (or not) this new type.

Signed-off-by: Philippe Guibert <philippe.guib...@6wind.com>
---
 bgpd/bgp_clist.c      |  4 ++--
 bgpd/bgp_ecommunity.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++-----
 bgpd/bgp_ecommunity.h |  5 ++++-
 bgpd/bgpd.c           |  8 +++++--
 4 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index bb06028b0ca7..697fcef285ec 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -807,14 +807,14 @@ extcommunity_list_set (struct community_list_handler *ch,
     }
 
   if (ecom)
-    ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);
+    ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
 
   entry = community_entry_new ();
   entry->direct = direct;
   entry->style = style;
   entry->any = (str ? 0 : 1);
   if (ecom)
-    entry->config = ecommunity_ecom2str (ecom, 
ECOMMUNITY_FORMAT_COMMUNITY_LIST);
+    entry->config = ecommunity_ecom2str (ecom, 
ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
   else if (regex)
     entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);
   else
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index 5d69b42c310f..79b7af075e9f 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -58,7 +58,7 @@ ecommunity_free (struct ecommunity **ecom)
    structure, we don't add the value.  Newly added value is sorted by
    numerical order.  When the value is added to the structure return 1
    else return 0.  */
-static int
+int
 ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val *eval)
 {
   u_int8_t *p;
@@ -166,7 +166,7 @@ char *
 ecommunity_str (struct ecommunity *ecom)
 {
   if (! ecom->str)
-    ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);
+    ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
   return ecom->str;
 }
 
@@ -204,7 +204,7 @@ ecommunity_intern (struct ecommunity *ecom)
   find->refcnt++;
 
   if (! find->str)
-    find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY);
+    find->str = ecommunity_ecom2str (find, ECOMMUNITY_FORMAT_DISPLAY, 0);
 
   return find;
 }
@@ -585,9 +585,12 @@ ecommunity_str2com (const char *str, int type, int 
keyword_included)
    ECOMMUNITY_FORMAT_ROUTE_MAP
    ECOMMUNITY_FORMAT_COMMUNITY_LIST
    ECOMMUNITY_FORMAT_DISPLAY
+
+   Filter is added to display only ECOMMUNITY_ROUTE_TARGET in some cases. 
+   0 value displays all
 */
 char *
-ecommunity_ecom2str (struct ecommunity *ecom, int format)
+ecommunity_ecom2str (struct ecommunity *ecom, int format, int filter)
 {
   int i;
   u_int8_t *pnt;
@@ -652,6 +655,11 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format)
           break;
 
         case ECOMMUNITY_ENCODE_OPAQUE:
+          if(filter == ECOMMUNITY_ROUTE_TARGET)
+            {
+              first = 0;
+              continue;
+            }
           if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP)
             {
               uint16_t tunneltype;
@@ -662,8 +670,32 @@ ecommunity_ecom2str (struct ecommunity *ecom, int format)
               first = 0;
               continue;
             }
-            /* fall through */
-
+          len = sprintf (str_buf + str_pnt, "?");
+          str_pnt += len;
+          first = 0;
+          continue;
+        case ECOMMUNITY_ENCODE_EVPN:
+          if(filter == ECOMMUNITY_ROUTE_TARGET)
+            {
+              first = 0;
+              continue;
+            }
+          if (*pnt == ECOMMUNITY_SITE_ORIGIN)
+            {
+              char macaddr[6];
+              pnt++;
+              memcpy(&macaddr, pnt, 6);
+              len = sprintf(str_buf + str_pnt, 
"EVPN:%02x:%02x:%02x:%02x:%02x:%02x",
+                            macaddr[0], macaddr[1], macaddr[2],
+                            macaddr[3], macaddr[4], macaddr[5]);
+              str_pnt += len;
+              first = 0;
+              continue;
+            }
+          len = sprintf (str_buf + str_pnt, "?");
+          str_pnt += len;
+          first = 0;
+          continue;
         default:
           len = sprintf (str_buf + str_pnt, "?");
           str_pnt += len;
@@ -774,3 +806,20 @@ ecommunity_match (const struct ecommunity *ecom1,
     return 0;
 }
 
+/* return first occurence of type */
+extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity 
*ecom, uint8_t type)
+{
+  u_int8_t *p;
+  int c;
+  struct ecommunity_val *ecom_val;
+
+  /* If the value already exists in the structure return 0.  */
+  c = 0;
+  for (p = ecom->val; c < ecom->size; p += ECOMMUNITY_SIZE, c++)
+    {
+      ecom_val = (struct ecommunity_val *)p;
+      if(ecom_val->val[0] == type)
+        return ecom_val;
+    }
+  return NULL;
+}
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index 993fd5acfd44..05ae932a44c4 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, 
Boston, MA
 #define ECOMMUNITY_ENCODE_IP                0x01
 #define ECOMMUNITY_ENCODE_AS4               0x02
 #define ECOMMUNITY_ENCODE_OPAQUE            0x03
+#define ECOMMUNITY_ENCODE_EVPN              0x06
 
 /* Low-order octet of the Extended Communities type field.  */
 #define ECOMMUNITY_ROUTE_TARGET             0x02
@@ -81,8 +82,10 @@ extern int ecommunity_cmp (const void *, const void *);
 extern void ecommunity_unintern (struct ecommunity **);
 extern unsigned int ecommunity_hash_make (void *);
 extern struct ecommunity *ecommunity_str2com (const char *, int, int);
-extern char *ecommunity_ecom2str (struct ecommunity *, int);
+extern char *ecommunity_ecom2str (struct ecommunity *, int, int);
 extern int ecommunity_match (const struct ecommunity *, const struct 
ecommunity *);
 extern char *ecommunity_str (struct ecommunity *);
+extern struct ecommunity_val *ecommunity_lookup (const struct ecommunity *, 
uint8_t );
+extern int ecommunity_add_val (struct ecommunity *ecom, struct ecommunity_val 
*eval);
 
 #endif /* _QUAGGA_BGP_ECOMMUNITY_H */
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 020182af6e55..2833b6e8751f 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -5821,7 +5821,9 @@ bgp_config_write (struct vty *vty)
             vty_out(vty, " vrf rd %s%s", str_p == NULL?"<err>":str_p, 
VTY_NEWLINE);
             if(vrf->rt_import)
               {
-                str2_p = ecommunity_ecom2str (vrf->rt_import, 
ECOMMUNITY_FORMAT_ROUTE_MAP);
+                str2_p = ecommunity_ecom2str (vrf->rt_import,
+                                              ECOMMUNITY_FORMAT_ROUTE_MAP,
+                                              ECOMMUNITY_ROUTE_TARGET);
                 if(str2_p)
                   {
                     vty_out(vty, " vrf rd %s import %s%s", str_p == 
NULL?"<err>":str_p, str2_p, VTY_NEWLINE);
@@ -5830,7 +5832,9 @@ bgp_config_write (struct vty *vty)
               }
             if(vrf->rt_export)
               {
-                str2_p = ecommunity_ecom2str (vrf->rt_export, 
ECOMMUNITY_FORMAT_ROUTE_MAP);
+                str2_p = ecommunity_ecom2str (vrf->rt_export,
+                                              ECOMMUNITY_FORMAT_ROUTE_MAP,
+                                              ECOMMUNITY_ROUTE_TARGET);
                 if(str2_p)
                   {
                     vty_out(vty, " vrf rd %s export %s%s", str_p == 
NULL?"<err>":str_p, str2_p, VTY_NEWLINE);
-- 
2.1.4


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to