Merge pull request #8659 from mjstapp/fix_connected_multi

lib,zebra: Use a flag to track down status for connected addrs
This commit is contained in:
Donald Sharp 2021-05-13 07:23:42 -04:00 committed by GitHub
commit e524fc1e2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 5 deletions

View File

@ -393,6 +393,7 @@ struct connected {
#define ZEBRA_IFC_REAL (1 << 0) #define ZEBRA_IFC_REAL (1 << 0)
#define ZEBRA_IFC_CONFIGURED (1 << 1) #define ZEBRA_IFC_CONFIGURED (1 << 1)
#define ZEBRA_IFC_QUEUED (1 << 2) #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 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 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 in the kernel. It may and should be set although the address might
not be not be
usable yet. (compare with ZEBRA_IFC_REAL) 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. */ /* Flags for connected address. */

View File

@ -38,7 +38,6 @@
#include "zebra/connected.h" #include "zebra/connected.h"
#include "zebra/rtadv.h" #include "zebra/rtadv.h"
#include "zebra/zebra_mpls.h" #include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
#include "zebra/zebra_errors.h" #include "zebra/zebra_errors.h"
#include "zebra/zebra_router.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)) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
return; return;
/* Ensure 'down' flag is cleared */
UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
PREFIX_COPY(&p, CONNECTED_PREFIX(ifc)); PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
/* Apply mask to the network. */ /* Apply mask to the network. */
@ -280,7 +282,8 @@ void connected_up(struct interface *ifp, struct connected *ifc)
PREFIX_COPY(&cp, CONNECTED_PREFIX(c)); PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
apply_mask(&cp); apply_mask(&cp);
if (prefix_same(&cp, &p)) if (prefix_same(&cp, &p) &&
!CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
count++; count++;
if (count >= 2) if (count >= 2)
@ -390,7 +393,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)
if (!zvrf) { if (!zvrf) {
flog_err( flog_err(
EC_ZEBRA_VRF_NOT_FOUND, 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); __func__, ifp->vrf_id);
return; return;
} }
@ -398,6 +401,17 @@ void connected_down(struct interface *ifp, struct connected *ifc)
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
return; 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)); PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
/* Apply mask to the network. */ /* Apply mask to the network. */
@ -423,6 +437,9 @@ void connected_down(struct interface *ifp, struct connected *ifc)
break; break;
} }
/* Mark the address as 'down' */
SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
/* /*
* It's possible to have X number of addresses * It's possible to have X number of addresses
* on a interface that all resolve to the same * 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)); PREFIX_COPY(&cp, CONNECTED_PREFIX(c));
apply_mask(&cp); apply_mask(&cp);
if (prefix_same(&p, &cp)) if (prefix_same(&p, &cp) &&
!CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
count++; count++;
if (count >= 2) if (count >= 1)
return; return;
} }