]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib,zebra: Use a flag to track down status for connected addrs 8659/head
authorMark Stapp <mjs@voltanet.io>
Tue, 11 May 2021 19:57:39 +0000 (15:57 -0400)
committerMark Stapp <mjs@voltanet.io>
Wed, 12 May 2021 13:37:00 +0000 (09:37 -0400)
Track 'down' state of connected addresses with a new flag. We
may have multiple addresses on an interface that share a prefix;
in those cases, we need to determine when the first address
is valid, to install a connected route, and similarly detect
when the last address goes 'down', to remove the connected
route.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
lib/if.h
zebra/connected.c

index f425ba8bceaa7e2345dd9c880a548be8cb8bb9bf..0d689fe14b9513c0bc034f36b441b4baac450a8a 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -393,6 +393,7 @@ struct connected {
 #define ZEBRA_IFC_REAL         (1 << 0)
 #define ZEBRA_IFC_CONFIGURED   (1 << 1)
 #define ZEBRA_IFC_QUEUED       (1 << 2)
+#define ZEBRA_IFC_DOWN         (1 << 3)
        /*
           The ZEBRA_IFC_REAL flag should be set if and only if this address
           exists in the kernel and is actually usable. (A case where it exists
@@ -406,6 +407,8 @@ struct connected {
           in the kernel. It may and should be set although the address might
           not be
           usable yet. (compare with ZEBRA_IFC_REAL)
+          The ZEBRA_IFC_DOWN flag is used to record that an address is
+          present, but down/unavailable.
         */
 
        /* Flags for connected address. */
index 1e03f8b639b8a08ef8a10ec7f179857e7f366fbf..883334d509b610b17ee8a21ccd6bb1b630cce4e1 100644 (file)
@@ -38,7 +38,6 @@
 #include "zebra/connected.h"
 #include "zebra/rtadv.h"
 #include "zebra/zebra_mpls.h"
-#include "zebra/debug.h"
 #include "zebra/zebra_errors.h"
 #include "zebra/zebra_router.h"
 
@@ -223,6 +222,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
                return;
 
+       /* Ensure 'down' flag is cleared */
+       UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
+
        PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
 
        /* Apply mask to the network. */
@@ -280,7 +282,8 @@ void connected_up(struct interface *ifp, struct connected *ifc)
                PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
                apply_mask(&cp);
 
-               if (prefix_same(&cp, &p))
+               if (prefix_same(&cp, &p) &&
+                   !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
                        count++;
 
                if (count >= 2)
@@ -390,7 +393,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
        if (!zvrf) {
                flog_err(
                        EC_ZEBRA_VRF_NOT_FOUND,
-                       "%s: Received Up for interface but no associated zvrf: %d",
+                       "%s: Received Down for interface but no associated zvrf: %d",
                        __func__, ifp->vrf_id);
                return;
        }
@@ -398,6 +401,17 @@ void connected_down(struct interface *ifp, struct connected *ifc)
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
                return;
 
+       /* Skip if we've already done this; this can happen if we have a
+        * config change that takes an interface down, then we receive kernel
+        * notifications about the downed interface and its addresses.
+        */
+       if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_DOWN)) {
+               if (IS_ZEBRA_DEBUG_RIB)
+                       zlog_debug("%s: ifc %p, %pFX already DOWN",
+                                  __func__, ifc, ifc->address);
+               return;
+       }
+
        PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
 
        /* Apply mask to the network. */
@@ -423,6 +437,9 @@ void connected_down(struct interface *ifp, struct connected *ifc)
                break;
        }
 
+       /* Mark the address as 'down' */
+       SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
+
        /*
         * It's possible to have X number of addresses
         * on a interface that all resolve to the same
@@ -436,10 +453,11 @@ void connected_down(struct interface *ifp, struct connected *ifc)
                PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
                apply_mask(&cp);
 
-               if (prefix_same(&p, &cp))
+               if (prefix_same(&p, &cp) &&
+                   !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
                        count++;
 
-               if (count >= 2)
+               if (count >= 1)
                        return;
        }