From: Chirag Shah Date: Fri, 26 Jul 2019 21:57:59 +0000 (-0700) Subject: zebra: del auto mac when vni is down X-Git-Tag: base_7.2~90^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=6041b6864db54ad89674f8c757fb8c935bb9f9fe;p=mirror%2Ffrr.git 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 --- 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(