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.
This commit is contained in:
parent
ea97b89051
commit
9ac16df3d7
2 changed files with 52 additions and 15 deletions
|
@ -23,6 +23,7 @@ struct timer;
|
||||||
struct fib;
|
struct fib;
|
||||||
struct filter;
|
struct filter;
|
||||||
struct f_trie;
|
struct f_trie;
|
||||||
|
struct f_trie_walk_state;
|
||||||
struct cli;
|
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 *tab; /* Iterator over table list */
|
||||||
struct rt_show_data_rtable *last_table; /* Last table in output */
|
struct rt_show_data_rtable *last_table; /* Last table in output */
|
||||||
struct fib_iterator fit; /* Iterator over networks in table */
|
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;
|
int verbose, tables_defined_by;
|
||||||
const struct filter *filter;
|
const struct filter *filter;
|
||||||
struct proto *show_protocol;
|
struct proto *show_protocol;
|
||||||
|
@ -387,6 +389,7 @@ struct rt_show_data {
|
||||||
int export_mode, addr_mode, primary_only, filtered, stats;
|
int export_mode, addr_mode, primary_only, filtered, stats;
|
||||||
|
|
||||||
int table_open; /* Iteration (fit) is open */
|
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, rt_counter, show_counter, table_counter;
|
||||||
int net_counter_last, rt_counter_last, show_counter_last;
|
int net_counter_last, rt_counter_last, show_counter_last;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "nest/cli.h"
|
#include "nest/cli.h"
|
||||||
#include "nest/iface.h"
|
#include "nest/iface.h"
|
||||||
#include "filter/filter.h"
|
#include "filter/filter.h"
|
||||||
|
#include "filter/data.h"
|
||||||
#include "sysdep/unix/krt.h"
|
#include "sysdep/unix/krt.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -212,7 +213,7 @@ rt_show_cleanup(struct cli *c)
|
||||||
struct rt_show_data_rtable *tab;
|
struct rt_show_data_rtable *tab;
|
||||||
|
|
||||||
/* Unlink the iterator */
|
/* Unlink the iterator */
|
||||||
if (d->table_open)
|
if (d->table_open && !d->trie_walk)
|
||||||
fit_get(&d->tab->table->fib, &d->fit);
|
fit_get(&d->tab->table->fib, &d->fit);
|
||||||
|
|
||||||
/* Unlock referenced tables */
|
/* Unlock referenced tables */
|
||||||
|
@ -224,12 +225,13 @@ static void
|
||||||
rt_show_cont(struct cli *c)
|
rt_show_cont(struct cli *c)
|
||||||
{
|
{
|
||||||
struct rt_show_data *d = c->rover;
|
struct rt_show_data *d = c->rover;
|
||||||
|
struct rtable *tab = d->tab->table;
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
unsigned max = 4;
|
unsigned max = 4;
|
||||||
#else
|
#else
|
||||||
unsigned max = 64;
|
unsigned max = 64;
|
||||||
#endif
|
#endif
|
||||||
struct fib *fib = &d->tab->table->fib;
|
struct fib *fib = &tab->fib;
|
||||||
struct fib_iterator *it = &d->fit;
|
struct fib_iterator *it = &d->fit;
|
||||||
|
|
||||||
if (d->running_on_config && (d->running_on_config != config))
|
if (d->running_on_config && (d->running_on_config != config))
|
||||||
|
@ -240,7 +242,19 @@ rt_show_cont(struct cli *c)
|
||||||
|
|
||||||
if (!d->table_open)
|
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_open = 1;
|
||||||
d->table_counter++;
|
d->table_counter++;
|
||||||
d->kernel = rt_show_get_kernel(d);
|
d->kernel = rt_show_get_kernel(d);
|
||||||
|
@ -253,21 +267,41 @@ rt_show_cont(struct cli *c)
|
||||||
rt_show_table(c, d);
|
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)))
|
/* Trie-based walk */
|
||||||
goto next;
|
net_addr addr;
|
||||||
|
while (trie_walk_next(d->walk_state, &addr))
|
||||||
if (!max--)
|
|
||||||
{
|
{
|
||||||
FIB_ITERATE_PUT(it);
|
net *n = net_find(tab, &addr);
|
||||||
return;
|
if (!n)
|
||||||
}
|
continue;
|
||||||
rt_show_net(c, n, d);
|
|
||||||
|
|
||||||
next:;
|
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)))
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
if (!max--)
|
||||||
|
{
|
||||||
|
FIB_ITERATE_PUT(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rt_show_net(c, n, d);
|
||||||
|
|
||||||
|
next:;
|
||||||
|
}
|
||||||
|
FIB_ITERATE_END;
|
||||||
}
|
}
|
||||||
FIB_ITERATE_END;
|
|
||||||
|
|
||||||
if (d->stats)
|
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",
|
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->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;
|
d->kernel = NULL;
|
||||||
|
|
Loading…
Reference in a new issue