Fixes 'show route export' w.r.t. protocols with different RA_* types.

This commit is contained in:
Ondrej Zajicek 2014-04-28 17:31:03 +02:00
parent 984d734944
commit c865cae3eb
2 changed files with 62 additions and 36 deletions

View file

@ -498,7 +498,6 @@ r_args:
if ($$->export_mode) cf_error("Protocol specified twice"); if ($$->export_mode) cf_error("Protocol specified twice");
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name); if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->export_mode = $2; $$->export_mode = $2;
$$->primary_only = 1;
$$->export_protocol = c->proto; $$->export_protocol = c->proto;
$$->running_on_config = c->proto->cf->global; $$->running_on_config = c->proto->cf->global;
} }

View file

@ -2246,59 +2246,82 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{ {
rte *e, *ee; rte *e, *ee;
byte ia[STD_ADDRESS_P_LENGTH+8]; byte ia[STD_ADDRESS_P_LENGTH+8];
struct announce_hook *a; struct ea_list *tmpa;
int ok; struct announce_hook *a = NULL;
int first = 1;
int pass = 0;
bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen); bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
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) for (e = n->routes; e; e = e->next)
{ {
if (rte_is_filtered(e) != d->filtered) if (rte_is_filtered(e) != d->filtered)
continue; 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->rt_counter++;
d->net_counter += first;
first = 0;
if (pass)
continue;
ee = e; ee = e;
rte_update_lock(); /* We use the update buffer for filtering */ rte_update_lock(); /* We use the update buffer for filtering */
tmpa = make_tmp_attrs(e, rte_update_pool); 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)
{
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)
{
/* 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)) && if (d->export_mode)
(f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
ok = 0;
}
}
if (ok)
{ {
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 (!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 (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++; d->show_counter++;
if (d->stats < 2) if (d->stats < 2)
rt_show_rte(c, ia, e, d, tmpa); rt_show_rte(c, ia, e, d, tmpa);
ia[0] = 0; ia[0] = 0;
}
skip:
if (e != ee) if (e != ee)
{ {
rte_free(e); rte_free(e);
e = ee; e = ee;
} }
rte_update_unlock(); rte_update_unlock();
if (d->primary_only) if (d->primary_only)
break; break;
} }
@ -2360,10 +2383,14 @@ rt_show(struct rt_show_data *d)
net *n; net *n;
/* Default is either a master table or a table related to a respective protocol */ /* 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->export_protocol) d->table = d->export_protocol->table;
if ((!d->table) && d->show_protocol) d->table = d->show_protocol->table; if (!d->table && d->show_protocol) d->table = d->show_protocol->table;
if (!d->table) d->table = config->master_rtc->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) if (d->pxlen == 256)
{ {
FIB_ITERATE_INIT(&d->fit, &d->table->fib); FIB_ITERATE_INIT(&d->fit, &d->table->fib);