Commit 56f4cae7 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Nest: Add trie iteration code to 'show route'

Add trie iteration code to rt_show_cont() CLI hook and use it to
accelerate 'show route in <addr>' commands using interval queries.
parent 2dd44514
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct symbol;
struct timer;
struct filter;
struct f_trie;
struct f_trie_walk_state;
struct cli;

/*
@@ -375,6 +376,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;
@@ -385,6 +387,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;
};
+48 −14
Original line number Diff line number Diff line
@@ -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,6 +267,25 @@ rt_show_cont(struct cli *c)
      rt_show_table(c, d);
  }

  if (d->trie_walk)
  {
    /* Trie-based walk */
    net_addr addr;
    while (trie_walk_next(d->walk_state, &addr))
    {
      net *n = net_find(tab, &addr);
      if (!n)
	continue;

      rt_show_net(c, n, d);

      if (!--max)
	return;
    }
  }
  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)))
@@ -268,6 +301,7 @@ rt_show_cont(struct cli *c)
    next:;
    }
    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;