Mailing List Archive

[PATCH 35/57] bgpd: support for router mac extended community
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.guibert@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