From: Ondrej Zajicek (work) Date: Thu, 14 May 2020 01:48:17 +0000 (+0200) Subject: Show info from multiple protocols when protocol is not specified X-Git-Tag: v2.0.8~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c26c6bc2d78a2fe76f27dcc9fbb5afc95c3a7626;p=thirdparty%2Fbird.git Show info from multiple protocols when protocol is not specified Most commands like 'show ospf neighbors' fail when protocol is not specified and there are multiple instances of given protocol type. This is annoying in BIRD 2, as many protocols have IPv4 and IPv6 instances. The patch changes that by showing output from all protocol instances of appropriate type. Note that the patch also removes terminating cli_msg() call from these commands and moves it to the common iterating code. --- diff --git a/nest/cli.h b/nest/cli.h index 6040be91c..8a3294c52 100644 --- a/nest/cli.h +++ b/nest/cli.h @@ -58,6 +58,9 @@ void cli_printf(cli *, int, char *, ...); #define cli_msg(x...) cli_printf(this_cli, x) void cli_set_log_echo(cli *, uint mask, uint size); +static inline void cli_separator(cli *c) +{ if (c->last_reply) cli_printf(c, -c->last_reply, ""); }; + /* Functions provided to sysdep layer */ cli *cli_new(void *); diff --git a/nest/proto.c b/nest/proto.c index 850904245..41b3a6b9c 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -2084,3 +2084,47 @@ proto_get_named(struct symbol *sym, struct protocol *pr) return p; } + +struct proto * +proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old) +{ + if (sym) + { + /* Just the first pass */ + if (old) + { + cli_msg(0, ""); + return NULL; + } + + if (sym->class != SYM_PROTO) + cf_error("%s: Not a protocol", sym->name); + + struct proto *p = sym->proto->proto; + if (!p || (p->proto != proto)) + cf_error("%s: Not a %s protocol", sym->name, proto->name); + + return p; + } + else + { + for (struct proto *p = !old ? HEAD(proto_list) : NODE_NEXT(old); + NODE_VALID(p); + p = NODE_NEXT(p)) + { + if ((p->proto == proto) && (p->proto_state != PS_DOWN)) + { + cli_separator(this_cli); + return p; + } + } + + /* Not found anything during first pass */ + if (!old) + cf_error("There is no %s protocol running", proto->name); + + /* No more items */ + cli_msg(0, ""); + return NULL; + } +} diff --git a/nest/protocol.h b/nest/protocol.h index a934c0476..14b6123a8 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -292,6 +292,10 @@ void proto_cmd_mrtdump(struct proto *, uintptr_t, int); void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg); struct proto *proto_get_named(struct symbol *, struct protocol *); +struct proto *proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old); + +#define PROTO_WALK_CMD(sym,pr,p) for(struct proto *p = NULL; p = proto_iterate_named(sym, pr, p); ) + #define CMD_RELOAD 0 #define CMD_RELOAD_IN 1 diff --git a/proto/babel/babel.c b/proto/babel/babel.c index ba98598ba..618abaa8a 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -1891,7 +1891,6 @@ babel_show_interfaces(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1023, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -1915,8 +1914,6 @@ babel_show_interfaces(struct proto *P, const char *iff) ifa->cf->rxcost, nbrs, MAX(timer, 0), ifa->next_hop_ip4, ifa->next_hop_ip6); } - - cli_msg(0, ""); } void @@ -1930,7 +1927,6 @@ babel_show_neighbors(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1024, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -1955,8 +1951,6 @@ babel_show_neighbors(struct proto *P, const char *iff) n->addr, ifa->iface->name, n->cost, rts, hellos, MAX(timer, 0)); } } - - cli_msg(0, ""); } static void @@ -1998,7 +1992,6 @@ babel_show_entries(struct proto *P) if (p->p.proto_state != PS_UP) { cli_msg(-1025, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -2008,8 +2001,6 @@ babel_show_entries(struct proto *P) babel_show_entries_(p, &p->ip4_rtable); babel_show_entries_(p, &p->ip6_rtable); - - cli_msg(0, ""); } static void @@ -2041,7 +2032,6 @@ babel_show_routes(struct proto *P) if (p->p.proto_state != PS_UP) { cli_msg(-1025, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -2051,8 +2041,6 @@ babel_show_routes(struct proto *P) babel_show_routes_(p, &p->ip4_rtable); babel_show_routes_(p, &p->ip6_rtable); - - cli_msg(0, ""); } diff --git a/proto/babel/config.Y b/proto/babel/config.Y index b6bc70fa8..2f3b637b4 100644 --- a/proto/babel/config.Y +++ b/proto/babel/config.Y @@ -130,16 +130,16 @@ dynamic_attr: BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_BAB CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]); CF_CLI(SHOW BABEL INTERFACES, optproto opttext, [] [\"\"], [[Show information about Babel interfaces]]) -{ babel_show_interfaces(proto_get_named($4, &proto_babel), $5); }; +{ PROTO_WALK_CMD($4, &proto_babel, p) babel_show_interfaces(p, $5); }; CF_CLI(SHOW BABEL NEIGHBORS, optproto opttext, [] [\"\"], [[Show information about Babel neighbors]]) -{ babel_show_neighbors(proto_get_named($4, &proto_babel), $5); }; +{ PROTO_WALK_CMD($4, &proto_babel, p) babel_show_neighbors(p, $5); }; CF_CLI(SHOW BABEL ENTRIES, optproto opttext, [], [[Show information about Babel prefix entries]]) -{ babel_show_entries(proto_get_named($4, &proto_babel)); }; +{ PROTO_WALK_CMD($4, &proto_babel, p) babel_show_entries(p); }; CF_CLI(SHOW BABEL ROUTES, optproto opttext, [], [[Show information about Babel route entries]]) -{ babel_show_routes(proto_get_named($4, &proto_babel)); }; +{ PROTO_WALK_CMD($4, &proto_babel, p) babel_show_routes(p); }; CF_CODE diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index b4c53754b..e303d7a0d 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -1104,7 +1104,6 @@ bfd_show_sessions(struct proto *P) if (p->p.proto_state != PS_UP) { cli_msg(-1020, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -1129,8 +1128,6 @@ bfd_show_sessions(struct proto *P) s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout); } HASH_WALK_END; - - cli_msg(0, ""); } diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index 84d12306c..df1cba42c 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -182,7 +182,7 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); CF_CLI(SHOW BFD SESSIONS, optproto, [], [[Show information about BFD sessions]]) -{ bfd_show_sessions(proto_get_named($4, &proto_bfd)); }; +{ PROTO_WALK_CMD($4, &proto_bfd, p) bfd_show_sessions(p); }; CF_CODE diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index ce9245a1f..fd2cfe8ae 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -513,13 +513,13 @@ dynamic_attr: OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUA CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]); CF_CLI(SHOW OSPF, optproto, [], [[Show information about OSPF protocol]]) -{ ospf_sh(proto_get_named($3, &proto_ospf)); }; +{ PROTO_WALK_CMD($3, &proto_ospf, p) ospf_sh(p); }; CF_CLI(SHOW OSPF NEIGHBORS, optproto opttext, [] [\"\"], [[Show information about OSPF neighbors]]) -{ ospf_sh_neigh(proto_get_named($4, &proto_ospf), $5); }; +{ PROTO_WALK_CMD($4, &proto_ospf, p) ospf_sh_neigh(p, $5); }; CF_CLI(SHOW OSPF INTERFACE, optproto opttext, [] [\"\"], [[Show information about interface]]) -{ ospf_sh_iface(proto_get_named($4, &proto_ospf), $5); }; +{ PROTO_WALK_CMD($4, &proto_ospf, p) ospf_sh_iface(p, $5); }; CF_CLI_HELP(SHOW OSPF TOPOLOGY, [all] [], [[Show information about OSPF network topology]]) diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index c8ed0e06d..ba8c2e2bc 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -800,7 +800,6 @@ ospf_sh_neigh(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1013, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -811,7 +810,6 @@ ospf_sh_neigh(struct proto *P, const char *iff) if ((iff == NULL) || patmatch(iff, ifa->ifname)) WALK_LIST(n, ifa->neigh_list) ospf_sh_neigh_info(n); - cli_msg(0, ""); } void @@ -826,7 +824,6 @@ ospf_sh(struct proto *P) if (p->p.proto_state != PS_UP) { cli_msg(-1014, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -896,7 +893,6 @@ ospf_sh(struct proto *P) FIB_WALK_END; } - cli_msg(0, ""); } void @@ -908,7 +904,6 @@ ospf_sh_iface(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1015, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -916,7 +911,6 @@ ospf_sh_iface(struct proto *P, const char *iff) WALK_LIST(ifa, p->iface_list) if ((iff == NULL) || patmatch(iff, ifa->ifname)) ospf_iface_info(ifa); - cli_msg(0, ""); } /* lsa_compare_for_state() - Compare function for 'show ospf state' diff --git a/proto/rip/config.Y b/proto/rip/config.Y index 6cea7dd0a..55527feb5 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -196,10 +196,10 @@ dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_TAG) CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]); CF_CLI(SHOW RIP INTERFACES, optproto opttext, [] [\"\"], [[Show information about RIP interfaces]]) -{ rip_show_interfaces(proto_get_named($4, &proto_rip), $5); }; +{ PROTO_WALK_CMD($4, &proto_rip, p) rip_show_interfaces(p, $5); }; CF_CLI(SHOW RIP NEIGHBORS, optproto opttext, [] [\"\"], [[Show information about RIP neighbors]]) -{ rip_show_neighbors(proto_get_named($4, &proto_rip), $5); }; +{ PROTO_WALK_CMD($4, &proto_rip, p) rip_show_neighbors(p, $5); }; CF_CODE diff --git a/proto/rip/rip.c b/proto/rip/rip.c index f3dc63535..5c53ab1e0 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1232,7 +1232,6 @@ rip_show_interfaces(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1021, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -1256,8 +1255,6 @@ rip_show_interfaces(struct proto *P, const char *iff) cli_msg(-1021, "%-10s %-6s %6u %6u %7t", ifa->iface->name, (ifa->up ? "Up" : "Down"), ifa->cf->metric, nbrs, timer); } - - cli_msg(0, ""); } void @@ -1270,7 +1267,6 @@ rip_show_neighbors(struct proto *P, const char *iff) if (p->p.proto_state != PS_UP) { cli_msg(-1022, "%s: is not up", p->p.name); - cli_msg(0, ""); return; } @@ -1293,8 +1289,6 @@ rip_show_neighbors(struct proto *P, const char *iff) n->nbr->addr, ifa->iface->name, ifa->cf->metric, n->uc, timer); } } - - cli_msg(0, ""); } static void diff --git a/proto/static/config.Y b/proto/static/config.Y index 6e4108799..41e10dbf6 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -158,7 +158,7 @@ stat_route_opt_list: CF_CLI(SHOW STATIC, optproto, [], [[Show details of static protocol]]) -{ static_show(proto_get_named($3, &proto_static)); } ; +{ PROTO_WALK_CMD($3, &proto_static, p) static_show(p); } ; CF_CODE diff --git a/proto/static/static.c b/proto/static/static.c index c899cc87e..72b14991e 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -647,7 +647,6 @@ static_show(struct proto *P) WALK_LIST(r, c->routes) static_show_rt(r); - cli_msg(0, ""); }