summaryrefslogtreecommitdiff
path: root/zebra/connected.c
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-05-11 15:57:39 -0400
committerMark Stapp <mjs@voltanet.io>2021-05-12 09:37:00 -0400
commite3d901f8638dec32eac4c2690912138963ae5a05 (patch)
tree8b61690f526d085040cc5bd8e1ea98a5ec9f8683 /zebra/connected.c
parent449e54fd12372273dcac68781eb77c1297aeb2ba (diff)
lib,zebra: Use a flag to track down status for connected addrs
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>
Diffstat (limited to 'zebra/connected.c')
-rw-r--r--zebra/connected.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index 1e03f8b639..883334d509 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -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;
}