From 29c2ce7cfc283337e60d5498fb72f291528603b4 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Wed, 15 Aug 2018 13:32:03 -0700 Subject: [PATCH] zebra: check router_flag change for neigh update Neigh update can have router_flag change, from unset to set and viceversa. This is the case where MAC, IP and VLAN are same but entry's flag moved from R to not R bit and reverse case. Router flag change needs to trigger bgpd to inform all evpn peers to remove from the evpn route. Testing Done: Send GARP with and without R bit from host and validate neigh entry and evpn neigh and mac-ip route entry in zebra and bgpd. Check Peer VTEP evpn route entry where router flag is (un)set. With R-bit Route [2]:[0]:[0]:[48]:[00:1f:2f:db:45:a6]:[128]:[2006:33:33:2::10] VNI 1001 Imported from 27.0.0.16:5:[2]:[0]:[0]:[48]:[00:1f:2f:db:45:a6]:[128]:[2006:33:33:2::10] 4435 5551 27.0.0.16 from MSP1(uplink-1) (27.0.0.9) Origin IGP, valid, external, bestpath-from-AS 4435, best Extended Community: RT:5551:1001 ET:8 ND:Router Flag AddPath ID: RX 0, TX 1261 Last update: Wed Aug 15 20:52:14 2018 Without R-bit Route [2]:[0]:[0]:[48]:[00:1f:2f:db:45:a6]:[128]:[2006:33:33:2::10] VNI 1001 Imported from 27.0.0.16:5:[2]:[0]:[0]:[48]:[00:1f:2f:db:45:a6]:[128]:[2006:33:33:2::10] 4435 5551 27.0.0.16 from MSP2(uplink-2) (27.0.0.10) Origin IGP, valid, external, bestpath-from-AS 4435, best Extended Community: RT:5551:1001 ET:8 AddPath ID: RX 0, TX 1263 Last update: Wed Aug 15 20:53:10 2018 Signed-off-by: Chirag Shah --- zebra/zebra_vxlan.c | 59 ++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index a4f5f7b95..0b034fd3b 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1961,6 +1961,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, char buf2[INET6_ADDRSTRLEN]; zebra_neigh_t *n = NULL; zebra_mac_t *zmac = NULL, *old_zmac = NULL; + bool check_rbit = false; /* create a dummy MAC if the MAC is not already present */ zmac = zvni_mac_lookup(zvni, macaddr); @@ -1990,34 +1991,40 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n = zvni_neigh_lookup(zvni, ip); if (n) { if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) { + + if (router_flag != + (CHECK_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG) + ? 1 : 0)) + check_rbit = true; + if (memcmp(n->emac.octet, macaddr->octet, ETH_ALEN) == 0) { /* Update any params and return - client doesn't * care about a purely local change. */ n->ifindex = ifp->ifindex; - return 0; - } + } else { - /* If the MAC has changed, - * need to issue a delete first - * as this means a different MACIP route. - * Also, need to do some unlinking/relinking. - */ - zvni_neigh_send_del_to_client(zvni->vni, &n->ip, + /* If the MAC has changed, + * need to issue a delete first + * as this means a different MACIP route. + * Also, need to do some unlinking/relinking. + */ + zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0); - old_zmac = zvni_mac_lookup(zvni, &n->emac); - if (old_zmac) { - listnode_delete(old_zmac->neigh_list, n); - zvni_deref_ip2mac(zvni, old_zmac, 0); - } + old_zmac = zvni_mac_lookup(zvni, &n->emac); + if (old_zmac) { + listnode_delete(old_zmac->neigh_list, n); + zvni_deref_ip2mac(zvni, old_zmac, 0); + } - /* Update the forwarding info. */ - n->ifindex = ifp->ifindex; - memcpy(&n->emac, macaddr, ETH_ALEN); + /* Update the forwarding info. */ + n->ifindex = ifp->ifindex; + memcpy(&n->emac, macaddr, ETH_ALEN); - /* Link to new MAC */ - listnode_add_sort(zmac->neigh_list, n); + /* Link to new MAC */ + listnode_add_sort(zmac->neigh_list, n); + } } else /* Neighbor has moved from remote to local. */ @@ -2042,6 +2049,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, n->r_vtep_ip.s_addr = 0; SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); n->ifindex = ifp->ifindex; + check_rbit = true; } } else { /* New neighbor - create */ @@ -2058,6 +2066,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, /* Set "local" forwarding info. */ SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL); n->ifindex = ifp->ifindex; + check_rbit = true; } /*Mark Router flag (R-bit) */ @@ -2072,11 +2081,21 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni, if (!CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( - "Skipping neigh %s add to client as MAC %s is not local on VNI %u", + "Skipping neigh %s add to client as MAC %s is not local on VNI %u with flags 0x%x", ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), - zvni->vni); + zvni->vni, n->flags); + + return 0; + } + if (!check_rbit) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "Skipping neigh %s with MAC %s on VNI %u add to client as router flag is not set.", + ipaddr2str(ip, buf2, sizeof(buf2)), + prefix_mac2str(macaddr, buf, sizeof(buf)), + zvni->vni); return 0; } -- 2.39.5