]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Add trie iteration code to 'show route'
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 2 Dec 2021 02:30:39 +0000 (03:30 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sun, 6 Feb 2022 22:27:13 +0000 (23:27 +0100)
Add trie iteration code to rt_show_cont() CLI hook and use it to
accelerate 'show route in <addr>' commands using interval queries.

nest/route.h
nest/rt-show.c

index ace4c7f71a5068bbd58f9a992abaf9f2fba078d0..5f0c35783270d6d3c9719c2ce5029aff00fe58e0 100644 (file)
@@ -23,6 +23,7 @@ struct timer;
 struct fib;
 struct filter;
 struct f_trie;
+struct f_trie_walk_state;
 struct cli;
 
 /*
@@ -377,6 +378,7 @@ struct rt_show_data {
   struct rt_show_data_rtable *tab;     /* Iterator over table list */
   struct rt_show_data_rtable *last_table; /* Last table in output */
   struct fib_iterator fit;             /* Iterator over networks in table */
+  struct f_trie_walk_state *walk_state;        /* Iterator over networks in trie */
   int verbose, tables_defined_by;
   const struct filter *filter;
   struct proto *show_protocol;
@@ -387,6 +389,7 @@ struct rt_show_data {
   int export_mode, addr_mode, primary_only, filtered, stats;
 
   int table_open;                      /* Iteration (fit) is open */
+  int trie_walk;                       /* Current table is iterated using trie */
   int net_counter, rt_counter, show_counter, table_counter;
   int net_counter_last, rt_counter_last, show_counter_last;
 };
index b8c818f88bf8ba11d850b99cc74cc68a9ac998df..d8abab5f18f1858e8dc068d165f0e550feee5d65 100644 (file)
@@ -15,6 +15,7 @@
 #include "nest/cli.h"
 #include "nest/iface.h"
 #include "filter/filter.h"
+#include "filter/data.h"
 #include "sysdep/unix/krt.h"
 
 static void
@@ -212,7 +213,7 @@ rt_show_cleanup(struct cli *c)
   struct rt_show_data_rtable *tab;
 
   /* Unlink the iterator */
-  if (d->table_open)
+  if (d->table_open && !d->trie_walk)
     fit_get(&d->tab->table->fib, &d->fit);
 
   /* Unlock referenced tables */
@@ -224,12 +225,13 @@ static void
 rt_show_cont(struct cli *c)
 {
   struct rt_show_data *d = c->rover;
+  struct rtable *tab = d->tab->table;
 #ifdef DEBUGGING
   unsigned max = 4;
 #else
   unsigned max = 64;
 #endif
-  struct fib *fib = &d->tab->table->fib;
+  struct fib *fib = &tab->fib;
   struct fib_iterator *it = &d->fit;
 
   if (d->running_on_config && (d->running_on_config != config))
@@ -240,7 +242,19 @@ rt_show_cont(struct cli *c)
 
   if (!d->table_open)
   {
-    FIB_ITERATE_INIT(&d->fit, &d->tab->table->fib);
+    /* We use either trie-based walk or fib-based walk */
+    d->trie_walk = tab->trie &&
+      (d->addr_mode == RSD_ADDR_IN) &&
+      net_val_match(tab->addr_type, NB_IP);
+
+    if (d->trie_walk && !d->walk_state)
+      d->walk_state = lp_allocz(c->parser_pool, sizeof (struct f_trie_walk_state));
+
+    if (d->trie_walk)
+      trie_walk_init(d->walk_state, tab->trie, d->addr);
+    else
+      FIB_ITERATE_INIT(&d->fit, &tab->fib);
+
     d->table_open = 1;
     d->table_counter++;
     d->kernel = rt_show_get_kernel(d);
@@ -253,21 +267,41 @@ rt_show_cont(struct cli *c)
       rt_show_table(c, d);
   }
 
-  FIB_ITERATE_START(fib, it, net, n)
+  if (d->trie_walk)
   {
-    if ((d->addr_mode == RSD_ADDR_IN) && (!net_in_netX(n->n.addr, d->addr)))
-      goto next;
-
-    if (!max--)
+    /* Trie-based walk */
+    net_addr addr;
+    while (trie_walk_next(d->walk_state, &addr))
     {
-      FIB_ITERATE_PUT(it);
-      return;
+      net *n = net_find(tab, &addr);
+      if (!n)
+       continue;
+
+      rt_show_net(c, n, d);
+
+      if (!--max)
+       return;
     }
-    rt_show_net(c, n, d);
+  }
+  else
+  {
+    /* fib-based walk */
+    FIB_ITERATE_START(fib, it, net, n)
+    {
+      if ((d->addr_mode == RSD_ADDR_IN) && (!net_in_netX(n->n.addr, d->addr)))
+       goto next;
 
-  next:;
+      if (!max--)
+      {
+       FIB_ITERATE_PUT(it);
+       return;
+      }
+      rt_show_net(c, n, d);
+
+    next:;
+    }
+    FIB_ITERATE_END;
   }
-  FIB_ITERATE_END;
 
   if (d->stats)
   {
@@ -276,7 +310,7 @@ rt_show_cont(struct cli *c)
 
     cli_printf(c, -1007, "%d of %d routes for %d networks in table %s",
               d->show_counter - d->show_counter_last, d->rt_counter - d->rt_counter_last,
-              d->net_counter - d->net_counter_last, d->tab->table->name);
+              d->net_counter - d->net_counter_last, tab->name);
   }
 
   d->kernel = NULL;