1023 Show Babel interfaces
1024 Show Babel neighbors
1025 Show Babel entries
+1026 Show table
8000 Reply too long
8001 Route not found
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)
%type <i32> idval
%type <f> imexport
-%type <r> rtable
+%type <r> rtable rtable_spec
%type <s> optsym
%type <ra> r_args
%type <sd> sym_args
| SEC { $$ = "sec"; }
;
+CF_CLI(SHOW TABLE STATISTICS, rtable_spec, (<table> | 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|<symbol>], [[Show all known symbolic names]])
{ cmd_show_symbols($3); } ;
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,
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;
#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"
}
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)
}
+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
*/