From eee353c5565fff0cd7d3d4656065c5267fabec07 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 19 Feb 2019 16:02:00 -0800 Subject: [PATCH] bgpd: parse and comapre rmac attr against self mac Any evpn bgp update message comes with router mac extended community, which can potentially contain the madd adddress same as any of the local SVIs (L3VNI) MAC address. Set route mac exist and during route processing in bgp_update() filter the route. Ticket:CM-23674 Reviewed By:CCR-8336 Testing Done: Configure L3vni mac on TORS1 which is similar to TORC11 L3vni MAC. When TORC11 received the EVPN update with Router mac extended community, this check rejected the BGP update message. Signed-off-by: Chirag Shah --- bgpd/bgp_attr.c | 14 +++++++++++++- bgpd/bgp_attr_evpn.c | 6 ++++-- bgpd/bgp_attr_evpn.h | 2 +- bgpd/bgp_mac.c | 33 +++++++++++++++++++++++++++------ bgpd/bgp_mac.h | 1 + 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index e731af754c..4c6da724b1 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -54,6 +54,7 @@ #include "bgp_encap_types.h" #include "bgp_evpn.h" #include "bgp_flowspec_private.h" +#include "bgp_mac.h" /* Attribute strings for logging. */ static const struct message attr_str[] = { @@ -1944,7 +1945,18 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) bgp_attr_evpn_na_flag(attr, &attr->router_flag); /* Extract the Rmac, if any */ - bgp_attr_rmac(attr, &attr->rmac); + if (bgp_attr_rmac(attr, &attr->rmac)) { + if (bgp_debug_update(peer, NULL, NULL, 1) && + bgp_mac_exist(&attr->rmac)) { + char buf1[ETHER_ADDR_STRLEN]; + + zlog_debug("%s: router mac %s is self mac", + __func__, + prefix_mac2str(&attr->rmac, buf1, + sizeof(buf1))); + } + + } return BGP_ATTR_PARSE_PROCEED; } diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 3e9d05ad97..208a9d4705 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -106,14 +106,14 @@ char *ecom_mac2str(char *ecom_mac) } /* Fetch router-mac from extended community */ -void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) +bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) { int i = 0; struct ecommunity *ecom; ecom = attr->ecommunity; if (!ecom || !ecom->size) - return; + return false; /* If there is a router mac extended community, set RMAC in attr */ for (i = 0; i < ecom->size; i++) { @@ -130,7 +130,9 @@ void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) continue; memcpy(rmac, pnt, ETH_ALEN); + return true; } + return false; } /* diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index b036702151..5b0ce1da28 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -60,7 +60,7 @@ extern void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac); extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag, struct prefix *dst); -extern void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac); +extern bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac); extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky); extern uint8_t bgp_attr_default_gw(struct attr *attr); diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 4a408df858..49b5854020 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -311,11 +311,35 @@ void bgp_mac_del_mac_entry(struct interface *ifp) bgp_mac_remove_ifp_internal(bsm, ifp->name); } -bool bgp_mac_entry_exists(struct prefix *p) +/* This API checks MAC address against any of local + * assigned (SVIs) MAC address. + * An example: router-mac attribute in any of evpn update + * requires to compare against local mac. + */ +bool bgp_mac_exist(struct ethaddr *mac) { - struct prefix_evpn *pevpn = (struct prefix_evpn *)p; struct bgp_self_mac lookup; struct bgp_self_mac *bsm; + static uint8_t tmp [ETHER_ADDR_STRLEN] = {0}; + + if (memcmp(mac, &tmp, ETH_ALEN) == 0) + return false; + + memcpy(&lookup.macaddr, mac, ETH_ALEN); + bsm = hash_lookup(bm->self_mac_hash, &lookup); + if (!bsm) + return false; + + return true; +} + +/* This API checks EVPN type-2 prefix and comapares + * mac against any of local assigned (SVIs) MAC + * address. + */ +bool bgp_mac_entry_exists(struct prefix *p) +{ + struct prefix_evpn *pevpn = (struct prefix_evpn *)p; if (pevpn->family != AF_EVPN) return false; @@ -323,10 +347,7 @@ bool bgp_mac_entry_exists(struct prefix *p) if (pevpn->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE) return false; - memcpy(&lookup.macaddr, &p->u.prefix_evpn.macip_addr.mac, ETH_ALEN); - bsm = hash_lookup(bm->self_mac_hash, &lookup); - if (!bsm) - return false; + return bgp_mac_exist(&p->u.prefix_evpn.macip_addr.mac); return true; } diff --git a/bgpd/bgp_mac.h b/bgpd/bgp_mac.h index 1dd987ef12..68449b574a 100644 --- a/bgpd/bgp_mac.h +++ b/bgpd/bgp_mac.h @@ -37,5 +37,6 @@ void bgp_mac_dump_table(struct vty *vty); * Function to lookup the prefix and see if we have a matching mac */ bool bgp_mac_entry_exists(struct prefix *p); +bool bgp_mac_exist(struct ethaddr *mac); #endif -- 2.39.5