summaryrefslogtreecommitdiff
path: root/nest/rt-show.c
diff options
context:
space:
mode:
Diffstat (limited to 'nest/rt-show.c')
-rw-r--r--nest/rt-show.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/nest/rt-show.c b/nest/rt-show.c
index 1c764d8c..6c5f32b1 100644
--- a/nest/rt-show.c
+++ b/nest/rt-show.c
@@ -99,10 +99,32 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
rta_show(c, a);
}
+static uint
+rte_feed_count(net *n)
+{
+ uint count = 0;
+ for (struct rte_storage *e = n->routes; e; e = e->next)
+ if (rte_is_valid(RTE_OR_NULL(e)))
+ count++;
+ return count;
+}
+
+static void
+rte_feed_obtain(net *n, rte **feed, uint count)
+{
+ uint i = 0;
+ for (struct rte_storage *e = n->routes; e; e = e->next)
+ if (rte_is_valid(RTE_OR_NULL(e)))
+ {
+ ASSERT_DIE(i < count);
+ feed[i++] = &e->rte;
+ }
+ ASSERT_DIE(i == count);
+}
+
static void
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
- rte *e, *ee;
byte ia[NET_MAX_TEXT_LENGTH+1];
struct channel *ec = d->tab->export_channel;
@@ -114,9 +136,9 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
int first_show = 1;
int pass = 0;
- for (e = n->routes; e; e = e->next)
+ for (struct rte_storage *er = n->routes; er; er = er->next)
{
- if (rte_is_filtered(e) != d->filtered)
+ if (rte_is_filtered(&er->rte) != d->filtered)
continue;
d->rt_counter++;
@@ -126,15 +148,15 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
if (pass)
continue;
- ee = e;
+ struct rte e = er->rte;
/* Export channel is down, do not try to export routes to it */
- if (ec && (ec->export_state == ES_DOWN))
+ if (ec && !ec->out_req.hook)
goto skip;
if (d->export_mode == RSEM_EXPORTED)
{
- if (!bmap_test(&ec->export_map, ee->id))
+ if (!bmap_test(&ec->export_map, e.id))
goto skip;
// if (ec->ra_mode != RA_ANY)
@@ -143,17 +165,24 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
else if ((d->export_mode == RSEM_EXPORT) && (ec->ra_mode == RA_MERGED))
{
/* Special case for merged export */
- rte *rt_free;
- e = rt_export_merged(ec, n, &rt_free, c->show_pool, 1);
pass = 1;
+ uint count = rte_feed_count(n);
+ if (!count)
+ goto skip;
+
+ rte **feed = alloca(count * sizeof(rte *));
+ rte_feed_obtain(n, feed, count);
+ rte *em = rt_export_merged(ec, feed, count, c->show_pool, 1);
- if (!e)
- { e = ee; goto skip; }
+ if (em)
+ e = *em;
+ else
+ goto skip;
}
else if (d->export_mode)
{
struct proto *ep = ec->proto;
- int ic = ep->preexport ? ep->preexport(ep, e) : 0;
+ int ic = ep->preexport ? ep->preexport(ec, &e) : 0;
if (ec->ra_mode == RA_OPTIMAL || ec->ra_mode == RA_MERGED)
pass = 1;
@@ -179,7 +208,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
}
}
- if (d->show_protocol && (d->show_protocol != e->src->proto))
+ if (d->show_protocol && (d->show_protocol != e.src->proto))
goto skip;
if (f_run(d->filter, &e, 0) > F_ACCEPT)
@@ -192,18 +221,13 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
else
ia[0] = 0;
- rt_show_rte(c, ia, e, d, (e->net->routes == ee));
+ rt_show_rte(c, ia, &e, d, (n->routes == er));
first_show = 0;
}
d->show_counter++;
skip:
- if (e != ee)
- {
- rte_free(e);
- e = ee;
- }
lp_flush(c->show_pool);
if (d->primary_only)
@@ -375,7 +399,7 @@ rt_show_get_default_tables(struct rt_show_data *d)
{
WALK_LIST(c, d->export_protocol->channels)
{
- if (c->export_state == ES_DOWN)
+ if (!c->out_req.hook)
continue;
tab = rt_show_add_table(d, c->table);