Commit b2949999 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Nest: Update of show route cmd

Some code cleanup, multiple bugfixes, allows to specify also channel
for 'show route export'. Interesting how such apparenty simple thing
like show route cmd has plenty of ugly corner cases.
parent 6f535924
......@@ -924,13 +924,10 @@ This argument can be omitted if there exists only a single instance.
Show the list of symbols defined in the configuration (names of
protocols, routing tables etc.).
<tag><label id="cli-show-route">show route [[for] <m/prefix/|<m/IP/] [table (<m/t/ | all)] [filter <m/f/|where <m/c/] [(export|preexport|noexport) <m/p/] [protocol <m/p/] [(stats|count) [by table]] [<m/options/]</tag>
<tag><label id="cli-show-route">show route [[for] <m/prefix/|<m/IP/] [table (<m/t/ | all)] [filter <m/f/|where <m/c/] [(export|preexport|noexport) <m/p/] [protocol <m/p/] [(stats|count)] [<m/options/]</tag>
Show contents of specified routing tables, that is routes, their metrics
and (in case the <cf/all/ switch is given) all their attributes.
<p>More tables can be specified by repeating the <cf>table <m/t/></cf> clause.
To cycle over all tables, specify <cf>table all</cf>.
<p>You can specify a <m/prefix/ if you want to print routes for a
specific network. If you use <cf>for <m/prefix or IP/</cf>, you'll get
the entry which will be used for forwarding of packets to the given
......@@ -938,57 +935,39 @@ This argument can be omitted if there exists only a single instance.
the selected one at the top, unless <cf/primary/ is given in which case
only the selected route is shown.
<p>The <cf/show route/ command can process one or multiple routing
tables. The set of selected tables is determined on three levels: First,
tables can be explicitly selected by <cf/table/ switch, which could be
used multiple times, all tables are specified by <cf/table all/. Second,
tables can be implicitly selected by channels or protocols that are
arguments of several other switches (e.g., <cf/export/, <cf/protocol/).
Last, the set of default tables is used: <cf/master4/, <cf/master6/ and
each first table of any other network type.
<p>You can also ask for printing only routes processed and accepted by
a given filter (<cf>filter <m/name/</cf> or <cf>filter { <m/filter/ }
</cf> or matching a given condition (<cf>where <m/condition/</cf>).
The <cf/export/, <cf/preexport/ and <cf/noexport/ switches ask for
printing of routes that are exported to the specified protocol.
With <cf/preexport/, the export filter of the protocol is skipped.
With <cf/noexport/, routes rejected by the export filter are printed
instead. Note that routes not exported to the protocol for other reasons
printing of routes that are exported to the specified protocol or
channel. With <cf/preexport/, the export filter of the channel is
skipped. With <cf/noexport/, routes rejected by the export filter are
printed instead. Note that routes not exported for other reasons
(e.g. secondary routes or routes imported from that protocol) are not
printed even with <cf/noexport/. These switches magically cycle over
all tables connected to the protocol.
printed even with <cf/noexport/. These switches also imply that
associated routing tables are selected instead of default ones.
<p>You can also select just routes added by a specific protocol.
<cf>protocol <m/p/</cf>. This switch also magically cycles over
all tables connected to the protocol.
<cf>protocol <m/p/</cf>. This switch also implies that associated
routing tables are selected instead of default ones.
<p>If BIRD is configured to keep filtered routes (see <cf/import keep
filtered/ option), you can show them instead of routes by using
<cf/filtered/ switch.
<p>If no table is specified in any way (<cf/table/, <cf/export/, <cf/preexport/, <cf/noexport/, <cf/protocol/),
the default tables are listed: <cf/master4/, <cf/master6/
and first declared table of any other net type.
<p>The <cf/stats/ switch requests showing of route statistics (the
number of networks, number of routes before and after filtering). If
you use <cf/count/ instead, only the statistics will be printed.
If you use <cf/stats by table/ or <cf/count by table/, the statistics
will be printed also per-table.
<tag><label id="cli-show-roa">show roa [<m/prefix/ | in <m/prefix/ | for <m/prefix/] [as <m/num/] [table <m/t/]</tag>
Show contents of a ROA table (by default of the first one). You can
specify a <m/prefix/ to print ROA entries for a specific network. If you
use <cf>for <m/prefix/</cf>, you'll get all entries relevant for route
validation of the network prefix; i.e., ROA entries whose prefixes cover
the network prefix. Or you can use <cf>in <m/prefix/</cf> to get ROA
entries covered by the network prefix. You could also use <cf/as/ option
to show just entries for given AS.
<tag><label id="cli-add-roa">add roa <m/prefix/ max <m/num/ as <m/num/ [table <m/t/]</tag>
Add a new ROA entry to a ROA table. Such entry is called <it/dynamic/
compared to <it/static/ entries specified in the config file. These
dynamic entries survive reconfiguration.
<tag><label id="cli-delete-roa">delete roa <m/prefix/ max <m/num/ as <m/num/ [table <m/t/]</tag>
Delete the specified ROA entry from a ROA table. Only dynamic ROA
entries (i.e., the ones added by <cf/add roa/ command) can be deleted.
<tag><label id="cli-flush-roa">flush roa [table <m/t/]</tag>
Remove all dynamic ROA entries from a ROA table.
<tag><label id="cli-configure">configure [soft] ["<m/config file/"] [timeout [<m/num/]]</tag>
Reload configuration from a given file. BIRD will smoothly switch itself
......
......@@ -75,6 +75,9 @@ CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SO
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
/* For r_args_channel */
CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL)
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
......@@ -93,6 +96,7 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <cl> limit_spec
%type <net> r_args_for_val
%type <net_ptr> r_args_for
%type <t> r_args_channel
CF_GRAMMAR
......@@ -514,7 +518,7 @@ CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filte
r_args:
/* empty */ {
$$ = cfg_allocz(sizeof(struct rt_show_data));
init_list(&($$->table));
init_list(&($$->tables));
$$->filter = FILTER_ACCEPT;
}
| r_args net_any {
......@@ -566,13 +570,24 @@ r_args:
| r_args export_mode SYM {
struct proto_config *c = (struct proto_config *) $3->def;
$$ = $1;
if ($$->export_mode) cf_error("Protocol specified twice");
if ($$->export_mode) cf_error("Export specified twice");
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->export_mode = $2;
$$->export_protocol = c->proto;
$$->running_on_config = c->proto->cf->global;
$$->tables_defined_by = RSD_TDB_INDIRECT;
}
| r_args export_mode SYM '.' r_args_channel {
struct proto_config *c = (struct proto_config *) $3->def;
$$ = $1;
if ($$->export_mode) cf_error("Export specified twice");
if ($3->class != SYM_PROTO || !c->proto) cf_error("%s is not a protocol", $3->name);
$$->export_mode = $2;
$$->export_channel = proto_find_channel_by_name(c->proto, $5);
if (!$$->export_channel) cf_error("Export channel not found");
$$->running_on_config = c->proto->cf->global;
$$->tables_defined_by = RSD_TDB_INDIRECT;
}
| r_args PROTOCOL SYM {
struct proto_config *c = (struct proto_config *) $3->def;
$$ = $1;
......@@ -590,16 +605,6 @@ r_args:
$$ = $1;
$$->stats = 2;
}
| r_args STATS BY TABLE {
$$ = $1;
$$->stats = 1;
$$->stats_by_table = 1;
}
| r_args COUNT BY TABLE {
$$ = $1;
$$->stats = 2;
$$->stats_by_table = 1;
}
;
r_args_for:
......@@ -642,6 +647,28 @@ export_mode:
| NOEXPORT { $$ = RSEM_NOEXPORT; }
;
/* This is ugly hack */
r_args_channel:
IPV4 { $$ = "ipv4"; }
| IPV4_MC { $$ = "ipv4-mc"; }
| IPV4_MPLS { $$ = "ipv4-mpls"; }
| IPV6 { $$ = "ipv6"; }
| IPV6_MC { $$ = "ipv6-mc"; }
| IPV6_MPLS { $$ = "ipv6-mpls"; }
| VPN4 { $$ = "vpn4"; }
| VPN4_MC { $$ = "vpn4-mc"; }
| VPN4_MPLS { $$ = "vpn4-mpls"; }
| VPN6 { $$ = "vpn6"; }
| VPN6_MC { $$ = "vpn6-mc"; }
| VPN6_MPLS { $$ = "vpn6-mpls"; }
| ROA4 { $$ = "roa4"; }
| ROA6 { $$ = "roa6"; }
| FLOW4 { $$ = "flow4"; }
| FLOW6 { $$ = "flow6"; }
| MPLS { $$ = "mpls"; }
| PRI { $$ = "pri"; }
| SEC { $$ = "sec"; }
;
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]])
......
......@@ -104,6 +104,25 @@ proto_find_channel_by_table(struct proto *p, struct rtable *t)
return NULL;
}
/**
* proto_find_channel_by_name - find channel by its name
* @p: protocol instance
* @n: channel name
*
* Returns pointer to channel or NULL
*/
struct channel *
proto_find_channel_by_name(struct proto *p, const char *n)
{
struct channel *c;
WALK_LIST(c, p->channels)
if (!strcmp(c->name, n))
return c;
return NULL;
}
/**
* proto_add_channel - connect protocol to a routing table
* @p: protocol instance
......
......@@ -563,6 +563,7 @@ static inline struct channel_config *proto_cf_main_channel(struct proto_config *
{ struct channel_config *cc = HEAD(pc->channels); return NODE_VALID(cc) ? cc : NULL; }
struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
......
......@@ -313,26 +313,30 @@ struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
struct rt_show_data_rtable {
node n;
rtable *table;
struct channel *export_channel;
};
struct rt_show_data {
net_addr *addr;
list table;
struct rt_show_data_rtable *tit;
struct filter *filter;
list tables;
struct rt_show_data_rtable *tab; /* Iterator over table list */
struct rt_show_data_rtable *last_table; /* Last table in output */
struct fib_iterator fit; /* Iterator over networks in table */
int verbose, tables_defined_by;
struct fib_iterator fit;
struct filter *filter;
struct proto *show_protocol;
struct proto *export_protocol;
struct channel *export_channel;
int export_mode, primary_only, filtered;
struct config *running_on_config;
int export_mode, primary_only, filtered, stats, show_for;
int table_open; /* Iteration (fit) is open */
int net_counter, rt_counter, show_counter, table_counter;
int net_counter_last, rt_counter_last, show_counter_last;
int stats, show_for, stats_by_table;
};
void rt_show(struct rt_show_data *);
void rt_show_add_table(struct rt_show_data *d, rtable *t);
struct rt_show_data_rtable * rt_show_add_table(struct rt_show_data *d, rtable *t);
/* Value of table definition mode in struct rt_show_data */
#define RSD_TDB_DEFAULT 0 /* no table specified */
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment