0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-10 05:08:42 +00:00

Protocol stats split to import and export

This commit is contained in:
Maria Matejka 2021-06-21 19:11:42 +02:00
parent 56c8f2f03a
commit c56752e436
4 changed files with 105 additions and 96 deletions

View File

@ -284,7 +284,7 @@ channel_feed_loop(void *ptr)
if (c->refeeding &&
(l->state == PLS_BLOCKED) &&
(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);
channel_reset_limit(&c->out_limit);
@ -461,7 +461,7 @@ channel_stop_export(struct channel *c)
rt_feed_channel_abort(c);
c->export_state = ES_DOWN;
c->stats.exp_routes = 0;
c->export_stats.routes = 0;
bmap_reset(&c->export_map, 1024);
}
@ -551,7 +551,8 @@ channel_do_start(struct channel *c)
c->feed_event = ev_new_init(c->proto->pool, channel_feed_loop, c);
bmap_init(&c->export_map, c->proto->pool, 1024);
memset(&c->stats, 0, sizeof(struct proto_stats));
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->in_limit);
@ -600,11 +601,12 @@ channel_do_down(struct channel *c)
rt_unlock_table(c->table);
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);
// 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->reload_event = NULL;
@ -1842,19 +1844,19 @@ static void
channel_verify_limits(struct channel *c)
{
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;
if (l->action && (all_routes > l->limit))
channel_notify_limit(c, l, PLD_RX, all_routes);
l = &c->in_limit;
if (l->action && (c->stats.imp_routes > l->limit))
channel_notify_limit(c, l, PLD_IN, c->stats.imp_routes);
if (l->action && (c->import_stats.routes > l->limit))
channel_notify_limit(c, l, PLD_IN, c->import_stats.routes);
l = &c->out_limit;
if (l->action && (c->stats.exp_routes > l->limit))
channel_notify_limit(c, l, PLD_OUT, c->stats.exp_routes);
if (l->action && (c->export_stats.routes > l->limit))
channel_notify_limit(c, l, PLD_OUT, c->export_stats.routes);
}
static inline void
@ -2009,28 +2011,29 @@ proto_state_name(struct proto *p)
static void
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)
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
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, " Import updates: %10u %10u %10u %10u %10u",
s->imp_updates_received, s->imp_updates_invalid,
s->imp_updates_filtered, s->imp_updates_ignored,
s->imp_updates_accepted);
is->updates_received, is->updates_invalid,
is->updates_filtered, is->updates_ignored,
is->updates_accepted);
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
s->imp_withdraws_received, s->imp_withdraws_invalid,
s->imp_withdraws_ignored, s->imp_withdraws_accepted);
is->withdraws_received, is->withdraws_invalid,
is->withdraws_ignored, is->withdraws_accepted);
cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
s->exp_updates_received, s->exp_updates_rejected,
s->exp_updates_filtered, s->exp_updates_accepted);
es->updates_received, es->updates_rejected,
es->updates_filtered, es->updates_accepted);
cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
s->exp_withdraws_received, s->exp_withdraws_accepted);
es->withdraws_received, es->withdraws_accepted);
}
void

View File

