diff options
| author | Mark Stapp <mjs@voltanet.io> | 2021-05-11 15:57:39 -0400 | 
|---|---|---|
| committer | Mark Stapp <mjs@voltanet.io> | 2021-05-12 09:37:00 -0400 | 
| commit | e3d901f8638dec32eac4c2690912138963ae5a05 (patch) | |
| tree | 8b61690f526d085040cc5bd8e1ea98a5ec9f8683 /zebra/connected.c | |
| parent | 449e54fd12372273dcac68781eb77c1297aeb2ba (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.c | 28 | 
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;  	}  | 
