summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSri Mohana Singamsetty <srimohans@gmail.com>2019-03-04 20:45:44 -0800
committerGitHub <noreply@github.com>2019-03-04 20:45:44 -0800
commit1ac29269cdfee4ed07c0a165329233eecfefe465 (patch)
treefbdc965700df4a73c5594da33b4ceca08dd670d9
parent94b4f0860197b9f180ac9de7160e85c3c1dfceb7 (diff)
parent5c14a191826ea67cdc4499fbc714b76b70cd7998 (diff)
Merge pull request #3848 from chiragshah6/evpn_dev2
bgpd: evpn reject bgp update to overwrite self mac as part of router-mac ext. community
-rw-r--r--bgpd/bgp_attr.c14
-rw-r--r--bgpd/bgp_attr_evpn.c6
-rw-r--r--bgpd/bgp_attr_evpn.h2
-rw-r--r--bgpd/bgp_mac.c33
-rw-r--r--bgpd/bgp_mac.h1
-rw-r--r--bgpd/bgp_route.c2
6 files changed, 47 insertions, 11 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
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 666254a620..a83e4419e4 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3094,7 +3094,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
goto filtered;
}
- if (bgp_mac_entry_exists(p)) {
+ if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
reason = "self mac;";
goto filtered;
}