When recomputing routes we can just mark everything that we already had
as "potentially stale", build the new set of parsed routes and then
remove what actually is stale in one go for all router datapaths.

The old code was achieving the same thing but in a very inefficient way.
It used to:
- walk all routers, for each router R:
    - walk all parsed routes (for all routers) and mark as potentially stale
    the ones that correspond to R
    - reparse R's routes (making the ones that are still relevant "not
    stale")
    - remove all actually stale routes for R

But that means O(N x M) iterations, where N is the number of routers and
M is the number of routes in the NB database.

But it turns out we never had any stale routes because we always do a
recompute of the routes node.  So we can remove all the stale checking
and looking up of parsed routes.

This makes it that we can rebuild the parsed routes in a single pass,
with a complexity of O(M).

Some test numbers from a scaled setup, 1.6K routers with a total number
of 28K routes:

Before the change:
    node: routes, recompute (forced) took 5841ms
After the change:
    node: routes, recompute (forced) took 177ms

Fixes: 15c9c9f42ad8 ("northd: Add bfd, static_routes, route_policies and 
bfd_sync nodes to I-P engine.")
Reported-at: https://redhat.atlassian.net/browse/FDP-3988
Assisted-by: Claude Opus 4.6, Claude Code
Signed-off-by: Dumitru Ceara <[email protected]>
---
 northd/northd.c | 17 -----------------
 northd/northd.h |  1 -
 2 files changed, 18 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index aa332c4492..6c93208a84 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -12433,7 +12433,6 @@ parsed_route_add(const struct ovn_datapath *od,
         hmap_insert(routes, &new_pr->key_node, hash);
         return new_pr;
     } else {
-        pr->stale = false;
         parsed_route_free(new_pr);
         return pr;
     }
@@ -12607,13 +12606,6 @@ build_parsed_routes(const struct ovn_datapath *od, 
const struct hmap *lr_ports,
                     struct simap *route_tables,
                     struct hmap *bfd_active_connections)
 {
-    struct parsed_route *pr;
-    HMAP_FOR_EACH (pr, key_node, routes) {
-        if (pr->od == od) {
-            pr->stale = true;
-        }
-    }
-
     for (size_t i = 0; i < od->nbr->n_static_routes; i++) {
         parsed_routes_add_static(od, lr_ports, od->nbr->static_routes[i],
                                  bfd_connections, routes, route_tables,
@@ -12624,15 +12616,6 @@ build_parsed_routes(const struct ovn_datapath *od, 
const struct hmap *lr_ports,
     HMAP_FOR_EACH (op, dp_node, &od->ports) {
         parsed_routes_add_connected(od, op, routes);
     }
-
-    HMAP_FOR_EACH_SAFE (pr, key_node, routes) {
-        if (!pr->stale) {
-            continue;
-        }
-
-        hmap_remove(routes, &pr->key_node);
-        parsed_route_free(pr);
-    }
 }
 
 static char *
diff --git a/northd/northd.h b/northd/northd.h
index a895345f50..ede9e81bc6 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -860,7 +860,6 @@ struct parsed_route {
     bool ecmp_symmetric_reply;
     bool override_connected;
     bool is_discard_route;
-    bool stale;
     const struct ovn_datapath *od;
     struct sset ecmp_selection_fields;
     enum route_source source;
-- 
2.54.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to