]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: parse and comapre rmac attr against self mac
authorChirag Shah <chirag@cumulusnetworks.com>
Wed, 20 Feb 2019 00:02:00 +0000 (16:02 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Mon, 4 Mar 2019 17:56:05 +0000 (09:56 -0800)
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 <chirag@cumulusnetworks.com>
bgpd/bgp_attr.c
bgpd/bgp_attr_evpn.c
bgpd/bgp_attr_evpn.h
bgpd/bgp_mac.c
bgpd/bgp_mac.h

index e731af754cc05c9fbbf94be31afaed105e951d90..4c6da724b1bc54cad17fe91f6325abd9f5495a38 100644 (file)
@@ -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;
 }
index 3e9d05ad978c905a4d14005890530500e698b0eb..208a9d4705f236a426f3c98034fcc95f11340539 100644 (file)
@@ -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;
 }
 
 /*
index b036702151d0e01957bec7d693bd765a1374dd6d..5b0ce1da2886ec290a752f1d87de634ba7682f92 100644 (file)
@@ -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);
index 4a408df858052be4a26fb8b21c444267559d9828..49b585402090352723efee25f32948c72f0a6a10 100644 (file)
@@ -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;
 }
index 1dd987ef12c78fd5be929adadf5880144bdd57d3..68449b574ab3062e8cf84b5c2dd9b26617467fb4 100644 (file)
@@ -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