summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/if_netlink.c22
-rw-r--r--zebra/interface.c45
-rw-r--r--zebra/zebra_dplane.c15
-rw-r--r--zebra/zebra_dplane.h5
4 files changed, 52 insertions, 35 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 2467e837b8..3591106fed 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -852,7 +852,8 @@ static void netlink_proc_dplane_if_protodown(struct zebra_if *zif,
* If the reason we got from the kernel is ONLY frr though, don't
* set it.
*/
- if (protodown && is_if_protodown_r_only_frr(rc_bitfield) == false)
+ if (protodown && rc_bitfield &&
+ is_if_protodown_r_only_frr(rc_bitfield) == false)
zif->protodown_rc |= ZEBRA_PROTODOWN_EXTERNAL;
else
zif->protodown_rc &= ~ZEBRA_PROTODOWN_EXTERNAL;
@@ -900,7 +901,8 @@ static uint8_t netlink_parse_lacp_bypass(struct rtattr **linkinfo)
}
/*
- * Only called at startup to cleanup leftover protodown we may have not cleanup
+ * Only called at startup to cleanup leftover protodown reasons we may
+ * have not cleaned up. We leave protodown set though.
*/
static void if_sweep_protodown(struct zebra_if *zif)
{
@@ -912,12 +914,12 @@ static void if_sweep_protodown(struct zebra_if *zif)
return;
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("interface %s sweeping protdown %s", zif->ifp->name,
- protodown ? "on" : "off");
+ zlog_debug("interface %s sweeping protodown %s reason 0x%x",
+ zif->ifp->name, protodown ? "on" : "off",
+ zif->protodown_rc);
/* Only clear our reason codes, leave external if it was set */
- zif->protodown_rc |= ~ZEBRA_PROTODOWN_ALL;
- zif->flags |= ZIF_FLAG_UNSET_PROTODOWN;
+ zif->protodown_rc &= ~ZEBRA_PROTODOWN_ALL;
dplane_intf_update(zif->ifp);
}
@@ -2158,6 +2160,7 @@ ssize_t netlink_intf_msg_encode(uint16_t cmd,
struct rtattr *nest_protodown_reason;
ifindex_t ifindex = dplane_ctx_get_ifindex(ctx);
bool down = dplane_ctx_intf_is_protodown(ctx);
+ bool pd_reason_val = dplane_ctx_get_intf_pd_reason_val(ctx);
struct nlsock *nl =
kernel_netlink_nlsock_lookup(dplane_ctx_get_ns_sock(ctx));
@@ -2191,13 +2194,14 @@ ssize_t netlink_intf_msg_encode(uint16_t cmd,
nl_attr_put32(&req->n, buflen, IFLA_PROTO_DOWN_REASON_MASK,
(1 << frr_protodown_r_bit));
nl_attr_put32(&req->n, buflen, IFLA_PROTO_DOWN_REASON_VALUE,
- ((int)down) << frr_protodown_r_bit);
+ ((int)pd_reason_val) << frr_protodown_r_bit);
nl_attr_nest_end(&req->n, nest_protodown_reason);
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: %s, protodown=%d ifindex=%u", __func__,
- nl_msg_type_to_str(cmd), down, ifindex);
+ zlog_debug("%s: %s, protodown=%d reason_val=%d ifindex=%u",
+ __func__, nl_msg_type_to_str(cmd), down,
+ pd_reason_val, ifindex);
return NLMSG_ALIGN(req->n.nlmsg_len);
}
diff --git a/zebra/interface.c b/zebra/interface.c
index 6fb34d59ac..167f1b4587 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -63,6 +63,8 @@ DEFINE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
static void if_down_del_nbr_connected(struct interface *ifp);
+static int zebra_if_update_protodown(struct interface *ifp, bool new_down,
+ uint32_t new_protodown_rc);
static void if_zebra_speed_update(struct thread *thread)
{
@@ -261,11 +263,12 @@ static int if_zebra_delete_hook(struct interface *ifp)
if (ifp->info) {
zebra_if = ifp->info;
- /* If we set protodown, clear it now from the kernel */
- if (ZEBRA_IF_IS_PROTODOWN(zebra_if) &&
+ /* If we set protodown, clear our reason now from the kernel */
+ if (ZEBRA_IF_IS_PROTODOWN(zebra_if) && zebra_if->protodown_rc &&
!ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zebra_if))
- zebra_if_set_protodown(ifp, false, ZEBRA_PROTODOWN_ALL);
-
+ zebra_if_update_protodown(ifp, true,
+ (zebra_if->protodown_rc &
+ ~ZEBRA_PROTODOWN_ALL));
/* Free installed address chains tree. */
if (zebra_if->ipv4_subnets)
@@ -1291,19 +1294,13 @@ static bool if_ignore_set_protodown(const struct interface *ifp, bool new_down,
return false;
}
-int zebra_if_set_protodown(struct interface *ifp, bool new_down,
- enum protodown_reasons new_reason)
+static int zebra_if_update_protodown(struct interface *ifp, bool new_down,
+ uint32_t new_protodown_rc)
{
struct zebra_if *zif;
- uint32_t new_protodown_rc;
zif = ifp->info;
- if (new_down)
- new_protodown_rc = zif->protodown_rc | new_reason;
- else
- new_protodown_rc = zif->protodown_rc & ~new_reason;
-
/* Check if we already have this state or it's queued */
if (if_ignore_set_protodown(ifp, new_down, new_protodown_rc))
return 1;
@@ -1328,6 +1325,22 @@ int zebra_if_set_protodown(struct interface *ifp, bool new_down,
return 0;
}
+int zebra_if_set_protodown(struct interface *ifp, bool new_down,
+ enum protodown_reasons new_reason)
+{
+ struct zebra_if *zif;
+ uint32_t new_protodown_rc;
+
+ zif = ifp->info;
+
+ if (new_down)
+ new_protodown_rc = zif->protodown_rc | new_reason;
+ else
+ new_protodown_rc = zif->protodown_rc & ~new_reason;
+
+ return zebra_if_update_protodown(ifp, new_down, new_protodown_rc);
+}
+
/*
* Handle an interface events based on info in a dplane context object.
* This runs in the main pthread, using the info in the context object to
@@ -1410,18 +1423,18 @@ static void zebra_if_update_ctx(struct zebra_dplane_ctx *ctx,
{
enum zebra_dplane_result dp_res;
struct zebra_if *zif;
- uint32_t r_bitfield;
+ bool pd_reason_val;
bool down;
dp_res = dplane_ctx_get_status(ctx);
- r_bitfield = dplane_ctx_get_intf_r_bitfield(ctx);
+ pd_reason_val = dplane_ctx_get_intf_pd_reason_val(ctx);
down = dplane_ctx_intf_is_protodown(ctx);
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason 0x%x",
+ zlog_debug("%s: %s: if %s(%u) ctx-protodown %s ctx-reason %d",
__func__, dplane_op2str(dplane_ctx_get_op(ctx)),
ifp->name, ifp->ifindex, down ? "on" : "off",
- r_bitfield);
+ pd_reason_val);
zif = ifp->info;
if (!zif) {
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 2d13b9b54b..1ad5d93ae2 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -192,9 +192,9 @@ struct dplane_intf_info {
uint32_t metric;
uint32_t flags;
- uint32_t r_bitfield;
bool protodown;
+ bool pd_reason_val;
#define DPLANE_INTF_CONNECTED (1 << 0) /* Connected peer, p2p */
#define DPLANE_INTF_SECONDARY (1 << 1)
@@ -1790,19 +1790,18 @@ void dplane_ctx_set_intf_metric(struct zebra_dplane_ctx *ctx, uint32_t metric)
ctx->u.intf.metric = metric;
}
-uint32_t dplane_ctx_get_intf_r_bitfield(const struct zebra_dplane_ctx *ctx)
+uint32_t dplane_ctx_get_intf_pd_reason_val(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
- return ctx->u.intf.r_bitfield;
+ return ctx->u.intf.pd_reason_val;
}
-void dplane_ctx_set_intf_r_bitfield(struct zebra_dplane_ctx *ctx,
- uint32_t r_bitfield)
+void dplane_ctx_set_intf_pd_reason_val(struct zebra_dplane_ctx *ctx, bool val)
{
DPLANE_CTX_VALID(ctx);
- ctx->u.intf.r_bitfield = r_bitfield;
+ ctx->u.intf.pd_reason_val = val;
}
bool dplane_ctx_intf_is_protodown(const struct zebra_dplane_ctx *ctx)
@@ -2721,7 +2720,9 @@ int dplane_ctx_intf_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
set_pdown = !!(zif->flags & ZIF_FLAG_SET_PROTODOWN);
unset_pdown = !!(zif->flags & ZIF_FLAG_UNSET_PROTODOWN);
- ctx->u.intf.r_bitfield = zif->protodown_rc;
+ if (zif->protodown_rc &&
+ ZEBRA_IF_IS_PROTODOWN_ONLY_EXTERNAL(zif) == false)
+ ctx->u.intf.pd_reason_val = true;
/*
* See if we have new protodown state to set, otherwise keep
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 73acf03411..334d440a2f 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -485,9 +485,8 @@ dplane_ctx_get_pw_backup_nhg(const struct zebra_dplane_ctx *ctx);
/* Accessors for interface information */
uint32_t dplane_ctx_get_intf_metric(const struct zebra_dplane_ctx *ctx);
void dplane_ctx_set_intf_metric(struct zebra_dplane_ctx *ctx, uint32_t metric);
-uint32_t dplane_ctx_get_intf_r_bitfield(const struct zebra_dplane_ctx *ctx);
-void dplane_ctx_set_intf_r_bitfield(struct zebra_dplane_ctx *ctx,
- uint32_t r_bitfield);
+uint32_t dplane_ctx_get_intf_pd_reason_val(const struct zebra_dplane_ctx *ctx);
+void dplane_ctx_set_intf_pd_reason_val(struct zebra_dplane_ctx *ctx, bool val);
bool dplane_ctx_intf_is_protodown(const struct zebra_dplane_ctx *ctx);
/* Is interface addr p2p? */
bool dplane_ctx_intf_is_connected(const struct zebra_dplane_ctx *ctx);