From 5a96090a5b5b3d39943ba22201d977df4e101880 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Wed, 24 Oct 2018 16:18:36 +0200 Subject: [PATCH] Nest: Statistics Adds command 'show table statistics' to show statistics related to routing tables. --- doc/reply_codes | 1 + nest/config.Y | 12 +++++++++-- nest/route.h | 5 +++++ nest/rt-table.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/doc/reply_codes b/doc/reply_codes index 3a7f2c90..e8704335 100644 --- a/doc/reply_codes +++ b/doc/reply_codes @@ -60,6 +60,7 @@ Reply codes of BIRD command-line interface 1023 Show Babel interfaces 1024 Show Babel neighbors 1025 Show Babel entries +1026 Show table 8000 Reply too long 8001 Route not found diff --git a/nest/config.Y b/nest/config.Y index ab09a10c..5f89918a 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -74,7 +74,7 @@ CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENER CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION, SORTED) CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP) CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US) -CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS) +CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS, STATISTICS) /* For r_args_channel */ CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC) @@ -87,7 +87,7 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID) %type idval %type imexport -%type rtable +%type rtable rtable_spec %type optsym %type r_args %type sym_args @@ -688,6 +688,14 @@ r_args_channel: | SEC { $$ = "sec"; } ; +CF_CLI(SHOW TABLE STATISTICS, rtable_spec, ( | all), [[Show routing table details]]) +{ cmd_show_table_stats($4); } ; + +rtable_spec: + rtable { $$ = $1; } + | ALL { $$ = NULL; } + ; + CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]]) CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|], [[Show all known symbolic names]]) { cmd_show_symbols($3); } ; diff --git a/nest/route.h b/nest/route.h index 79127519..c52b7592 100644 --- a/nest/route.h +++ b/nest/route.h @@ -151,6 +151,9 @@ typedef struct rtable { uint addr_type; /* Type of address data stored in table (NET_*) */ int pipe_busy; /* Pipe loop detection */ int use_count; /* Number of protocols using this table */ + uint route_count; /* Number of routes in the table */ + uint route_updates; /* Number of accepted route updates */ + uint route_withdraws; /* Number of accepted route withdraws */ struct hostcache *hostcache; struct rtable_config *config; /* Configuration of this table */ struct config *deleted; /* Table doesn't exist in current configuration, @@ -308,6 +311,8 @@ void rt_dump_all(void); int rt_feed_channel(struct channel *c); void rt_feed_channel_abort(struct channel *c); struct rtable_config *rt_new_table(struct symbol *s, uint addr_type); +void cmd_show_table_stats(struct rtable_config *tab); + /* Default limit for ECMP next hops, defined in sysdep code */ extern const int rt_default_ecmp; diff --git a/nest/rt-table.c b/nest/rt-table.c index b885c6e3..293138d1 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -34,6 +34,7 @@ #include "nest/route.h" #include "nest/protocol.h" #include "nest/iface.h" +#include "nest/cli.h" #include "lib/resource.h" #include "lib/event.h" #include "lib/string.h" @@ -1125,14 +1126,19 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) } if (new_ok) - stats->imp_updates_accepted++; + { stats->imp_updates_accepted++; table->route_updates++; } else if (old_ok) - stats->imp_withdraws_accepted++; + { stats->imp_withdraws_accepted++; table->route_withdraws++; } else stats->imp_withdraws_ignored++; skip_stats1: + if (new_ok) + table->route_count++; + if (old_ok) + table->route_count--; + if (new) rte_is_filtered(new) ? stats->filt_routes++ : stats->imp_routes++; if (old) @@ -2541,6 +2547,51 @@ rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep) } +static void +rt_show_table_stats(rtable *tab) +{ + cli_msg(-1026, "%s:", tab->name); + cli_msg(-1026, "Table type:\t\t%s", net_label[tab->addr_type]); + cli_msg(-1026, "Hash table size:\t%u", tab->fib.hash_size); + cli_msg(-1026, "Hash entry count:\t%u", tab->fib.entries); + cli_msg(-1026, "Total route count:\t%u", tab->route_count); + cli_msg(-1026, "Route updates:\t\t%u", tab->route_updates); + cli_msg(-1026, "Route withdraws:\t%u", tab->route_withdraws); + + cli_msg(-1026, ""); + cli_msg(-1026, "%-16s %10s %10s %10s", "Protocol", "Routes", "Updates", "Withdraws"); + + struct channel *c; node *n; + WALK_LIST2(c, n, tab->channels, table_node) + { + if (c->channel_state == CS_DOWN) + continue; + + cli_msg(-1026, "%-16s %10u %10u %10u", c->proto->name, c->stats.imp_routes, + c->stats.imp_updates_accepted, c->stats.imp_withdraws_accepted); + } + cli_msg(-1026, ""); +} + +void +cmd_show_table_stats(struct rtable_config *tab) +{ + if (tab && tab->table) + { + rt_show_table_stats(tab->table); + cli_msg(0, ""); + return; + } + + ASSERT(!tab); + + rtable *t; + WALK_LIST(t, routing_tables) + rt_show_table_stats(t); + + cli_msg(0, ""); +} + /* * Documentation for functions declared inline in route.h */