From 6041b6864db54ad89674f8c757fb8c935bb9f9fe Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 26 Jul 2019 14:57:59 -0700 Subject: [PATCH] zebra: del auto mac when vni is down Delete an auto MAC with no neighbor associated, when its VNI is down. In Following sequence stale MAC entry retained in FRR (zebra). - Local MAC-IP pair - MAC is deleted in bridge fdb table - VNI is down, triggers IP (neigh) entries removed from FRR DB. - MAC retained as AUTO MAC with neigh list count 0. - When VNI is UP again, stale MAC entry retained in FRR DB. When the MAC-IP pair moves behind remote VTEP, local VTEP fails to add remote entry as its MAC is in auto state. Ticket:CM-25504 Reviewed By: Testing Done: Validated the sequence with fix and auto MAC is deleted when VNI is down. When VNI comes up, the remote MAC-IP is added to FRR (Zebra) and kernel. Signed-off-by: Chirag Shah --- zebra/zebra_vxlan.c | 49 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 2974a374de..2e8c81bddd 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3403,6 +3403,39 @@ static int zvni_mac_del(zebra_vni_t *zvni, zebra_mac_t *mac) return 0; } +static bool zvni_check_mac_del_from_db(struct mac_walk_ctx *wctx, + zebra_mac_t *mac) +{ + if ((wctx->flags & DEL_LOCAL_MAC) && + (mac->flags & ZEBRA_MAC_LOCAL)) + return true; + else if ((wctx->flags & DEL_REMOTE_MAC) && + (mac->flags & ZEBRA_MAC_REMOTE)) + return true; + else if ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP) && + (mac->flags & ZEBRA_MAC_REMOTE) && + IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)) + return true; + else if ((wctx->flags & DEL_LOCAL_MAC) && + (mac->flags & ZEBRA_MAC_AUTO) && + !listcount(mac->neigh_list)) { + if (IS_ZEBRA_DEBUG_VXLAN) { + char buf[ETHER_ADDR_STRLEN]; + + zlog_debug("%s: Del MAC %s flags 0x%x", + __PRETTY_FUNCTION__, + prefix_mac2str(&mac->macaddr, + buf, sizeof(buf)), + mac->flags); + } + wctx->uninstall = 0; + + return true; + } + + return false; +} + /* * Free MAC hash entry (callback) */ @@ -3411,18 +3444,11 @@ static void zvni_mac_del_hash_entry(struct hash_bucket *bucket, void *arg) struct mac_walk_ctx *wctx = arg; zebra_mac_t *mac = bucket->data; - if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL)) - || ((wctx->flags & DEL_REMOTE_MAC) - && (mac->flags & ZEBRA_MAC_REMOTE)) - || ((wctx->flags & DEL_REMOTE_MAC_FROM_VTEP) - && (mac->flags & ZEBRA_MAC_REMOTE) - && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, - &wctx->r_vtep_ip))) { + if (zvni_check_mac_del_from_db(wctx, mac)) { if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) { zvni_mac_send_del_to_client(wctx->zvni->vni, &mac->macaddr); } - if (wctx->uninstall) zvni_mac_uninstall(wctx->zvni, mac); @@ -7269,8 +7295,13 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, * of a VxLAN bridge. */ zvni = zvni_from_svi(ifp, link_if); - if (!zvni) + if (!zvni) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s: Del neighbor %s VNI is not present for interface %s", + __PRETTY_FUNCTION__, + ipaddr2str(ip, buf, sizeof(buf)), ifp->name); return 0; + } if (!zvni->vxlan_if) { zlog_debug( -- 2.39.5