]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Further handle route replace semantics
authorDonald Sharp <sharpd@nvidia.com>
Mon, 17 Jul 2023 14:00:32 +0000 (10:00 -0400)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Tue, 18 Jul 2023 07:38:00 +0000 (07:38 +0000)
When an upper level protocol is installing a route X that needs to be
route replaced and at the same time the same or another protocol installs a
different route that depends on route X for nexthop resolution can leave
us with a state where the route is not accepted because zebra is still
really early in the route replace semantics ( route X is still on the work
Queue to be processed ) then the dependent route would not be installed.
This came up in the bgp_default_originate test cases frequently.

Further extendd the ROUTE_ENTR_ROUTE_REPLACING flag to cover this case
as well.  This has come up because the early route processing queueing
that was implemented late last year.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit af80201876db00f339e2fbb9036942629aad9e67)

zebra/zebra_nhg.c
zebra/zebra_rib.c

index 68fce701c45827110a8d896bdb3389ef650783eb..717a7a7b48c9e69a63d428420b736208f3966351 100644 (file)
@@ -2366,17 +2366,18 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
                if (is_default_prefix(&rn->p)
                    && !rnh_resolve_via_default(zvrf, p.family)) {
                        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
-                               zlog_debug(
-                                       "        :%s: Resolved against default route",
-                                       __func__);
+                               zlog_debug("        :%s: %pFX Resolved against default route",
+                                          __func__, &p);
                        return 0;
                }
 
                dest = rib_dest_from_rnode(rn);
-               if (dest && dest->selected_fib
-                   && !CHECK_FLAG(dest->selected_fib->status,
-                                  ROUTE_ENTRY_REMOVED)
-                   && dest->selected_fib->type != ZEBRA_ROUTE_TABLE)
+               if (dest && dest->selected_fib &&
+                   (!CHECK_FLAG(dest->selected_fib->status,
+                                ROUTE_ENTRY_REMOVED) ||
+                    CHECK_FLAG(dest->selected_fib->status,
+                               ROUTE_ENTRY_ROUTE_REPLACING)) &&
+                   dest->selected_fib->type != ZEBRA_ROUTE_TABLE)
                        match = dest->selected_fib;
 
                /* If there is no selected route or matched route is EGP, go up
@@ -2388,7 +2389,6 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe,
                        } while (rn && rn->info == NULL);
                        if (rn)
                                route_lock_node(rn);
-
                        continue;
                }
 
index 357f1128218907d957ff7c23e81962b2f733f646..8260ccddf66161dfdd374a0b564f41b35bcd21b6 100644 (file)
@@ -2824,8 +2824,13 @@ static void process_subq_early_route_add(struct zebra_early_route *ere)
        rib_addnode(rn, re, 1);
 
        /* Free implicit route.*/
-       if (same)
+       if (same) {
+               rib_dest_t *dest = rn->info;
+
+               if (same == dest->selected_fib)
+                       SET_FLAG(same->status, ROUTE_ENTRY_ROUTE_REPLACING);
                rib_delnode(rn, same);
+       }
 
        /* See if we can remove some RE entries that are queued for
         * removal, but won't be considered in rib processing.