@ -132,29 +132,31 @@ struct proto_config {
};
/* Protocol statistics */
struct proto_stats {
struct import_stats {
/* Import - from protocol to core */
u32 imp_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 pref_routes; /* Number of routes selected as best in the (adjacent) routing table */
u32 imp_updates_received; /* Number of route updates received */
u32 imp_updates_invalid; /* Number of route updates rejected as invalid */
u32 imp_updates_filtered; /* Number of route updates rejected by filters */
u32 imp_updates_ignored; /* Number of route updates rejected as already in route table */
u32 imp_updates_accepted; /* Number of route updates accepted and imported */
u32 imp_withdraws_received; /* Number of route withdraws received */
u32 imp_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 imp_withdraws_accepted; /* Number of route withdraws accepted and processed */
u32 routes; /* Number of routes successfully imported to the (adjacent) routing table */
u32 filtered; /* Number of routes rejected in import filter but kept in the routing table */
u32 pref; /* Number of routes selected as best in the (adjacent) routing table */
u32 updates_received; /* Number of route updates received */
u32 updates_invalid; /* Number of route updates rejected as invalid */
u32 updates_filtered; /* Number of route updates rejected by filters */
u32 updates_ignored; /* Number of route updates rejected as already in route table */
u32 updates_accepted; /* Number of route updates accepted and imported */
u32 withdraws_received; /* Number of route withdraws received */
u32 withdraws_invalid; /* Number of route withdraws rejected as invalid */
u32 withdraws_ignored; /* Number of route withdraws rejected as already not in route table */
u32 withdraws_accepted; /* Number of route withdraws accepted and processed */
};
struct export_stats {
/* Export - from core to protocol */
u32 exp_routes; /* Number of routes successfully exported to the protocol */
u32 exp_updates_received; /* Number of route updates received */
u32 exp_updates_rejected; /* Number of route updates rejected by protocol */
u32 exp_updates_filtered; /* Number of route updates rejected by filters */
u32 exp_updates_accepted; /* Number of route updates accepted and exported */
u32 exp_withdraws_received; /* Number of route withdraws received */
u32 exp_withdraws_accepted; /* Number of route withdraws accepted and processed */
u32 routes; /* Number of routes successfully exported to the protocol */
u32 updates_received; /* Number of route updates received */
u32 updates_rejected; /* Number of route updates rejected by protocol */
u32 updates_filtered; /* Number of route updates rejected by filters */
u32 updates_accepted; /* Number of route updates accepted and exported */
u32 withdraws_received; /* Number of route withdraws received */
u32 withdraws_accepted; /* Number of route withdraws accepted and processed */
};
struct proto {
@ -516,7 +518,9 @@ struct channel {
struct event *feed_event; /* Event responsible for 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 */
u8 net_type; /* Routing table network type (NET_*), 0 for undefined */

View File

@ -375,7 +375,7 @@ export_filter_(struct channel *c, rte *rt, linpool *pool, int silent)
{
struct proto *p = c->proto;
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;
@ -384,7 +384,7 @@ export_filter_(struct channel *c, rte *rt, linpool *pool, int silent)
if (silent)
goto reject;
stats->exp_updates_rejected++;
stats->updates_rejected++;
if (v == RIC_REJECT)
rte_trace_out(D_FILTERS, c, rt, "rejected by protocol");
goto reject;
@ -404,7 +404,7 @@ export_filter_(struct channel *c, rte *rt, linpool *pool, int silent)
if (silent)
goto reject;
stats->exp_updates_filtered++;
stats->updates_filtered++;
rte_trace_out(D_FILTERS, c, rt, "filtered out");
goto reject;
}
@ -427,7 +427,7 @@ static void
do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
{
struct proto *p = c->proto;
struct proto_stats *stats = &c->stats;
struct export_stats *stats = &c->export_stats;
if (refeed && new)
c->refeed_count++;
@ -436,12 +436,12 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
struct channel_limit *l = &c->out_limit;
if (l->action && !old && new)
{
if (stats->exp_routes >= l->limit)
channel_notify_limit(c, l, PLD_OUT, stats->exp_routes);
if (stats->routes >= l->limit)
channel_notify_limit(c, l, PLD_OUT, stats->routes);
if (l->state == PLS_BLOCKED)
{
stats->exp_updates_rejected++;
stats->updates_rejected++;
rte_trace_out(D_FILTERS, c, new, "rejected [limit]");
return;
}
@ -459,20 +459,20 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
}
if (new)
stats->exp_updates_accepted++;
stats->updates_accepted++;
else
stats->exp_withdraws_accepted++;
stats->withdraws_accepted++;
if (old)
{
bmap_clear(&c->export_map, old->id);
stats->exp_routes--;
stats->routes--;
}
if (new)
{
bmap_set(&c->export_map, new->id);
stats->exp_routes++;
stats->routes++;
}
if (p->debug & D_ROUTES)
@ -495,9 +495,9 @@ static void
rt_notify_basic(struct channel *c, const net_addr *net, rte *new, rte *old, int refeed)
{
if (new)
c->stats.exp_updates_received++;
c->export_stats.updates_received++;
else
c->stats.exp_withdraws_received++;
c->export_stats.withdraws_received++;
if (new)
new = export_filter(c, new, 0);
@ -537,9 +537,9 @@ rt_notify_accepted(struct channel *c, net *net, rte *new_changed, rte *old_chang
*/
if (net->routes)
c->stats.exp_updates_received++;
c->export_stats.updates_received++;
else
c->stats.exp_withdraws_received++;
c->export_stats.withdraws_received++;
/* Find old_best - either old_changed, or route for net->routes */
if (old_changed && bmap_test(&c->export_map, old_changed->id))
@ -655,9 +655,9 @@ rt_notify_merged(struct channel *c, net *net, rte *new_changed, rte *old_changed
return;
if (new_best)
c->stats.exp_updates_received++;
c->export_stats.updates_received++;
else
c->stats.exp_withdraws_received++;
c->export_stats.withdraws_received++;
/* Prepare new merged route */
if (new_best)
@ -735,9 +735,9 @@ rte_announce(rtable *tab, uint type, net *net, struct rte_storage *new, struct r
if (new_best != old_best)
{
if (new_best)
new_best->rte.sender->stats.pref_routes++;
new_best->rte.sender->import_stats.pref++;
if (old_best)
old_best->rte.sender->stats.pref_routes--;
old_best->rte.sender->import_stats.pref--;
if (tab->hostcache)
rt_notify_hostcache(tab, net);
@ -836,7 +836,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
{
struct proto *p = c->proto;
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;
rte *old_best = old_best_stored ? &old_best_stored->rte : NULL;
rte *old = NULL;
@ -873,7 +873,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
if (!rte_is_filtered(new))
{
stats->imp_updates_ignored++;
stats->updates_ignored++;
rte_trace_in(D_ROUTES, c, new, "ignored");
}
@ -887,7 +887,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
if (!old && !new)
{
stats->imp_withdraws_ignored++;
stats->withdraws_ignored++;
return;
}
@ -897,7 +897,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
struct channel_limit *l = &c->rx_limit;
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)
channel_notify_limit(c, l, PLD_RX, all_routes);
@ -907,7 +907,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
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]");
return;
}
@ -916,8 +916,8 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
l = &c->in_limit;
if (l->action && !old_ok && new_ok)
{
if (stats->imp_routes >= l->limit)
channel_notify_limit(c, l, PLD_IN, stats->imp_routes);
if (stats->routes >= l->limit)
channel_notify_limit(c, l, PLD_IN, stats->routes);
if (l->state == PLS_BLOCKED)
{
@ -928,7 +928,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
already handled. */
stats->imp_updates_ignored++;
stats->updates_ignored++;
rte_trace_in(D_FILTERS, c, new, "ignored [limit]");
if (c->in_keep_filtered)
@ -948,11 +948,11 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
}
if (new_ok)
stats->imp_updates_accepted++;
stats->updates_accepted++;
else if (old_ok)
stats->imp_withdraws_accepted++;
stats->withdraws_accepted++;
else
stats->imp_withdraws_ignored++;
stats->withdraws_ignored++;
if (old_ok || new_ok)
table->last_rt_change = current_time();
@ -961,9 +961,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;
if (new)
rte_is_filtered(new) ? stats->filt_routes++ : stats->imp_routes++;
rte_is_filtered(new) ? stats->filtered++ : stats->routes++;
if (old)
rte_is_filtered(old) ? stats->filt_routes-- : stats->imp_routes--;
rte_is_filtered(old) ? stats->filtered-- : stats->routes--;
if (table->config->sorted)
{
@ -1128,7 +1128,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))
return;
struct proto_stats *stats = &c->stats;
struct import_stats *stats = &c->import_stats;
const struct filter *filter = c->in_filter;
net *nn;
@ -1140,17 +1140,17 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
new->net = n;
new->sender = c;
stats->imp_updates_received++;
stats->updates_received++;
if (!rte_validate(new))
{
rte_trace_in(D_FILTERS, c, new, "invalid");
stats->imp_updates_invalid++;
stats->updates_invalid++;
goto drop;
}
if (filter == FILTER_REJECT)
{
stats->imp_updates_filtered++;
stats->updates_filtered++;
rte_trace_in(D_FILTERS, c, new, "filtered out");
if (! c->in_keep_filtered)
@ -1164,7 +1164,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);
if (fr > F_ACCEPT)
{
stats->imp_updates_filtered++;
stats->updates_filtered++;
rte_trace_in(D_FILTERS, c, new, "filtered out");
if (! c->in_keep_filtered)
@ -1180,11 +1180,11 @@ rte_update(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
}
else
{
stats->imp_withdraws_received++;
stats->withdraws_received++;
if (!(nn = net_find(c->table, n)) || !src)
{
stats->imp_withdraws_ignored++;
stats->withdraws_ignored++;
rte_update_unlock();
return;
}
@ -2297,8 +2297,8 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
return 1;
drop_update:
c->stats.imp_updates_received++;
c->stats.imp_updates_ignored++;
c->import_stats.updates_received++;
c->import_stats.updates_ignored++;
if (!net->routes)
fib_delete(&tab->fib, net);
@ -2306,8 +2306,8 @@ drop_update:
return 0;
drop_withdraw:
c->stats.imp_withdraws_received++;
c->stats.imp_withdraws_ignored++;
c->import_stats.withdraws_received++;
c->import_stats.withdraws_ignored++;
return 0;
}

View File

@ -212,8 +212,10 @@ pipe_get_status(struct proto *P, byte *buf)
static void
pipe_show_stats(struct pipe_proto *p)
{
struct proto_stats *s1 = &p->pri->stats;
struct proto_stats *s2 = &p->sec->stats;
struct import_stats *s1i = &p->pri->import_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
@ -237,20 +239,20 @@ pipe_show_stats(struct pipe_proto *p)
*/
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, " Import updates: %10u %10u %10u %10u %10u",
s2->exp_updates_received, s2->exp_updates_rejected + s1->imp_updates_invalid,
s2->exp_updates_filtered, s1->imp_updates_ignored, s1->imp_updates_accepted);
s2e->updates_received, s2e->updates_rejected + s1i->updates_invalid,
s2e->updates_filtered, s1i->updates_ignored, s1i->updates_accepted);
cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
s2->exp_withdraws_received, s1->imp_withdraws_invalid,
s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
s2e->withdraws_received, s1i->withdraws_invalid,
s1i->withdraws_ignored, s1i->withdraws_accepted);
cli_msg(-1006, " Export updates: %10u %10u %10u %10u %10u",
s1->exp_updates_received, s1->exp_updates_rejected + s2->imp_updates_invalid,
s1->exp_updates_filtered, s2->imp_updates_ignored, s2->imp_updates_accepted);
s1e->updates_received, s1e->updates_rejected + s2i->updates_invalid,
s1e->updates_filtered, s2i->updates_ignored, s2i->updates_accepted);
cli_msg(-1006, " Export withdraws: %10u %10u --- %10u %10u",
s1->exp_withdraws_received, s2->imp_withdraws_invalid,
s2->imp_withdraws_ignored, s2->imp_withdraws_accepted);
s1e->withdraws_received, s2i->withdraws_invalid,
s2i->withdraws_ignored, s2i->withdraws_accepted);
}
static const char *pipe_feed_state[] = { [ES_DOWN] = "down", [ES_FEEDING] = "feed", [ES_READY] = "up" };