From fc3de981be3d294f459e1e34cfef375c53414c30 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 23 Jun 2022 12:22:30 -0400 Subject: [PATCH] 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) { -- 2.39.5