mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-10 05:08:42 +00:00
Merge commit '8f3942a9' into haugesund
Conflicts: nest/rt-table.c
This commit is contained in:
commit
6151e51ffa
48
nest/proto.c
48
nest/proto.c
@ -284,7 +284,7 @@ channel_feed_loop(void *ptr)
|
|||||||
if (c->refeeding &&
|
if (c->refeeding &&
|
||||||
(l->state == PLS_BLOCKED) &&
|
(l->state == PLS_BLOCKED) &&
|
||||||
(c->refeed_count <= l->limit) &&
|
(c->refeed_count <= l->limit) &&
|
||||||
(c->stats.exp_routes <= l->limit))
|
(c->export_stats.routes <= l->limit))
|
||||||
{
|
{
|
||||||
log(L_INFO "Protocol %s resets route export limit (%u)", c->proto->name, l->limit);
|
log(L_INFO "Protocol %s resets route export limit (%u)", c->proto->name, l->limit);
|
||||||
channel_reset_limit(&c->out_limit);
|
channel_reset_limit(&c->out_limit);
|
||||||
@ -461,8 +461,9 @@ channel_stop_export(struct channel *c)
|
|||||||
rt_feed_channel_abort(c);
|
rt_feed_channel_abort(c);
|
||||||
|
|
||||||
c->export_state = ES_DOWN;
|
c->export_state = ES_DOWN;
|
||||||
c->stats.exp_routes = 0;
|
c->export_stats.routes = 0;
|
||||||
bmap_reset(&c->export_map, 1024);
|
bmap_reset(&c->export_map, 1024);
|
||||||
|
bmap_reset(&c->export_reject_map, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -551,7 +552,9 @@ channel_do_start(struct channel *c)
|
|||||||
c->feed_event = ev_new_init(c->proto->pool, channel_feed_loop, c);
|
c->feed_event = ev_new_init(c->proto->pool, channel_feed_loop, c);
|
||||||
|
|
||||||
bmap_init(&c->export_map, c->proto->pool, 1024);
|
bmap_init(&c->export_map, c->proto->pool, 1024);
|
||||||
memset(&c->stats, 0, sizeof(struct proto_stats));
|
bmap_init(&c->export_reject_map, c->proto->pool, 1024);
|
||||||
|
memset(&c->export_stats, 0, sizeof(struct export_stats));
|
||||||
|
memset(&c->import_stats, 0, sizeof(struct import_stats));
|
||||||
|
|
||||||
channel_reset_limit(&c->rx_limit);
|
channel_reset_limit(&c->rx_limit);
|
||||||
channel_reset_limit(&c->in_limit);
|
channel_reset_limit(&c->in_limit);
|
||||||
@ -584,6 +587,7 @@ channel_do_flush(struct channel *c)
|
|||||||
|
|
||||||
/* This have to be done in here, as channel pool is freed before channel_do_down() */
|
/* This have to be done in here, as channel pool is freed before channel_do_down() */
|
||||||
bmap_free(&c->export_map);
|
bmap_free(&c->export_map);
|
||||||
|
bmap_free(&c->export_reject_map);
|
||||||
c->in_table = NULL;
|
c->in_table = NULL;
|
||||||
c->reload_event = NULL;
|
c->reload_event = NULL;
|
||||||
c->out_table = NULL;
|
c->out_table = NULL;
|
||||||
@ -600,11 +604,12 @@ channel_do_down(struct channel *c)
|
|||||||
rt_unlock_table(c->table);
|
rt_unlock_table(c->table);
|
||||||
c->proto->active_channels--;
|
c->proto->active_channels--;
|
||||||
|
|
||||||
if ((c->stats.imp_routes + c->stats.filt_routes) != 0)
|
if ((c->import_stats.routes + c->import_stats.filtered) != 0)
|
||||||
log(L_ERR "%s: Channel %s is down but still has some routes", c->proto->name, c->name);
|
log(L_ERR "%s: Channel %s is down but still has some routes", c->proto->name, c->name);
|
||||||
|
|
||||||
// bmap_free(&c->export_map);
|
// bmap_free(&c->export_map);
|
||||||
memset(&c->stats, 0, sizeof(struct proto_stats));
|
memset(&c->import_stats, 0, sizeof(struct import_stats));
|
||||||
|
memset(&c->export_stats, 0, sizeof(struct export_stats));
|
||||||
|
|
||||||
c->in_table = NULL;
|
c->in_table = NULL;
|
||||||
c->reload_event = NULL;
|
c->reload_event = NULL;
|
||||||
@ -1842,19 +1847,19 @@ static void
|
|||||||
channel_verify_limits(struct channel *c)
|
channel_verify_limits(struct channel *c)
|
||||||
{
|
{
|
||||||
struct channel_limit *l;
|
struct channel_limit *l;
|
||||||
u32 all_routes = c->stats.imp_routes + c->stats.filt_routes;
|
u32 all_routes = c->import_stats.routes + c->import_stats.filtered;
|
||||||
|
|
||||||
l = &c->rx_limit;
|
l = &c->rx_limit;
|
||||||
if (l->action && (all_routes > l->limit))
|
if (l->action && (all_routes > l->limit))
|
||||||
channel_notify_limit(c, l, PLD_RX, all_routes);
|
channel_notify_limit(c, l, PLD_RX, all_routes);
|
||||||
|
|
||||||
l = &c->in_limit;
|
l = &c->in_limit;
|
||||||
if (l->action && (c->stats.imp_routes > l->limit))
|
if (l->action && (c->import_stats.routes > l->limit))
|
||||||
channel_notify_limit(c, l, PLD_IN, c->stats.imp_routes);
|
channel_notify_limit(c, l, PLD_IN, c->import_stats.routes);
|
||||||
|
|
||||||
l = &c->out_limit;
|
l = &c->out_limit;
|
||||||
if (l->action && (c->stats.exp_routes > l->limit))
|
if (l->action && (c->export_stats.routes > l->limit))
|
||||||
channel_notify_limit(c, l, PLD_OUT, c->stats.exp_routes);
|
channel_notify_limit(c, l, PLD_OUT, c->export_stats.routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -2009,28 +2014,29 @@ proto_state_name(struct proto *p)
|
|||||||
static void
|
static void
|
||||||
channel_show_stats(struct channel *c)
|
channel_show_stats(struct channel *c)
|
||||||
{
|
{
|
||||||
struct proto_stats *s = &c->stats;
|
struct import_stats *is = &c->import_stats;
|
||||||
|
struct export_stats *es = &c->export_stats;
|
||||||
|
|
||||||
if (c->in_keep_filtered)
|
if (c->in_keep_filtered)
|
||||||
cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
|
cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
|
||||||
s->imp_routes, s->filt_routes, s->exp_routes, s->pref_routes);
|
is->routes, is->filtered, es->routes, is->pref);
|
||||||
else
|
else
|
||||||
cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
|
cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
|
||||||
s->imp_routes, s->exp_routes, s->pref_routes);
|
is->routes, es->routes, is->pref);
|
||||||
|
|
||||||
cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
|
cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
|
||||||
cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
|
cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
|
||||||
s->imp_updates_received, s->imp_updates_invalid,
|
is->updates_received, is->updates_invalid,
|
||||||
s->imp_updates_filtered, s->imp_updates_ignored,
|
is->updates_filtered, is->updates_ignored,
|
||||||
s->imp_updates_accepted);
|
is->updates_accepted);
|
||||||
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
|
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
|
||||||
s->imp_withdraws_received, s->imp_withdraws_invalid,
|
is->withdraws_received, is->withdraws_invalid,
|
||||||
s->imp_withdraws_ignored, s->imp_withdraws_accepted);
|
is->withdraws_ignored, is->withdraws_accepted);
|
||||||
cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
|
cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
|
||||||
s->exp_updates_received, s->exp_updates_rejected,
|
es->updates_received, es->updates_rejected,
|
||||||
s->exp_updates_filtered, s->exp_updates_accepted);
|
es->updates_filtered, es->updates_accepted);
|
||||||
cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
|
cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
|
||||||
s->exp_withdraws_received, s->exp_withdraws_accepted);
|
es->withdraws_received, es->withdraws_accepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -132,29 +132,31 @@ struct proto_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Protocol statistics */
|
/* Protocol statistics */
|
||||||
struct proto_stats {
|
struct import_stats {
|
||||||
/* Import - from protocol to core */
|
/* Import - from protocol to core */
|
||||||
u32 imp_routes; /* Number of routes successfully imported to the (adjacent) routing table */
|
u32 routes; /* Number of routes successfully imported to the (adjacent) routing table */
|
||||||
u32 filt_routes; /* Number of routes rejected in import filter but kept in the routing table */
|
u32 filtered; /* Number of routes rejected in import filter but kept in the routing table */
|
||||||
u32 pref_routes; /* Number of routes selected as best in the (adjacent) routing table */
|
u32 pref; /* Number of routes selected as best in the (adjacent) routing table */
|
||||||
u32 imp_updates_received; /* Number of route updates received */
|
u32 updates_received; /* Number of route updates received */
|
||||||
u32 imp_updates_invalid; /* Number of route updates rejected as invalid */
|
u32 updates_invalid; /* Number of route updates rejected as invalid */
|
||||||
u32 imp_updates_filtered; /* Number of route updates rejected by filters */
|
u32 updates_filtered; /* Number of route updates rejected by filters */
|
||||||
u32 imp_updates_ignored; /* Number of route updates rejected as already in route table */
|
u32 updates_ignored; /* Number of route updates rejected as already in route table */
|
||||||
u32 imp_updates_accepted; /* Number of route updates accepted and imported */
|
u32 updates_accepted; /* Number of route updates accepted and imported */
|
||||||
u32 imp_withdraws_received; /* Number of route withdraws received */
|
u32 withdraws_received; /* Number of route withdraws received */
|
||||||
u32 imp_withdraws_invalid; /* Number of route withdraws rejected as invalid */
|
u32 withdraws_invalid; /* Number of route withdraws rejected as invalid */
|
||||||
u32 imp_withdraws_ignored; /* Number of route withdraws rejected as already not in route table */
|
u32 withdraws_ignored; /* Number of route withdraws rejected as already not in route table */
|
||||||
u32 imp_withdraws_accepted; /* Number of route withdraws accepted and processed */
|
u32 withdraws_accepted; /* Number of route withdraws accepted and processed */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct export_stats {
|
||||||
/* Export - from core to protocol */
|
/* Export - from core to protocol */
|
||||||
u32 exp_routes; /* Number of routes successfully exported to the protocol */
|
u32 routes; /* Number of routes successfully exported to the protocol */
|
||||||
u32 exp_updates_received; /* Number of route updates received */
|
u32 updates_received; /* Number of route updates received */
|
||||||
u32 exp_updates_rejected; /* Number of route updates rejected by protocol */
|
u32 updates_rejected; /* Number of route updates rejected by protocol */
|
||||||
u32 exp_updates_filtered; /* Number of route updates rejected by filters */
|
u32 updates_filtered; /* Number of route updates rejected by filters */
|
||||||
u32 exp_updates_accepted; /* Number of route updates accepted and exported */
|
u32 updates_accepted; /* Number of route updates accepted and exported */
|
||||||
u32 exp_withdraws_received; /* Number of route withdraws received */
|
u32 withdraws_received; /* Number of route withdraws received */
|
||||||
u32 exp_withdraws_accepted; /* Number of route withdraws accepted and processed */
|
u32 withdraws_accepted; /* Number of route withdraws accepted and processed */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proto {
|
struct proto {
|
||||||
@ -509,14 +511,17 @@ struct channel {
|
|||||||
struct rtable *table;
|
struct rtable *table;
|
||||||
const struct filter *in_filter; /* Input filter */
|
const struct filter *in_filter; /* Input filter */
|
||||||
const struct filter *out_filter; /* Output filter */
|
const struct filter *out_filter; /* Output filter */
|
||||||
struct bmap export_map; /* Keeps track which routes passed export filter */
|
struct bmap export_map; /* Keeps track which routes were really exported */
|
||||||
|
struct bmap export_reject_map; /* Keeps track which routes were rejected by export filter */
|
||||||
struct channel_limit rx_limit; /* Receive limit (for in_keep_filtered) */
|
struct channel_limit rx_limit; /* Receive limit (for in_keep_filtered) */
|
||||||
struct channel_limit in_limit; /* Input limit */
|
struct channel_limit in_limit; /* Input limit */
|
||||||
struct channel_limit out_limit; /* Output limit */
|
struct channel_limit out_limit; /* Output limit */
|
||||||
|
|
||||||
struct event *feed_event; /* Event responsible for feeding */
|
struct event *feed_event; /* Event responsible for feeding */
|
||||||
struct fib_iterator feed_fit; /* Routing table iterator used during feeding */
|
struct fib_iterator feed_fit; /* Routing table iterator used during feeding */
|
||||||
struct proto_stats stats; /* Per-channel protocol statistics */
|
struct import_stats import_stats; /* Import statistics */
|
||||||
|
struct export_stats export_stats; /* Export statistics */
|
||||||
|
|
||||||
u32 refeed_count; /* Number of routes exported during refeed regardless of out_limit */
|
u32 refeed_count; /* Number of routes exported during refeed regardless of out_limit */
|
||||||
|
|
||||||
u8 net_type; /* Routing table network type (NET_*), 0 for undefined */
|
u8 net_type; /* Routing table network type (NET_*), 0 for undefined */
|
||||||
|
137
nest/rt-table.c
137
nest/rt-table.c
@ -663,19 +663,23 @@ export_filter_(struct channel *c, rte *rt, linpool *pool, int silent)
|
|||||||
{
|
{
|
||||||
struct proto *p = c->proto;
|
struct proto *p = c->proto;
|
||||||
const struct filter *filter = c->out_filter;
|
const struct filter *filter = c->out_filter;
|
||||||
struct proto_stats *stats = &c->stats;
|
struct export_stats *stats = &c->export_stats;
|
||||||
int v;
|
|
||||||
|
|
||||||
v = p->preexport ? p->preexport(c, rt) : 0;
|
/* Do nothing if we have already rejected the route */
|
||||||
|
if (silent && bmap_test(&c->export_reject_map, rt->id))
|
||||||
|
goto reject_noset;
|
||||||
|
|
||||||
|
int v = p->preexport ? p->preexport(c, rt) : 0;
|
||||||
if (v < 0)
|
if (v < 0)
|
||||||
{
|
{
|
||||||
if (silent)
|
if (silent)
|
||||||
goto reject;
|
goto reject_noset;
|
||||||
|
|
||||||
stats->exp_updates_rejected++;
|
stats->updates_rejected++;
|
||||||
if (v == RIC_REJECT)
|
if (v == RIC_REJECT)
|
||||||
rte_trace_out(D_FILTERS, c, rt, "rejected by protocol");
|
rte_trace_out(D_FILTERS, c, rt, "rejected by protocol");
|
||||||
goto reject;
|
goto reject_noset;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (v > 0)
|
if (v > 0)
|
||||||
{
|
{
|
||||||
@ -692,15 +696,22 @@ export_filter_(struct channel *c, rte *rt, linpool *pool, int silent)
|
|||||||
if (silent)
|
if (silent)
|
||||||
goto reject;
|
goto reject;
|
||||||
|
|
||||||
stats->exp_updates_filtered++;
|
stats->updates_filtered++;
|
||||||
rte_trace_out(D_FILTERS, c, rt, "filtered out");
|
rte_trace_out(D_FILTERS, c, rt, "filtered out");
|
||||||
goto reject;
|
goto reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
accept:
|
accept:
|
||||||
|
/* We have accepted the route */
|
||||||
|
bmap_clear(&c->export_reject_map, rt->id);
|
||||||
return rt;
|
return rt;
|
||||||
|
|
||||||
reject:
|
reject:
|
||||||
|
/* We have rejected the route by filter */
|
||||||
|
bmap_set(&c->export_reject_map, rt->id);
|
||||||
|
|
||||||
|
reject_noset:
|
||||||
|
/* Invalidate the route */
|
||||||
/* Discard temporary rte */
|
/* Discard temporary rte */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -715,7 +726,7 @@ static void
|
|||||||
do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
|
do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
|
||||||
{
|
{
|
||||||
struct proto *p = c->proto;
|
struct proto *p = c->proto;
|
||||||
struct proto_stats *stats = &c->stats;
|
struct export_stats *stats = &c->export_stats;
|
||||||
|
|
||||||
if (refeed && new)
|
if (refeed && new)
|
||||||
c->refeed_count++;
|
c->refeed_count++;
|
||||||
@ -724,12 +735,12 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
|
|||||||
struct channel_limit *l = &c->out_limit;
|
struct channel_limit *l = &c->out_limit;
|
||||||
if (l->action && !old && new)
|
if (l->action && !old && new)
|
||||||
{
|
{
|
||||||
if (stats->exp_routes >= l->limit)
|
if (stats->routes >= l->limit)
|
||||||
channel_notify_limit(c, l, PLD_OUT, stats->exp_routes);
|
channel_notify_limit(c, l, PLD_OUT, stats->routes);
|
||||||
|
|
||||||
if (l->state == PLS_BLOCKED)
|
if (l->state == PLS_BLOCKED)
|
||||||
{
|
{
|
||||||
stats->exp_updates_rejected++;
|
stats->updates_rejected++;
|
||||||
rte_trace_out(D_FILTERS, c, new, "rejected [limit]");
|
rte_trace_out(D_FILTERS, c, new, "rejected [limit]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -747,20 +758,20 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
stats->exp_updates_accepted++;
|
stats->updates_accepted++;
|
||||||
else
|
else
|
||||||
stats->exp_withdraws_accepted++;
|
stats->withdraws_accepted++;
|
||||||
|
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
bmap_clear(&c->export_map, old->id);
|
bmap_clear(&c->export_map, old->id);
|
||||||
stats->exp_routes--;
|
stats->routes--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
{
|
{
|
||||||
bmap_set(&c->export_map, new->id);
|
bmap_set(&c->export_map, new->id);
|
||||||
stats->exp_routes++;
|
stats->routes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->debug & D_ROUTES)
|
if (p->debug & D_ROUTES)
|
||||||
@ -783,9 +794,9 @@ static void
|
|||||||
rt_notify_basic(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
|
rt_notify_basic(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
|
||||||
{
|
{
|
||||||
if (new)
|
if (new)
|
||||||
c->stats.exp_updates_received++;
|
c->export_stats.updates_received++;
|
||||||
else
|
else
|
||||||
c->stats.exp_withdraws_received++;
|
c->export_stats.withdraws_received++;
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
new = export_filter(c, new, 0);
|
new = export_filter(c, new, 0);
|
||||||
@ -825,9 +836,9 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (net->routes)
|
if (net->routes)
|
||||||
c->stats.exp_updates_received++;
|
c->export_stats.updates_received++;
|
||||||
else
|
else
|
||||||
c->stats.exp_withdraws_received++;
|
c->export_stats.withdraws_received++;
|
||||||
|
|
||||||
/* Find old_best - either old_changed, or route for net->routes */
|
/* Find old_best - either old_changed, or route for net->routes */
|
||||||
if (old_changed && bmap_test(&c->export_map, old_changed->id))
|
if (old_changed && bmap_test(&c->export_map, old_changed->id))
|
||||||
@ -853,9 +864,15 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang
|
|||||||
{
|
{
|
||||||
/* Feed or old_best changed -> find first accepted by filters */
|
/* Feed or old_best changed -> find first accepted by filters */
|
||||||
for (struct rte_storage *r = net->routes; rte_is_valid(r); r = r->next)
|
for (struct rte_storage *r = net->routes; rte_is_valid(r); r = r->next)
|
||||||
|
{
|
||||||
|
/* Already rejected before */
|
||||||
|
if (!refeed && bmap_test(&c->export_reject_map, r->rte.id))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (new_best = export_filter(c, ((nb0 = r->rte), &nb0), 0))
|
if (new_best = export_filter(c, ((nb0 = r->rte), &nb0), 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Other cases -> either new_changed, or old_best (and nothing changed) */
|
/* Other cases -> either new_changed, or old_best (and nothing changed) */
|
||||||
@ -943,9 +960,9 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (new_best)
|
if (new_best)
|
||||||
c->stats.exp_updates_received++;
|
c->export_stats.updates_received++;
|
||||||
else
|
else
|
||||||
c->stats.exp_withdraws_received++;
|
c->export_stats.withdraws_received++;
|
||||||
|
|
||||||
/* Prepare new merged route */
|
/* Prepare new merged route */
|
||||||
if (new_best)
|
if (new_best)
|
||||||
@ -965,7 +982,6 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
|
|||||||
/**
|
/**
|
||||||
* rte_announce - announce a routing table change
|
* rte_announce - announce a routing table change
|
||||||
* @tab: table the route has been added to
|
* @tab: table the route has been added to
|
||||||
* @type: type of route announcement (RA_UNDEF or RA_ANY)
|
|
||||||
* @net: network in question
|
* @net: network in question
|
||||||
* @new: the new or changed route
|
* @new: the new or changed route
|
||||||
* @old: the previous route replaced by the new one
|
* @old: the previous route replaced by the new one
|
||||||
@ -981,13 +997,6 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
|
|||||||
* and @new_best and @old_best describes best routes. Other routes are not
|
* and @new_best and @old_best describes best routes. Other routes are not
|
||||||
* affected, but in sorted table the order of other routes might change.
|
* affected, but in sorted table the order of other routes might change.
|
||||||
*
|
*
|
||||||
* Second, There is a bulk change of multiple routes in @net, with shared best
|
|
||||||
* route selection. In such case separate route changes are described using
|
|
||||||
* @type of %RA_ANY, with @new and @old specifying the changed route, while
|
|
||||||
* @new_best and @old_best are NULL. After that, another notification is done
|
|
||||||
* where @new_best and @old_best are filled (may be the same), but @new and @old
|
|
||||||
* are NULL.
|
|
||||||
*
|
|
||||||
* The function announces the change to all associated channels. For each
|
* The function announces the change to all associated channels. For each
|
||||||
* channel, an appropriate preprocessing is done according to channel &ra_mode.
|
* channel, an appropriate preprocessing is done according to channel &ra_mode.
|
||||||
* For example, %RA_OPTIMAL channels receive just changes of best routes.
|
* For example, %RA_OPTIMAL channels receive just changes of best routes.
|
||||||
@ -1002,7 +1011,7 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
|
|||||||
* done outside of scope of rte_announce().
|
* done outside of scope of rte_announce().
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rte_announce(rtable *tab, uint type, net *net, struct rte_storage *new, struct rte_storage *old,
|
rte_announce(rtable *tab, net *net, struct rte_storage *new, struct rte_storage *old,
|
||||||
struct rte_storage *new_best, struct rte_storage *old_best)
|
struct rte_storage *new_best, struct rte_storage *old_best)
|
||||||
{
|
{
|
||||||
if (!rte_is_valid(new))
|
if (!rte_is_valid(new))
|
||||||
@ -1023,9 +1032,9 @@ rte_announce(rtable *tab, uint type, net *net, struct rte_storage *new, struct r
|
|||||||
if (new_best != old_best)
|
if (new_best != old_best)
|
||||||
{
|
{
|
||||||
if (new_best)
|
if (new_best)
|
||||||
new_best->rte.sender->stats.pref_routes++;
|
new_best->rte.sender->import_stats.pref++;
|
||||||
if (old_best)
|
if (old_best)
|
||||||
old_best->rte.sender->stats.pref_routes--;
|
old_best->rte.sender->import_stats.pref--;
|
||||||
|
|
||||||
if (tab->hostcache)
|
if (tab->hostcache)
|
||||||
rt_notify_hostcache(tab, net);
|
rt_notify_hostcache(tab, net);
|
||||||
@ -1042,9 +1051,6 @@ rte_announce(rtable *tab, uint type, net *net, struct rte_storage *new, struct r
|
|||||||
if (c->export_state == ES_DOWN)
|
if (c->export_state == ES_DOWN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (type && (type != c->ra_mode))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
rte n0;
|
rte n0;
|
||||||
switch (c->ra_mode)
|
switch (c->ra_mode)
|
||||||
{
|
{
|
||||||
@ -1066,6 +1072,11 @@ rte_announce(rtable *tab, uint type, net *net, struct rte_storage *new, struct r
|
|||||||
rt_notify_merged(c, net, RTE_OR_NULL(new), RTE_OR_NULL(old), RTE_OR_NULL(new_best), RTE_OR_NULL(old_best), 0);
|
rt_notify_merged(c, net, RTE_OR_NULL(new), RTE_OR_NULL(old), RTE_OR_NULL(new_best), RTE_OR_NULL(old_best), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Drop the old stored rejection if applicable.
|
||||||
|
* new->id == old->id happens when updating hostentries. */
|
||||||
|
if (old && (!new || (new->rte.id != old->rte.id)))
|
||||||
|
bmap_clear(&c->export_reject_map, old->rte.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1131,7 +1142,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
{
|
{
|
||||||
struct proto *p = c->proto;
|
struct proto *p = c->proto;
|
||||||
struct rtable *table = c->table;
|
struct rtable *table = c->table;
|
||||||
struct proto_stats *stats = &c->stats;
|
struct import_stats *stats = &c->import_stats;
|
||||||
struct rte_storage *old_best_stored = net->routes, *old_stored = NULL;
|
struct rte_storage *old_best_stored = net->routes, *old_stored = NULL;
|
||||||
rte *old_best = old_best_stored ? &old_best_stored->rte : NULL;
|
rte *old_best = old_best_stored ? &old_best_stored->rte : NULL;
|
||||||
rte *old = NULL;
|
rte *old = NULL;
|
||||||
@ -1168,7 +1179,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
|
|
||||||
if (!rte_is_filtered(new))
|
if (!rte_is_filtered(new))
|
||||||
{
|
{
|
||||||
stats->imp_updates_ignored++;
|
stats->updates_ignored++;
|
||||||
rte_trace_in(D_ROUTES, c, new, "ignored");
|
rte_trace_in(D_ROUTES, c, new, "ignored");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,7 +1193,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
|
|
||||||
if (!old && !new)
|
if (!old && !new)
|
||||||
{
|
{
|
||||||
stats->imp_withdraws_ignored++;
|
stats->withdraws_ignored++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1192,7 +1203,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
struct channel_limit *l = &c->rx_limit;
|
struct channel_limit *l = &c->rx_limit;
|
||||||
if (l->action && !old && new && !c->in_table)
|
if (l->action && !old && new && !c->in_table)
|
||||||
{
|
{
|
||||||
u32 all_routes = stats->imp_routes + stats->filt_routes;
|
u32 all_routes = stats->routes + stats->filtered;
|
||||||
|
|
||||||
if (all_routes >= l->limit)
|
if (all_routes >= l->limit)
|
||||||
channel_notify_limit(c, l, PLD_RX, all_routes);
|
channel_notify_limit(c, l, PLD_RX, all_routes);
|
||||||
@ -1202,7 +1213,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
/* In receive limit the situation is simple, old is NULL so
|
/* In receive limit the situation is simple, old is NULL so
|
||||||
we just free new and exit like nothing happened */
|
we just free new and exit like nothing happened */
|
||||||
|
|
||||||
stats->imp_updates_ignored++;
|
stats->updates_ignored++;
|
||||||
rte_trace_in(D_FILTERS, c, new, "ignored [limit]");
|
rte_trace_in(D_FILTERS, c, new, "ignored [limit]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1211,8 +1222,8 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
l = &c->in_limit;
|
l = &c->in_limit;
|
||||||
if (l->action && !old_ok && new_ok)
|
if (l->action && !old_ok && new_ok)
|
||||||
{
|
{
|
||||||
if (stats->imp_routes >= l->limit)
|
if (stats->routes >= l->limit)
|
||||||
channel_notify_limit(c, l, PLD_IN, stats->imp_routes);
|
channel_notify_limit(c, l, PLD_IN, stats->routes);
|
||||||
|
|
||||||
if (l->state == PLS_BLOCKED)
|
if (l->state == PLS_BLOCKED)
|
||||||
{
|
{
|
||||||
@ -1223,7 +1234,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
if both are NULL as this case is probably assumed to be
|
if both are NULL as this case is probably assumed to be
|
||||||
already handled. */
|
already handled. */
|
||||||
|
|
||||||
stats->imp_updates_ignored++;
|
stats->updates_ignored++;
|
||||||
rte_trace_in(D_FILTERS, c, new, "ignored [limit]");
|
rte_trace_in(D_FILTERS, c, new, "ignored [limit]");
|
||||||
|
|
||||||
if (c->in_keep_filtered)
|
if (c->in_keep_filtered)
|
||||||
@ -1243,11 +1254,11 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new_ok)
|
if (new_ok)
|
||||||
stats->imp_updates_accepted++;
|
stats->updates_accepted++;
|
||||||
else if (old_ok)
|
else if (old_ok)
|
||||||
stats->imp_withdraws_accepted++;
|
stats->withdraws_accepted++;
|
||||||
else
|
else
|
||||||
stats->imp_withdraws_ignored++;
|
stats->withdraws_ignored++;
|
||||||
|
|
||||||
if (old_ok || new_ok)
|
if (old_ok || new_ok)
|
||||||
table->last_rt_change = current_time();
|
table->last_rt_change = current_time();
|
||||||
@ -1256,9 +1267,9 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
struct rte_storage *new_stored = new ? rte_store(new, net, table) : NULL;
|
struct rte_storage *new_stored = new ? rte_store(new, net, table) : NULL;
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
rte_is_filtered(new) ? stats->filt_routes++ : stats->imp_routes++;
|
rte_is_filtered(new) ? stats->filtered++ : stats->routes++;
|
||||||
if (old)
|
if (old)
|
||||||
rte_is_filtered(old) ? stats->filt_routes-- : stats->imp_routes--;
|
rte_is_filtered(old) ? stats->filtered-- : stats->routes--;
|
||||||
|
|
||||||
if (table->config->sorted)
|
if (table->config->sorted)
|
||||||
{
|
{
|
||||||
@ -1378,7 +1389,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Propagate the route change */
|
/* Propagate the route change */
|
||||||
rte_announce(table, RA_UNDEF, net, new_stored, old_stored,
|
rte_announce(table, net, new_stored, old_stored,
|
||||||
net->routes, old_best_stored);
|
net->routes, old_best_stored);
|
||||||
|
|
||||||
if (!net->routes &&
|
if (!net->routes &&
|
||||||
@ -1423,7 +1434,7 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
if (c->in_table && !rte_update_in(c, n, new, src))
|
if (c->in_table && !rte_update_in(c, n, new, src))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct proto_stats *stats = &c->stats;
|
struct import_stats *stats = &c->import_stats;
|
||||||
const struct filter *filter = c->in_filter;
|
const struct filter *filter = c->in_filter;
|
||||||
net *nn;
|
net *nn;
|
||||||
|
|
||||||
@ -1435,17 +1446,17 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
new->net = n;
|
new->net = n;
|
||||||
new->sender = c;
|
new->sender = c;
|
||||||
|
|
||||||
stats->imp_updates_received++;
|
stats->updates_received++;
|
||||||
if (!rte_validate(new))
|
if (!rte_validate(new))
|
||||||
{
|
{
|
||||||
rte_trace_in(D_FILTERS, c, new, "invalid");
|
rte_trace_in(D_FILTERS, c, new, "invalid");
|
||||||
stats->imp_updates_invalid++;
|
stats->updates_invalid++;
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter == FILTER_REJECT)
|
if (filter == FILTER_REJECT)
|
||||||
{
|
{
|
||||||
stats->imp_updates_filtered++;
|
stats->updates_filtered++;
|
||||||
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
||||||
|
|
||||||
if (! c->in_keep_filtered)
|
if (! c->in_keep_filtered)
|
||||||
@ -1459,7 +1470,7 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
int fr = f_run(filter, new, rte_update_pool, 0);
|
int fr = f_run(filter, new, rte_update_pool, 0);
|
||||||
if (fr > F_ACCEPT)
|
if (fr > F_ACCEPT)
|
||||||
{
|
{
|
||||||
stats->imp_updates_filtered++;
|
stats->updates_filtered++;
|
||||||
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
rte_trace_in(D_FILTERS, c, new, "filtered out");
|
||||||
|
|
||||||
if (! c->in_keep_filtered)
|
if (! c->in_keep_filtered)
|
||||||
@ -1475,11 +1486,11 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stats->imp_withdraws_received++;
|
stats->withdraws_received++;
|
||||||
|
|
||||||
if (!(nn = net_find(c->table, n)) || !src)
|
if (!(nn = net_find(c->table, n)) || !src)
|
||||||
{
|
{
|
||||||
stats->imp_withdraws_ignored++;
|
stats->withdraws_ignored++;
|
||||||
rte_update_unlock();
|
rte_update_unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1503,11 +1514,11 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
/* Independent call to rte_announce(), used from next hop
|
/* Independent call to rte_announce(), used from next hop
|
||||||
recalculation, outside of rte_update(). new must be non-NULL */
|
recalculation, outside of rte_update(). new must be non-NULL */
|
||||||
static inline void
|
static inline void
|
||||||
rte_announce_i(rtable *tab, uint type, net *net, struct rte_storage *new, struct rte_storage *old,
|
rte_announce_i(rtable *tab, net *net, struct rte_storage *new, struct rte_storage *old,
|
||||||
struct rte_storage *new_best, struct rte_storage *old_best)
|
struct rte_storage *new_best, struct rte_storage *old_best)
|
||||||
{
|
{
|
||||||
rte_update_lock();
|
rte_update_lock();
|
||||||
rte_announce(tab, type, net, new, old, new_best, old_best);
|
rte_announce(tab, net, new, old, new_best, old_best);
|
||||||
rte_update_unlock();
|
rte_update_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2587,7 +2598,7 @@ rt_next_hop_update_net(rtable *tab, net *n)
|
|||||||
_Bool nb = (new == updates[i].new), ob = (old_best == updates[i].old);
|
_Bool nb = (new == updates[i].new), ob = (old_best == updates[i].old);
|
||||||
const char *best_indicator[2][2] = { { "updated", "updated [-best]" }, { "updated [+best]", "updated [best]" } };
|
const char *best_indicator[2][2] = { { "updated", "updated [-best]" }, { "updated [+best]", "updated [best]" } };
|
||||||
rte_trace_in(D_ROUTES, new->rte.sender, &updates[i].new->rte, best_indicator[nb][ob]);
|
rte_trace_in(D_ROUTES, new->rte.sender, &updates[i].new->rte, best_indicator[nb][ob]);
|
||||||
rte_announce_i(tab, RA_UNDEF, n, updates[i].new, updates[i].old, new, old_best);
|
rte_announce_i(tab, n, updates[i].new, updates[i].old, new, old_best);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<count; i++)
|
for (int i=0; i<count; i++)
|
||||||
@ -2956,8 +2967,8 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
drop_update:
|
drop_update:
|
||||||
c->stats.imp_updates_received++;
|
c->import_stats.updates_received++;
|
||||||
c->stats.imp_updates_ignored++;
|
c->import_stats.updates_ignored++;
|
||||||
|
|
||||||
if (!net->routes)
|
if (!net->routes)
|
||||||
fib_delete(&tab->fib, net);
|
fib_delete(&tab->fib, net);
|
||||||
@ -2965,8 +2976,8 @@ drop_update:
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drop_withdraw:
|
drop_withdraw:
|
||||||
c->stats.imp_withdraws_received++;
|
c->import_stats.withdraws_received++;
|
||||||
c->stats.imp_withdraws_ignored++;
|
c->import_stats.withdraws_ignored++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,8 +212,10 @@ pipe_get_status(struct proto *P, byte *buf)
|
|||||||
static void
|
static void
|
||||||
pipe_show_stats(struct pipe_proto *p)
|
pipe_show_stats(struct pipe_proto *p)
|
||||||
{
|
{
|
||||||
struct proto_stats *s1 = &p->pri->stats;
|
struct import_stats *s1i = &p->pri->import_stats;
|
||||||
struct proto_stats *s2 = &p->sec->stats;
|
struct export_stats *s1e = &p->pri->export_stats;
|
||||||
|
struct import_stats *s2i = &p->sec->import_stats;
|
||||||
|
struct export_stats *s2e = &p->sec->export_stats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pipe stats (as anything related to pipes) are a bit tricky. There
|
* Pipe stats (as anything related to pipes) are a bit tricky. There
|
||||||
@ -237,20 +239,20 @@ pipe_show_stats(struct pipe_proto *p)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
cli_msg(-1006, " Routes: %u imported, %u exported",
|
cli_msg(-1006, " Routes: %u imported, %u exported",
|
||||||
s1->imp_routes, s2->imp_routes);
|
s1i->routes, s2i->routes);
|
||||||
cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
|
cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
|
||||||
cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
|
cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
|
||||||
s2->exp_updates_received, s2->exp_updates_rejected + s1->imp_updates_invalid,
|
s2e->updates_received, s2e->updates_rejected + s1i->updates_invalid,
|
||||||
s2->exp_updates_filtered, s1->imp_updates_ignored, s1->imp_updates_accepted);
|
s2e->updates_filtered, s1i->updates_ignored, s1i->updates_accepted);
|
||||||
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
|
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
|
||||||
s2->exp_withdraws_received, s1->imp_withdraws_invalid,
|
s2e->withdraws_received, s1i->withdraws_invalid,
|
||||||
s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
|
s1i->withdraws_ignored, s1i->withdraws_accepted);
|
||||||
cli_msg(-1006, " Export updates: %10u %10u %10u %10u %10u",
|
cli_msg(-1006, " Export updates: %10u %10u %10u %10u %10u",
|
||||||
s1->exp_updates_received, s1->exp_updates_rejected + s2->imp_updates_invalid,
|
s1e->updates_received, s1e->updates_rejected + s2i->updates_invalid,
|
||||||
s1->exp_updates_filtered, s2->imp_updates_ignored, s2->imp_updates_accepted);
|
s1e->updates_filtered, s2i->updates_ignored, s2i->updates_accepted);
|
||||||
cli_msg(-1006, " Export withdraws: %10u %10u --- %10u %10u",
|
cli_msg(-1006, " Export withdraws: %10u %10u --- %10u %10u",
|
||||||
s1->exp_withdraws_received, s2->imp_withdraws_invalid,
|
s1e->withdraws_received, s2i->withdraws_invalid,
|
||||||
s2->imp_withdraws_ignored, s2->imp_withdraws_accepted);
|
s2i->withdraws_ignored, s2i->withdraws_accepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *pipe_feed_state[] = { [ES_DOWN] = "down", [ES_FEEDING] = "feed", [ES_READY] = "up" };
|
static const char *pipe_feed_state[] = { [ES_DOWN] = "down", [ES_FEEDING] = "feed", [ES_READY] = "up" };
|
||||||
|
Loading…
Reference in New Issue
Block a user