From 2b9dc841b7bc608c2dc5256604f6ef7e9f72fbfd Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 11:14:46 -0400 Subject: [PATCH 1/5] zebra: Fix bug in netconf handling where dplane would drop the change When reading a on the fly change of an interested netconf netlink message. The ifindex and ns_id for the context was being set for the sub structure but not for the main context data structure and zebra_if_dplane_result was dropping the result on the floor because it was expecting the ns_id and the interface id to be in a different spot. Signed-off-by: Donald Sharp --- zebra/netconf_netlink.c | 4 ++-- zebra/zebra_dplane.c | 33 +-------------------------------- zebra/zebra_dplane.h | 5 ----- 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/zebra/netconf_netlink.c b/zebra/netconf_netlink.c index 587f6c749e..03ddfdc525 100644 --- a/zebra/netconf_netlink.c +++ b/zebra/netconf_netlink.c @@ -53,8 +53,8 @@ static int netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex, ctx = dplane_ctx_alloc(); dplane_ctx_set_op(ctx, DPLANE_OP_INTF_NETCONFIG); - dplane_ctx_set_netconf_ns_id(ctx, ns_id); - dplane_ctx_set_netconf_ifindex(ctx, ifindex); + dplane_ctx_set_ns_id(ctx, ns_id); + dplane_ctx_set_ifindex(ctx, ifindex); dplane_ctx_set_netconf_mpls(ctx, mpls_on); dplane_ctx_set_netconf_mcast(ctx, mcast_on); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index bb03d33e99..d464f4a4e6 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -301,8 +301,6 @@ struct dplane_gre_ctx { * info. The flags values are public, in the dplane.h file... */ struct dplane_netconf_info { - ns_id_t ns_id; - ifindex_t ifindex; enum dplane_netconf_status_e mpls_val; enum dplane_netconf_status_e mcast_val; }; @@ -2334,35 +2332,6 @@ dplane_ctx_neightable_get_mcast_probes(const struct zebra_dplane_ctx *ctx) return ctx->u.neightable.mcast_probes; } -ifindex_t dplane_ctx_get_netconf_ifindex(const struct zebra_dplane_ctx *ctx) -{ - DPLANE_CTX_VALID(ctx); - - return ctx->u.netconf.ifindex; -} - -ns_id_t dplane_ctx_get_netconf_ns_id(const struct zebra_dplane_ctx *ctx) -{ - DPLANE_CTX_VALID(ctx); - - return ctx->u.netconf.ns_id; -} - -void dplane_ctx_set_netconf_ifindex(struct zebra_dplane_ctx *ctx, - ifindex_t ifindex) -{ - DPLANE_CTX_VALID(ctx); - - ctx->u.netconf.ifindex = ifindex; -} - -void dplane_ctx_set_netconf_ns_id(struct zebra_dplane_ctx *ctx, ns_id_t ns_id) -{ - DPLANE_CTX_VALID(ctx); - - ctx->u.netconf.ns_id = ns_id; -} - enum dplane_netconf_status_e dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx) { @@ -5439,7 +5408,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) case DPLANE_OP_INTF_NETCONFIG: zlog_debug("%s: ifindex %d, mpls %d, mcast %d", dplane_op2str(dplane_ctx_get_op(ctx)), - dplane_ctx_get_netconf_ifindex(ctx), + dplane_ctx_get_ifindex(ctx), dplane_ctx_get_netconf_mpls(ctx), dplane_ctx_get_netconf_mcast(ctx)); break; diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 334d440a2f..7ba824c5c0 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -592,11 +592,6 @@ const struct zebra_l2info_gre * dplane_ctx_gre_get_info(const struct zebra_dplane_ctx *ctx); /* Interface netconf info */ -ifindex_t dplane_ctx_get_netconf_ifindex(const struct zebra_dplane_ctx *ctx); -ns_id_t dplane_ctx_get_netconf_ns_id(const struct zebra_dplane_ctx *ctx); -void dplane_ctx_set_netconf_ifindex(struct zebra_dplane_ctx *ctx, - ifindex_t ifindex); -void dplane_ctx_set_netconf_ns_id(struct zebra_dplane_ctx *ctx, ns_id_t ns_id); enum dplane_netconf_status_e dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx); enum dplane_netconf_status_e From 52e8a7c4f000a0396cbaf9f22d1ae372b745ba23 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 10:22:45 -0400 Subject: [PATCH 2/5] lib: Increase nexthop flags size to 16 bits commit: 5609e70fb87a3b23b55629a33e5afb298974c142 Added a new flag to the `struct nexthop` and this addition of a flag caused the flags size to be too small. Increase the size of flags to allow more flags to be had. Signed-off-by: Donald Sharp --- lib/nexthop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nexthop.h b/lib/nexthop.h index e324e58491..c939fd37e3 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -81,7 +81,7 @@ struct nexthop { enum nexthop_types_t type; - uint8_t flags; + uint16_t flags; #define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */ #define NEXTHOP_FLAG_FIB (1 << 1) /* FIB nexthop. */ #define NEXTHOP_FLAG_RECURSIVE (1 << 2) /* Recursive nexthop. */ From c704cb44a9874079616acfd94f2315f29392e30f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 10:27:56 -0400 Subject: [PATCH 3/5] lib, zebra: Notice when a nexthop is set linkdown When a nexthop is set RTNH_F_LINKDOWN, start noticing that this flag is set. Allow FRR to know about this flag but at this point do not do anything with it. Signed-off-by: Donald Sharp --- lib/nexthop.h | 1 + zebra/rt_netlink.c | 3 +++ zebra/zebra_vty.c | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/lib/nexthop.h b/lib/nexthop.h index c939fd37e3..f1309aa525 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -95,6 +95,7 @@ struct nexthop { #define NEXTHOP_FLAG_HAS_BACKUP (1 << 6) /* Backup nexthop index is set */ #define NEXTHOP_FLAG_SRTE (1 << 7) /* SR-TE color used for BGP traffic */ #define NEXTHOP_FLAG_EVPN (1 << 8) /* nexthop is EVPN */ +#define NEXTHOP_FLAG_LINKDOWN (1 << 9) /* is not removed on link down */ #define NEXTHOP_IS_ACTIVE(flags) \ (CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 93b2d94671..be7feb21a3 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -535,6 +535,9 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb, if (rtm->rtm_flags & RTNH_F_ONLINK) SET_FLAG(nh.flags, NEXTHOP_FLAG_ONLINK); + if (rtm->rtm_flags & RTNH_F_LINKDOWN) + SET_FLAG(nh.flags, NEXTHOP_FLAG_LINKDOWN); + if (num_labels) nexthop_add_labels(&nh, ZEBRA_LSP_STATIC, num_labels, labels); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 9149da8b0d..011fa2a1e5 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -376,6 +376,9 @@ static void show_nexthop_detail_helper(struct vty *vty, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) vty_out(vty, " onlink"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) + vty_out(vty, " linkdown"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) vty_out(vty, " (recursive)"); @@ -657,6 +660,9 @@ static void show_route_nexthop_helper(struct vty *vty, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) vty_out(vty, " onlink"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) + vty_out(vty, " linkdown"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) vty_out(vty, " (recursive)"); @@ -837,6 +843,9 @@ static void show_nexthop_json_helper(json_object *json_nexthop, json_object_boolean_true_add(json_nexthop, "onLink"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) + json_object_boolean_true_add(json_nexthop, "linkDown"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) json_object_boolean_true_add(json_nexthop, "recursive"); From 3689905d326cf5bbed298baf256443454bdde6a3 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 11:00:08 -0400 Subject: [PATCH 4/5] zebra: Add interface sysctl ignore on linkdown status Add the ability to decode the ignore on linkdown nexthop status for an interface. Signed-off-by: Donald Sharp --- zebra/interface.c | 17 ++++++++++++++--- zebra/interface.h | 3 +++ zebra/netconf_netlink.c | 28 ++++++++++++++++++++++------ zebra/zebra_dplane.c | 18 ++++++++++++++++++ zebra/zebra_dplane.h | 5 +++++ 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index 93ffeb437c..5f36b88a1c 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1407,7 +1407,7 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx, struct interface *ifp) { struct zebra_if *zif; - enum dplane_netconf_status_e mpls; + enum dplane_netconf_status_e mpls, linkdown; zif = ifp->info; if (!zif) { @@ -1424,10 +1424,17 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx, else if (mpls == DPLANE_NETCONF_STATUS_DISABLED) zif->mpls = false; + linkdown = dplane_ctx_get_netconf_linkdown(ctx); + if (linkdown == DPLANE_NETCONF_STATUS_ENABLED) + zif->linkdown = true; + else if (linkdown == DPLANE_NETCONF_STATUS_DISABLED) + zif->linkdown = false; + if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: if %s, ifindex %d, mpls %s", + zlog_debug("%s: if %s, ifindex %d, mpls %s linkdown %s", __func__, ifp->name, ifp->ifindex, - (zif->mpls ? "ON" : "OFF")); + (zif->mpls ? "ON" : "OFF"), + (zif->linkdown ? "ON" : "OFF")); } void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx) @@ -1890,6 +1897,9 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) if (zebra_if->mpls) vty_out(vty, " MPLS enabled\n"); + if (zebra_if->linkdown) + vty_out(vty, " Ignore all routes with linkdown\n"); + /* Hardware address. */ vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type)); if (ifp->hw_addr_len != 0) { @@ -2211,6 +2221,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, zebra_if->desc); json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls); + json_object_boolean_add(json_if, "linkDown", zebra_if->linkdown); if (ifp->ifindex == IFINDEX_INTERNAL) { json_object_boolean_add(json_if, "pseudoInterface", true); diff --git a/zebra/interface.h b/zebra/interface.h index 5569711aa7..54ad91a0b2 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -129,6 +129,9 @@ struct zebra_if { /* MPLS status. */ bool mpls; + /* Linkdown status */ + bool linkdown; + /* Router advertise configuration. */ uint8_t rtadv_enable; diff --git a/zebra/netconf_netlink.c b/zebra/netconf_netlink.c index 03ddfdc525..cc6a1201a5 100644 --- a/zebra/netconf_netlink.c +++ b/zebra/netconf_netlink.c @@ -45,9 +45,11 @@ static struct rtattr *netconf_rta(struct netconfmsg *ncm) * Handle netconf update about a single interface: create dplane * context, and enqueue for processing in the main zebra pthread. */ -static int netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex, - enum dplane_netconf_status_e mpls_on, - enum dplane_netconf_status_e mcast_on) +static int +netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex, + enum dplane_netconf_status_e mpls_on, + enum dplane_netconf_status_e mcast_on, + enum dplane_netconf_status_e linkdown_on) { struct zebra_dplane_ctx *ctx; @@ -58,6 +60,7 @@ static int netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex, dplane_ctx_set_netconf_mpls(ctx, mpls_on); dplane_ctx_set_netconf_mcast(ctx, mcast_on); + dplane_ctx_set_netconf_linkdown(ctx, linkdown_on); /* Enqueue ctx for main pthread to process */ dplane_provider_enqueue_to_zebra(ctx); @@ -77,6 +80,8 @@ int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) uint32_t ival; enum dplane_netconf_status_e mpls_on = DPLANE_NETCONF_STATUS_UNKNOWN; enum dplane_netconf_status_e mcast_on = DPLANE_NETCONF_STATUS_UNKNOWN; + enum dplane_netconf_status_e linkdown_on = + DPLANE_NETCONF_STATUS_UNKNOWN; if (h->nlmsg_type != RTM_NEWNETCONF && h->nlmsg_type != RTM_DELNETCONF) return 0; @@ -133,12 +138,23 @@ int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) mcast_on = DPLANE_NETCONF_STATUS_DISABLED; } + if (tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]) { + ival = *(uint32_t *)RTA_DATA( + tb[NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN]); + if (ival != 0) + linkdown_on = DPLANE_NETCONF_STATUS_ENABLED; + else + linkdown_on = DPLANE_NETCONF_STATUS_DISABLED; + } + if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: interface %u is mpls on: %d multicast on: %d", - __func__, ifindex, mpls_on, mcast_on); + zlog_debug( + "%s: interface %u is mpls on: %d multicast on: %d linkdown: %d", + __func__, ifindex, mpls_on, mcast_on, linkdown_on); /* Create a dplane context and pass it along for processing */ - netlink_netconf_dplane_update(ns_id, ifindex, mpls_on, mcast_on); + netlink_netconf_dplane_update(ns_id, ifindex, mpls_on, mcast_on, + linkdown_on); return 0; } diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index d464f4a4e6..3a3bac6c74 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -303,6 +303,7 @@ struct dplane_gre_ctx { struct dplane_netconf_info { enum dplane_netconf_status_e mpls_val; enum dplane_netconf_status_e mcast_val; + enum dplane_netconf_status_e linkdown_val; }; /* @@ -2348,6 +2349,14 @@ dplane_ctx_get_netconf_mcast(const struct zebra_dplane_ctx *ctx) return ctx->u.netconf.mcast_val; } +enum dplane_netconf_status_e +dplane_ctx_get_netconf_linkdown(const struct zebra_dplane_ctx *ctx) +{ + DPLANE_CTX_VALID(ctx); + + return ctx->u.netconf.linkdown_val; +} + void dplane_ctx_set_netconf_mpls(struct zebra_dplane_ctx *ctx, enum dplane_netconf_status_e val) { @@ -2364,6 +2373,15 @@ void dplane_ctx_set_netconf_mcast(struct zebra_dplane_ctx *ctx, ctx->u.netconf.mcast_val = val; } +void dplane_ctx_set_netconf_linkdown(struct zebra_dplane_ctx *ctx, + enum dplane_netconf_status_e val) +{ + DPLANE_CTX_VALID(ctx); + + ctx->u.netconf.linkdown_val = val; +} + + /* * Retrieve the limit on the number of pending, unprocessed updates. */ diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 7ba824c5c0..d147a3e21c 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -596,10 +596,15 @@ enum dplane_netconf_status_e dplane_ctx_get_netconf_mpls(const struct zebra_dplane_ctx *ctx); enum dplane_netconf_status_e dplane_ctx_get_netconf_mcast(const struct zebra_dplane_ctx *ctx); +enum dplane_netconf_status_e +dplane_ctx_get_netconf_linkdown(const struct zebra_dplane_ctx *ctx); + void dplane_ctx_set_netconf_mpls(struct zebra_dplane_ctx *ctx, enum dplane_netconf_status_e val); void dplane_ctx_set_netconf_mcast(struct zebra_dplane_ctx *ctx, enum dplane_netconf_status_e val); +void dplane_ctx_set_netconf_linkdown(struct zebra_dplane_ctx *ctx, + enum dplane_netconf_status_e val); /* Namespace fd info - esp. for netlink communication */ const struct zebra_dplane_info *dplane_ctx_get_ns( From fc3de981be3d294f459e1e34cfef375c53414c30 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 12:22:30 -0400 Subject: [PATCH 5/5] zebra: Allow kernel routes to stick around better on interface state changes Currently kernel routes on system bring up would be `auto-accepted`, then if an interface went down all kernel and system routes would be re-evaluated. There exists situations where a kernel route can exist but the interface itself is not exactly in a state that is ready to create a connected route yet. As such when any interface goes down in the system all kernel/system routes would be re-evaluated and then since that interfaces connected route is not in the table yet the route is matching against a default route( or not at all ) and is being dropped. Modify the code such that kernel or system routes just look for interface being in a good state (up or operative) and accept it. Broken code: eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:05:08 K>* 1.2.3.5/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.6/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.7/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.8/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.9/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.10/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.12/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.13/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.14/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.16/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 1.2.3.17/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 C>* 4.5.6.99/32 is directly connected, dummy9, 00:05:08 K>* 4.9.10.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:05:08 K>* 10.11.12.13/32 [0/0] via 192.168.119.1, enp39s0, 00:05:08 C>* 192.168.10.0/24 is directly connected, dummy99, 00:05:08 C>* 192.168.119.0/24 is directly connected, enp39s0, 00:05:08 eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:05:28 C>* 4.5.6.99/32 is directly connected, dummy9, 00:05:28 K>* 10.11.12.13/32 [0/0] via 192.168.119.1, enp39s0, 00:05:28 C>* 192.168.10.0/24 is directly connected, dummy99, 00:05:28 C>* 192.168.119.0/24 is directly connected, enp39s0, 00:05:28 Working code: eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:00:04 K>* 1.2.3.5/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.6/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.7/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.8/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.9/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.10/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.12/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.13/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.14/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.16/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 1.2.3.17/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 C>* 4.5.6.99/32 is directly connected, dummy9, 00:00:04 K>* 4.9.10.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:04 K>* 10.11.12.13/32 [0/0] via 192.168.119.1, enp39s0, 00:00:04 C>* 192.168.10.0/24 is directly connected, dummy99, 00:00:04 C>* 192.168.119.0/24 is directly connected, enp39s0, 00:00:04 eva# show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, F - PBR, f - OpenFabric, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:00:15 K>* 1.2.3.5/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.6/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.7/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.8/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.9/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.10/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.12/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.13/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.14/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.16/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 1.2.3.17/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 C>* 4.5.6.99/32 is directly connected, dummy9, 00:00:15 K>* 4.9.10.11/32 [0/0] via 172.22.0.44, br-23e378ed7fd2 linkdown, 00:00:15 K>* 10.11.12.13/32 [0/0] via 192.168.119.1, enp39s0, 00:00:15 C>* 192.168.10.0/24 is directly connected, dummy99, 00:00:15 C>* 192.168.119.0/24 is directly connected, enp39s0, 00:00:15 eva# Signed-off-by: Donald Sharp --- zebra/zebra_nhg.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index f025507f7d..9a0f48158f 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2084,11 +2084,7 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe, * route and interface is up, its active. We trust kernel routes * to be good. */ - if (ifp - && (if_is_operative(ifp) - || (if_is_up(ifp) - && (type == ZEBRA_ROUTE_KERNEL - || type == ZEBRA_ROUTE_SYSTEM)))) + if (ifp && (if_is_operative(ifp))) return 1; else return 0; @@ -2457,20 +2453,19 @@ static unsigned nexthop_active_check(struct route_node *rn, zlog_debug("%s: re %p, nexthop %pNHv", __func__, re, nexthop); /* - * If the kernel has sent us a NEW route, then + * If this is a kernel route, then if the interface is *up* then * by golly gee whiz it's a good route. - * - * If its an already INSTALLED route we have already handled, then the - * kernel route's nexthop might have became unreachable - * and we have to handle that. */ - if (!CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) && - (re->type == ZEBRA_ROUTE_KERNEL || - re->type == ZEBRA_ROUTE_SYSTEM)) { - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); - goto skip_check; - } + if (re->type == ZEBRA_ROUTE_KERNEL || re->type == ZEBRA_ROUTE_SYSTEM) { + struct interface *ifp; + ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); + + if (ifp && (if_is_operative(ifp) || if_is_up(ifp))) { + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + goto skip_check; + } + } vrf_id = zvrf_id(rib_dest_vrf(rib_dest_from_rnode(rn))); switch (nexthop->type) {