Fixes 'show route export' w.r.t. protocols with different RA_* types.
This commit is contained in:
parent
984d734944
commit
c865cae3eb
2 changed files with 62 additions and 36 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
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)
|
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;
|
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 (ok)
|
|
||||||
{
|
if (d->show_protocol && (d->show_protocol != e->attrs->src->proto))
|
||||||
d->show_counter++;
|
goto skip;
|
||||||
if (d->stats < 2)
|
|
||||||
rt_show_rte(c, ia, e, d, tmpa);
|
if (f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
|
||||||
ia[0] = 0;
|
goto skip;
|
||||||
}
|
|
||||||
|
d->show_counter++;
|
||||||
|
if (d->stats < 2)
|
||||||
|
rt_show_rte(c, ia, e, d, tmpa);
|
||||||
|
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);
|
||||||
|
|
Loading…
Reference in a new issue