diff options
| author | Stephen Worley <sworley@nvidia.com> | 2022-01-31 16:12:01 -0500 |
|---|---|---|
| committer | Stephen Worley <sworley@nvidia.com> | 2022-03-09 18:02:44 -0500 |
| commit | ab465d24bd864c7ab9f5841af89c108e03e768ac (patch) | |
| tree | 922a88a2a82111b869059347bbe121ec6e169654 | |
| parent | 97c726337389b7084ad970cf631a1126e5d5329c (diff) | |
zebra: only clear pd_reason on shutdown/sweep
Only clear protodown reason on shutdown/sweep, retain protodown
state.
This is to retain traditional and expected behavior with daemons
like vrrpd setting protodown. They expet it to be set on shutdown
and retained on bring up to prevent traffic from being dropped.
We must cleanup our reason code though to prevent us from blocking
others.
Signed-off-by: Stephen Worley <sworley@nvidia.com>
| -rw-r--r-- | zebra/if_netlink.c | 22 | ||||
| -rw-r--r-- | zebra/interface.c | 45 | ||||
| -rw-r--r-- | zebra/zebra_dplane.c | 15 | ||||
| -rw-r--r-- | zebra/zebra_dplane.h | 5 |
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); |
