diff --git a/nest/cli.h b/nest/cli.h index 6040be91..8a3294c5 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 85090424..41b3a6b9 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 a934c047..14b6123a 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 ba98598b..618abaa8 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 b6bc70fa..2f3b637b 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 b4c53754..e303d7a0 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 84d12306..df1cba42 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 ce9245a1..fd2cfe8a 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 c8ed0e06..ba8c2e2b 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 6cea7dd0..55527feb 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 f3dc6353..5c53ab1e 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 6e410879..41e10dbf 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 c899cc87..72b14991 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, ""); }