]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_rib.c
zebra: Kernel routes w/ AD were not being marked as installed
[mirror_frr.git] / zebra / zebra_rib.c
index 5eeeebd6e3b65784566cdac9a6329522fd52154f..0200ef2a5e0b88207b8299400d39123dea2a7603 100644 (file)
@@ -228,7 +228,7 @@ int route_entry_update_nhe(struct route_entry *re, struct nhg_hash_entry *new)
 
                if (old)
                        zebra_nhg_decrement_ref(old);
-       } else if (!re->nhe->nhg)
+       } else if (!re->nhe)
                /* This is the first time it's being attached */
                route_entry_attach_ref(re, new);
 
@@ -1075,7 +1075,8 @@ static void rib_process(struct route_node *rn)
                }
 
                /* Infinite distance. */
-               if (re->distance == DISTANCE_INFINITY) {
+               if (re->distance == DISTANCE_INFINITY &&
+                   re->type != ZEBRA_ROUTE_KERNEL) {
                        UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
                        continue;
                }
@@ -1369,6 +1370,14 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
 
        ctx_nexthop = dplane_ctx_get_ng(ctx)->nexthop;
 
+       /* Nothing installed - we can skip some of the checking/comparison
+        * of nexthops.
+        */
+       if (ctx_nexthop == NULL) {
+               changed_p = true;
+               goto no_nexthops;
+       }
+
        /* Get the first `installed` one to check against.
         * If the dataplane doesn't set these to be what was actually installed,
         * it will just be whatever was in re->nhe->nhg?
@@ -1431,6 +1440,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
                goto done;
        }
 
+no_nexthops:
+
        /* FIB nexthop set differs from the RIB set:
         * create a fib-specific nexthop-group
         */
@@ -1788,18 +1799,40 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        /* Ensure we clear the QUEUED flag */
        UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
 
-       /* Is this a notification that ... matters? We only really care about
-        * the route that is currently selected for installation.
+       /* Is this a notification that ... matters? We mostly care about
+        * the route that is currently selected for installation; we may also
+        * get an un-install notification, and handle that too.
         */
        if (re != dest->selected_fib) {
-               /* TODO -- don't skip processing entirely? We might like to
-                * at least report on the event.
+               /*
+                * If we need to, clean up after a delete that was part of
+                * an update operation.
                 */
-               if (debug_p)
-                       zlog_debug("%u:%s dplane notif, but type %s not selected_fib",
-                                  dplane_ctx_get_vrf(ctx), dest_str,
-                                  zebra_route_string(
-                                          dplane_ctx_get_type(ctx)));
+               end_count = 0;
+               for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) {
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
+                               end_count++;
+               }
+
+               /* If no nexthops or none installed, ensure that this re
+                * gets its 'installed' flag cleared.
+                */
+               if (end_count == 0) {
+                       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+                       if (debug_p)
+                               zlog_debug("%u:%s dplane notif, uninstalled type %s route",
+                                          dplane_ctx_get_vrf(ctx), dest_str,
+                                          zebra_route_string(
+                                                  dplane_ctx_get_type(ctx)));
+               } else {
+                       /* At least report on the event. */
+                       if (debug_p)
+                               zlog_debug("%u:%s dplane notif, but type %s not selected_fib",
+                                          dplane_ctx_get_vrf(ctx), dest_str,
+                                          zebra_route_string(
+                                                  dplane_ctx_get_type(ctx)));
+               }
                goto done;
        }
 
@@ -1808,9 +1841,12 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
         * and then again if there's been a change.
         */
        start_count = 0;
-       for (ALL_NEXTHOPS_PTR(rib_active_nhg(re), nexthop)) {
-               if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
-                       start_count++;
+
+       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
+               for (ALL_NEXTHOPS_PTR(rib_active_nhg(re), nexthop)) {
+                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
+                               start_count++;
+               }
        }
 
        /* Update zebra's nexthop FIB flags based on the context struct's
@@ -1820,10 +1856,8 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
 
        if (!fib_changed) {
                if (debug_p)
-                       zlog_debug("%u:%s No change from dplane notification",
+                       zlog_debug("%u:%s dplane notification: rib_update returns FALSE",
                                   dplane_ctx_get_vrf(ctx), dest_str);
-
-               goto done;
        }
 
        /*
@@ -1865,11 +1899,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
                /* Redistribute, lsp, and nht update */
                redistribute_update(dest_pfx, src_pfx, re, NULL);
 
-               zebra_rib_evaluate_rn_nexthops(
-                       rn, zebra_router_get_next_sequence());
-
-               zebra_rib_evaluate_mpls(rn);
-
        } else if (start_count > 0 && end_count == 0) {
                if (debug_p)
                        zlog_debug("%u:%s un-installed transition from dplane notification",
@@ -1888,12 +1917,13 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
 
                /* Redistribute, lsp, and nht update */
                redistribute_delete(dest_pfx, src_pfx, re, NULL);
+       }
 
-               zebra_rib_evaluate_rn_nexthops(
-                       rn, zebra_router_get_next_sequence());
+       /* Make any changes visible for lsp and nexthop-tracking processing */
+       zebra_rib_evaluate_rn_nexthops(
+               rn, zebra_router_get_next_sequence());
 
-               zebra_rib_evaluate_mpls(rn);
-       }
+       zebra_rib_evaluate_mpls(rn);
 
 done:
        if (rn)
@@ -3548,7 +3578,7 @@ struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter)
         * Array that helps us go over all AFI/SAFI combinations via one
         * index.
         */
-       static struct {
+       static const struct {
                afi_t afi;
                safi_t safi;
        } afi_safis[] = {