diff --git a/nest/proto.c b/nest/proto.c index caf99829..4b0ee643 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -2587,20 +2587,20 @@ channel_show_stats(struct channel *c) cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred", in_routes, out_routes, SRI(pref)); - cli_msg(-1006, " Route change stats: received rejected filtered ignored RX limit IN limit accepted"); + cli_msg(-1006, " Route change stats: received rejected filtered ignored RX limit limit accepted"); cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u %10u %10u", SCI(updates_received), SCI(updates_invalid), SCI(updates_filtered), SRI(updates_ignored), SCI(updates_limited_rx), SCI(updates_limited_in), SRI(updates_accepted)); - cli_msg(-1006, " Import withdraws: %10u %10u --- %10u --- %10u", + cli_msg(-1006, " Import withdraws: %10u %10u --- %10u --- --- %10u", SCI(withdraws_received), SCI(withdraws_invalid), SRI(withdraws_ignored), SRI(withdraws_accepted)); - cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u %10u", - SRE(updates_received), SCE(updates_rejected), - SCE(updates_filtered), SCE(updates_limited), SCE(updates_accepted)); - cli_msg(-1006, " Export withdraws: %10u --- --- --- ---%10u", - SRE(withdraws_received), SCE(withdraws_accepted)); + cli_msg(-1006, " Export updates: %10u %10u %10u %10u --- %10u %10u", + SRE(updates_received), SCE(updates_rejected), SCE(updates_filtered), + SCE(updates_ignored), SCE(updates_limited), SCE(updates_accepted)); + cli_msg(-1006, " Export withdraws: %10u --- --- %10u --- --- %10u", + SRE(withdraws_received), SCE(withdraws_ignored), SCE(withdraws_accepted)); #undef SRI #undef SRE diff --git a/nest/protocol.h b/nest/protocol.h index ec561b26..75134b2c 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -637,10 +637,12 @@ struct channel { struct channel_export_stats { /* Export - from core to protocol */ + u32 updates_ignored; /* Number of route updates ignored (squashed) by channel */ 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 updates_limited; /* Number of route updates exceeding the out_limit */ + u32 withdraws_ignored; /* Number of route withdraws ignored (squashed) by channel */ u32 withdraws_accepted; /* Number of route withdraws accepted and processed */ } export_stats; diff --git a/nest/rt-export.c b/nest/rt-export.c index 7d51e54c..3c69d025 100644 --- a/nest/rt-export.c +++ b/nest/rt-export.c @@ -104,6 +104,7 @@ rt_export_get(struct rt_export_request *r) { /* Feeding more */ rtex_trace(r, D_ROUTES, "Feeding %N", feed->ni->addr); + r->stats.updates_received += feed->count_routes; EXPORT_FOUND(RT_EXPORT_FEED); } else if (rt_export_get_state(r) == TES_DOWN) @@ -158,12 +159,18 @@ rt_export_get(struct rt_export_request *r) ASSERT_DIE(feed && (feed != &rt_feed_index_out_of_range)); + r->stats.updates_received += feed->count_routes; EXPORT_FOUND(RT_EXPORT_FEED); } /* OK, now this actually is an update, thank you for your patience */ rtex_trace(r, D_ROUTES, "Updating %N, seq %lu", n, update->seq); + if (update->new) + r->stats.updates_received++; + else + r->stats.withdraws_received++; + EXPORT_FOUND(RT_EXPORT_UPDATE); } diff --git a/nest/rt-table.c b/nest/rt-table.c index 05191d74..c454e69f 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1131,7 +1131,7 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, const rte *old) if (!old && new) if (CHANNEL_LIMIT_PUSH(c, OUT)) { - stats->updates_rejected++; + stats->updates_limited++; channel_rte_trace_out(D_FILTERS, c, new, "rejected [limit]"); return; } @@ -1165,6 +1165,10 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old) { const rte *trte = new ?: old; + /* Have we exported the old route? */ + if (old && !bmap_test(&c->export_accepted_map, old->id)) + old = NULL; + /* Ignore invalid routes */ if (!rte_is_valid(new)) new = NULL; @@ -1175,6 +1179,7 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old) if (!new && !old) { channel_rte_trace_out(D_ROUTES, c, trte, "idempotent withdraw (filtered on import)"); + c->export_stats.withdraws_ignored++; return; } @@ -1196,14 +1201,11 @@ rt_notify_basic(struct channel *c, const rte *new, const rte *old) np = export_filter(c, &n0, 0); } - /* Have we exported the old route? */ - if (old && !bmap_test(&c->export_accepted_map, old->id)) - old = NULL; - /* Withdraw to withdraw. */ if (!np && !old) { channel_rte_trace_out(D_ROUTES, c, trte, "idempotent withdraw (filtered on export)"); + /* No stats update, done in export_filter() */ return; } @@ -1523,6 +1525,18 @@ channel_notify_basic(void *_channel) */ if ((rpe->it.old == new) && (new || src && (src == rpe->it.new->src))) { + /* Fix the stats: the old item is squashed (ignored) */ + if (new) + c->export_stats.updates_ignored++; + else + c->export_stats.withdraws_ignored++; + + /* Fix the stats: the new update is received */ + if (rpe->it.new) + c->out_req.stats.updates_received++; + else + c->out_req.stats.withdraws_received++; + new = rpe->it.new; rt_export_processed(&c->out_req, rpe->it.seq); } @@ -1538,7 +1552,10 @@ channel_notify_basic(void *_channel) } } else if (!new && !old) + { channel_rte_trace_out(D_ROUTES, c, u->update->new, "idempotent withdraw (squash)"); + c->export_stats.withdraws_ignored++; + } else rt_notify_basic(c, new, old); @@ -2147,7 +2164,10 @@ channel_preimport(struct rt_import_request *req, rte *new, const rte *old) if (new && !old) if (CHANNEL_LIMIT_PUSH(c, RX)) + { + c->import_stats.updates_limited_rx++; return 0; + } if (!new && old) CHANNEL_LIMIT_POP(c, RX); @@ -2162,7 +2182,10 @@ channel_preimport(struct rt_import_request *req, rte *new, const rte *old) if (c->in_keep & RIK_REJECTED) new->flags |= REF_FILTERED; else + { + c->import_stats.updates_limited_in++; verdict = 0; + } if (!new_in && old_in) CHANNEL_LIMIT_POP(c, IN);