0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-18 09:58:43 +00:00

Merge commit 'c865cae3eb327d1e0a745352c483bc7cb00f9323' into integrated

Conflicts:

	nest/rt-table.c
This commit is contained in:
Ondrej Zajicek 2014-05-02 20:23:38 +02:00
commit 621782ecee
5 changed files with 92 additions and 58 deletions

View File

@ -505,7 +505,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;
}

View File

@ -403,7 +403,6 @@ int proto_reconfig_type; /* Hack to propagate type info to pipe reconfigure hoo
static int
proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
{
struct announce_hook *ah = p->main_ahook;
/* If the protocol is DOWN, we just restart it */
if (p->proto_state == PS_DOWN)
return 0;
@ -435,31 +434,16 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
/* Update filters and limits in the main announce hook
Note that this also resets limit state */
if (ah)
{
if (p->main_ahook)
{
struct announce_hook *ah = p->main_ahook;
ah->in_filter = nc->in_filter;
ah->out_filter = nc->out_filter;
ah->rx_limit = nc->rx_limit;
ah->in_limit = nc->in_limit;
ah->out_limit = nc->out_limit;
ah->in_keep_filtered = nc->in_keep_filtered;
if (p->proto_state == PS_UP) /* Recheck export/import/receive limit */
{
struct proto_stats *stats = ah->stats;
struct proto_limit *l = ah->in_limit;
u32 all_routes = stats->imp_routes + stats->filt_routes;
if (l && (stats->imp_routes >= l->limit)) proto_notify_limit(ah, l, PLD_IN, stats->imp_routes);
l = ah->rx_limit;
if (l && ( all_routes >= l->limit)) proto_notify_limit(ah, l, PLD_RX, all_routes );
l = ah->out_limit;
if (l && ( stats->exp_routes >= l->limit)) proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes);
}
proto_verify_limits(ah);
}
/* Update routes when filters changed. If the protocol in not UP,
@ -1199,11 +1183,32 @@ proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32
case PLA_RESTART:
case PLA_DISABLE:
l->state = PLS_BLOCKED;
proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
if (p->proto_state == PS_UP)
proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
break;
}
}
void
proto_verify_limits(struct announce_hook *ah)
{
struct proto_limit *l;
struct proto_stats *stats = ah->stats;
u32 all_routes = stats->imp_routes + stats->filt_routes;
l = ah->rx_limit;
if (l && (all_routes > l->limit))
proto_notify_limit(ah, l, PLD_RX, all_routes);
l = ah->in_limit;
if (l && (stats->imp_routes > l->limit))
proto_notify_limit(ah, l, PLD_IN, stats->imp_routes);
l = ah->out_limit;
if (l && (stats->exp_routes > l->limit))
proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes);
}
static void
proto_want_core_up(struct proto *p)

View File

@ -424,6 +424,7 @@ struct proto_limit {
};
void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count);
void proto_verify_limits(struct announce_hook *ah);
static inline void
proto_reset_limit(struct proto_limit *l)

View File

@ -2326,60 +2326,83 @@ static void
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
{
rte *e, *ee;
byte prefix[MAX_ADDRESS_P_LENGTH];
struct announce_hook *a;
int ok;
byte prefix[MAX_ADDRESS_P_LENGTH+8];
struct ea_list *tmpa;
struct announce_hook *a = NULL;
int first = 1;
int pass = 0;
fn_print(prefix, sizeof(prefix), &n->n);
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 (prefix[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)
{
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)) &&
(f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
ok = 0;
if (d->export_mode)
{
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)
{
d->show_counter++;
if (d->stats < 2)
rt_show_rte(c, prefix, e, d, tmpa);
prefix[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, prefix, e, d, tmpa);
prefix[0] = '\0';
skip:
if (e != ee)
{
rte_free(e);
e = ee;
}
rte_update_unlock();
if (d->primary_only)
break;
}
@ -2441,10 +2464,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);

View File

@ -235,12 +235,14 @@ pipe_reconfigure(struct proto *P, struct proto_config *new)
{
P->main_ahook->out_filter = new->out_filter;
P->main_ahook->in_limit = new->in_limit;
proto_verify_limits(P->main_ahook);
}
if (p->peer_ahook)
{
p->peer_ahook->out_filter = new->in_filter;
p->peer_ahook->in_limit = new->out_limit;
proto_verify_limits(p->peer_ahook);
}
if ((P->proto_state != PS_UP) || (proto_reconfig_type == RECONFIG_SOFT))