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