diff options
-rw-r--r-- | conf/confbase.Y | 1 | ||||
-rw-r--r-- | doc/bird.sgml | 5 | ||||
-rw-r--r-- | proto/bfd/bfd.c | 17 | ||||
-rw-r--r-- | proto/bfd/bfd.h | 13 | ||||
-rw-r--r-- | proto/bfd/config.Y | 34 |
5 files changed, 47 insertions, 23 deletions
diff --git a/conf/confbase.Y b/conf/confbase.Y index b2471198..ed3c1e6e 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -89,6 +89,7 @@ CF_DECLS struct lsadb_show_data *ld; struct mrt_dump_data *md; struct mpls_show_ranges_cmd *msrc; + struct bfd_show_sessions_cmd *bssc; struct iface *iface; void *g; btime time; diff --git a/doc/bird.sgml b/doc/bird.sgml index aeecb1dc..ced927d4 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1288,8 +1288,9 @@ This argument can be omitted if there exists only a single instance. <tag><label id="cli-show-static">show static [<m/name/]</tag> Show detailed information about static routes. - <tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/]</tag> - Show information about BFD sessions. + <tag><label id="cli-show-bfd-sessions">show bfd sessions [<m/name/] [address (<m/IP/|<m/prefix/)] [(interface|dev) "<m/name/"] [ipv4|ipv6] [direct|multihop] [all]</tag> + Show information about BFD sessions. Options could be used to filter + entries, or in the case of the option <cf/all/ to give verbose output. <tag><label id="cli-show-symbols">show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag> Show the list of symbols defined in the configuration (names of diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index b9461085..41d8e210 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -1256,7 +1256,7 @@ bfd_show_session(struct bfd_session *s, int details) } void -bfd_show_sessions(struct proto *P, int details, net_addr addr) +bfd_show_sessions(struct proto *P, struct bfd_show_sessions_cmd *args) { struct bfd_proto *p = (struct bfd_proto *) P; @@ -1267,16 +1267,25 @@ bfd_show_sessions(struct proto *P, int details, net_addr addr) } cli_msg(-1020, "%s:", p->p.name); - if (!details) + if (!args->verbose) cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s", "IP address", "Interface", "State", "Since", "Interval", "Timeout"); HASH_WALK(p->session_hash_id, next_id, s) { - if (addr.type != 0 && !ipa_in_netX(s->addr, &addr)) + if (args->address.type && !ipa_in_netX(s->addr, &args->address)) + continue; + + if (args->iface && (s->ifa->iface != args->iface)) + continue; + + if (ipa_is_ip4(s->addr) ? args->ipv6 : args->ipv4) + continue; + + if (s->ifa->iface ? args->multihop : args->direct) continue; - bfd_show_session(s, details); + bfd_show_session(s, args->verbose); } HASH_WALK_END; } diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index 83c1c884..e711bc80 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -172,6 +172,17 @@ struct bfd_session u32 tx_csn_time; /* Timestamp of last tx_csn change */ }; +struct bfd_show_sessions_cmd { + net_addr address; + struct iface *iface; + struct symbol *name; + u8 verbose; + u8 ipv4; + u8 ipv6; + u8 direct; + u8 multihop; +}; + extern const char *bfd_state_names[]; @@ -218,7 +229,7 @@ static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unloc struct bfd_session * bfd_find_session_by_id(struct bfd_proto *p, u32 id); struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex); void bfd_session_process_ctl(struct bfd_session *s, u8 flags, u32 old_tx_int, u32 old_rx_int); -void bfd_show_sessions(struct proto *P, int details, net_addr addr); +void bfd_show_sessions(struct proto *P, struct bfd_show_sessions_cmd *args); /* packets.c */ void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final); diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index da687b5f..4edc13d9 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -29,7 +29,7 @@ CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE, %type <iface> bfd_neigh_iface %type <a> bfd_neigh_local %type <i> bfd_neigh_multihop bfd_auth_type -%type <net> opt_addr +%type <bssc> bfd_show_sessions_args CF_GRAMMAR @@ -182,24 +182,26 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop cf_error("Multihop neighbor requires specified local address"); }; -opt_addr: - /* empty */ { - net_addr addr; - addr.type = 0; - $$ = addr; } - | net_ip4_ - | net_ip6_ - | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); } - | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); } - - CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); -CF_CLI(SHOW BFD SESSIONS, optproto opt_addr, [<name>] [<addr>], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p, 0, $5); }; -CF_CLI(SHOW BFD SESSIONS ALL, optproto opt_addr, [<name>] [<addr>], [[Show information about BFD sessions]]) -{ PROTO_WALK_CMD($5, &proto_bfd, p) bfd_show_sessions(p, 1, $6); }; +CF_CLI_HELP(SHOW BFD SESSIONS, ..., [[Show information about BFD sessions]]); +CF_CLI(SHOW BFD SESSIONS, bfd_show_sessions_args, [<name>] [address <ip|prefix>] [(interface|dev) \"<name>\"] [ipv4|ipv6] [direct|multihop] [all], [[Show information about BFD sessions]]) +{ PROTO_WALK_CMD($4->name, &proto_bfd, p) bfd_show_sessions(p, $4); }; + +bfd_show_sessions_args: + /* empty */ { $$ = cfg_allocz(sizeof(struct bfd_show_sessions_cmd)); } + | bfd_show_sessions_args CF_SYM_KNOWN { cf_assert_symbol($2, SYM_PROTO); $$->name = $2; } + | bfd_show_sessions_args ADDRESS net_or_ipa { net_copy(&($$->address), &($3)); } + | bfd_show_sessions_args INTERFACE text { $$->iface = if_get_by_name($3); } + | bfd_show_sessions_args DEV text { $$->iface = if_get_by_name($3); } + | bfd_show_sessions_args ALL { $$->verbose = 1; } + | bfd_show_sessions_args IPV4 { $$->ipv4 = 1; if ($$->ipv6) cf_error("Options 'ipv4' and 'ipv6' are mutually exclusive"); } + | bfd_show_sessions_args IPV6 { $$->ipv6 = 1; if ($$->ipv4) cf_error("Options 'ipv4' and 'ipv6' are mutually exclusive"); } + | bfd_show_sessions_args DIRECT { $$->direct = 1; if ($$->multihop) cf_error("Options 'direct' and 'multihop' are mutually exclusive"); } + | bfd_show_sessions_args MULTIHOP { $$->multihop = 1; if ($$->direct) cf_error("Options 'direct' and 'multihop' are mutually exclusive"); } + ; + CF_CODE |