mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
Merge commit 'c865cae3eb327d1e0a745352c483bc7cb00f9323' into integrated
Conflicts: nest/rt-table.c
This commit is contained in:
commit
621782ecee
@ -505,7 +505,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;
|
||||||
}
|
}
|
||||||
|
43
nest/proto.c
43
nest/proto.c
@ -403,7 +403,6 @@ int proto_reconfig_type; /* Hack to propagate type info to pipe reconfigure hoo
|
|||||||
static int
|
static int
|
||||||
proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
|
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 the protocol is DOWN, we just restart it */
|
||||||
if (p->proto_state == PS_DOWN)
|
if (p->proto_state == PS_DOWN)
|
||||||
return 0;
|
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
|
/* Update filters and limits in the main announce hook
|
||||||
Note that this also resets limit state */
|
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->in_filter = nc->in_filter;
|
||||||
ah->out_filter = nc->out_filter;
|
ah->out_filter = nc->out_filter;
|
||||||
ah->rx_limit = nc->rx_limit;
|
ah->rx_limit = nc->rx_limit;
|
||||||
ah->in_limit = nc->in_limit;
|
ah->in_limit = nc->in_limit;
|
||||||
ah->out_limit = nc->out_limit;
|
ah->out_limit = nc->out_limit;
|
||||||
ah->in_keep_filtered = nc->in_keep_filtered;
|
ah->in_keep_filtered = nc->in_keep_filtered;
|
||||||
|
proto_verify_limits(ah);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update routes when filters changed. If the protocol in not UP,
|
/* 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_RESTART:
|
||||||
case PLA_DISABLE:
|
case PLA_DISABLE:
|
||||||
l->state = PLS_BLOCKED;
|
l->state = PLS_BLOCKED;
|
||||||
|
if (p->proto_state == PS_UP)
|
||||||
proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
|
proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
|
||||||
break;
|
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
|
static void
|
||||||
proto_want_core_up(struct proto *p)
|
proto_want_core_up(struct proto *p)
|
||||||
|
@ -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_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
|
static inline void
|
||||||
proto_reset_limit(struct proto_limit *l)
|
proto_reset_limit(struct proto_limit *l)
|
||||||
|
@ -2326,60 +2326,83 @@ static void
|
|||||||
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
||||||
{
|
{
|
||||||
rte *e, *ee;
|
rte *e, *ee;
|
||||||
byte prefix[MAX_ADDRESS_P_LENGTH];
|
byte prefix[MAX_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;
|
||||||
|
|
||||||
fn_print(prefix, sizeof(prefix), &n->n);
|
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)
|
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 (prefix[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, prefix, e, d, tmpa);
|
rt_show_rte(c, prefix, e, d, tmpa);
|
||||||
prefix[0] = '\0';
|
prefix[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;
|
||||||
}
|
}
|
||||||
@ -2441,10 +2464,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);
|
||||||
|
@ -235,12 +235,14 @@ pipe_reconfigure(struct proto *P, struct proto_config *new)
|
|||||||
{
|
{
|
||||||
P->main_ahook->out_filter = new->out_filter;
|
P->main_ahook->out_filter = new->out_filter;
|
||||||
P->main_ahook->in_limit = new->in_limit;
|
P->main_ahook->in_limit = new->in_limit;
|
||||||
|
proto_verify_limits(P->main_ahook);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->peer_ahook)
|
if (p->peer_ahook)
|
||||||
{
|
{
|
||||||
p->peer_ahook->out_filter = new->in_filter;
|
p->peer_ahook->out_filter = new->in_filter;
|
||||||
p->peer_ahook->in_limit = new->out_limit;
|
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))
|
if ((P->proto_state != PS_UP) || (proto_reconfig_type == RECONFIG_SOFT))
|
||||||
|
Loading…
Reference in New Issue
Block a user