]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: del auto mac when vni is down 4752/head
authorChirag Shah <chirag@cumulusnetworks.com>
Fri, 26 Jul 2019 21:57:59 +0000 (14:57 -0700)
committerChirag Shah <chirag@cumulusnetworks.com>
Thu, 1 Aug 2019 20:21:01 +0000 (13:21 -0700)
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 <chirag@cumulusnetworks.com>
zebra/zebra_vxlan.c

index 2974a374dea094a7acd979bcfd89dc48da43a184..2e8c81bddd1021cd8bf32816916e916a8619e07e 100644 (file)
@@ -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(