summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-04-28 17:31:03 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2014-04-28 17:31:03 +0200
commitc865cae3eb327d1e0a745352c483bc7cb00f9323 (patch)
tree0a7b9a97fec4cae1fa00dc586c889ee9d64bff39 /nest
parent984d734944a39b70a59f74e57f0e6fc3f720dd48 (diff)
Fixes 'show route export' w.r.t. protocols with different RA_* types.
Diffstat (limited to 'nest')
-rw-r--r--nest/config.Y1
-rw-r--r--nest/rt-table.c95
2 files changed, 61 insertions, 35 deletions
diff --git a/nest/config.Y b/nest/config.Y
index 5b544e59..85c06e74 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -498,7 +498,6 @@ r_args:
if ($$->export_mode) cf_error("Protocol specified twice");
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->export_mode = $2;
- $$->primary_only = 1;
$$->export_protocol = c->proto;
$$->running_on_config = c->proto->cf->global;
}
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 4295f836..4c889d0d 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2246,59 +2246,82 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
rte *e, *ee;
byte ia[STD_ADDRESS_P_LENGTH+8];
- struct announce_hook *a;
- int ok;
+ struct ea_list *tmpa;
+ struct announce_hook *a = NULL;
+ int first = 1;
+ int pass = 0;
bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
- for(e=n->routes; e; e=e->next)
+ if (d->export_mode)
+ {
+ a = proto_find_announce_hook(d->export_protocol, d->table);
+ if (!a)
+ return;
+ }
+
+ for (e = n->routes; e; e = e->next)
{
if (rte_is_filtered(e) != d->filtered)
continue;
- struct ea_list *tmpa;
- struct rte_src *src = e->attrs->src;
- struct proto *p1 = d->export_protocol;
- struct proto *p2 = d->show_protocol;
-
- if (ia[0])
- d->net_counter++;
d->rt_counter++;
+ d->net_counter += first;
+ first = 0;
+
+ if (pass)
+ continue;
+
ee = e;
rte_update_lock(); /* We use the update buffer for filtering */
tmpa = make_tmp_attrs(e, rte_update_pool);
- ok = f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT;
- if (p2 && p2 != src->proto) ok = 0;
- if (ok && d->export_mode)
+
+ if (d->export_mode)
{
- int ic;
- if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0)
- ok = 0;
- else if (!ic && d->export_mode > 1)
+ struct proto *ep = d->export_protocol;
+ int ic = ep->import_control ? ep->import_control(ep, &e, &tmpa, rte_update_pool) : 0;
+
+ if (ep->accept_ra_types == RA_OPTIMAL)
+ pass = 1;
+
+ if (ic < 0)
+ goto skip;
+
+ if (d->export_mode > 1)
{
- /* FIXME - this shows what should be exported according
- to current filters, but not what was really exported.
- 'configure soft' command may change the export filter
- and do not update routes */
-
- if ((a = proto_find_announce_hook(p1, d->table)) &&
- (f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
- ok = 0;
+ /*
+ * FIXME - This shows what should be exported according to current
+ * filters, but not what was really exported. 'configure soft'
+ * command may change the export filter and do not update routes.
+ */
+
+ if (!ic && (f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
+ goto skip;
+
+ if (ep->accept_ra_types == RA_ACCEPTED)
+ pass = 1;
}
}
- if (ok)
- {
- d->show_counter++;
- if (d->stats < 2)
- rt_show_rte(c, ia, e, d, tmpa);
- ia[0] = 0;
- }
+
+ if (d->show_protocol && (d->show_protocol != e->attrs->src->proto))
+ goto skip;
+
+ if (f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
+ goto skip;
+
+ d->show_counter++;
+ if (d->stats < 2)
+ rt_show_rte(c, ia, e, d, tmpa);
+ ia[0] = 0;
+
+ skip:
if (e != ee)
{
rte_free(e);
e = ee;
}
rte_update_unlock();
+
if (d->primary_only)
break;
}
@@ -2360,10 +2383,14 @@ rt_show(struct rt_show_data *d)
net *n;
/* Default is either a master table or a table related to a respective protocol */
- if ((!d->table) && d->export_protocol) d->table = d->export_protocol->table;
- if ((!d->table) && d->show_protocol) d->table = d->show_protocol->table;
+ if (!d->table && d->export_protocol) d->table = d->export_protocol->table;
+ if (!d->table && d->show_protocol) d->table = d->show_protocol->table;
if (!d->table) d->table = config->master_rtc->table;
+ /* Filtered routes are neither exported nor have sensible ordering */
+ if (d->filtered && (d->export_mode || d->primary_only))
+ cli_msg(0, "");
+
if (d->pxlen == 256)
{
FIB_ITERATE_INIT(&d->fit, &d->table->fib);