]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Show info from multiple protocols when protocol is not specified
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 14 May 2020 01:48:17 +0000 (03:48 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sun, 28 Jun 2020 13:38:47 +0000 (15:38 +0200)
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.

13 files changed:
nest/cli.h
nest/proto.c
nest/protocol.h
proto/babel/babel.c
proto/babel/config.Y
proto/bfd/bfd.c
proto/bfd/config.Y
proto/ospf/config.Y
proto/ospf/ospf.c
proto/rip/config.Y
proto/rip/rip.c
proto/static/config.Y
proto/static/static.c

index 6040be91cec59c764a0bc1ecdadf3088335d508f..8a3294c52224d5e618219ddd5d77b6f0e7831902 100644 (file)
@@ -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 *);
index 850904245dcb78baa91f0f7e370b436ad374c31d..41b3a6b9ce37e1df2921a9ab6755eeddc12fa287 100644 (file)
@@ -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;
+  }
+}
index a934c04765f75385b380899d6bfdc18639288362..14b6123a8d9fe02f344a5f4b28f306d3bfb1310c 100644 (file)
@@ -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
index ba98598ba8d33eb8791e98ebd047fe4c4c0f5529..618abaa8ab605ef76666f6dcfadb453c203b303e 100644 (file)
@@ -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, "");
 }
 
 
index b6bc70fa89e39d65a2a982ceec82b3105d2e7b51..2f3b637b4f6cc7a21d736ac135a28620edcb8ce7 100644 (file)
@@ -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, [<name>] [\"<interface>\"], [[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, [<name>] [\"<interface>\"], [[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, [<name>], [[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, [<name>], [[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
 
index b4c53754b6c89f8f09866b69bae23038d4ad51a1..e303d7a0d50ebbca1bd1c4a784e601aef5e05136 100644 (file)
@@ -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, "");
 }
 
 
index 84d12306c829c367e2c294daaf6e5a4894dc3e4d..df1cba42cfa7d2129389a80756849573b5b9b443 100644 (file)
@@ -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, [<name>], [[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
 
index ce9245a1fc09a963d7b7e5a6cc04c7695ce375bd..fd2cfe8ae1757eb765fd6474b7c7fbbc27efeec6 100644 (file)
@@ -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, [<name>], [[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, [<name>] [\"<interface>\"], [[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, [<name>] [\"<interface>\"], [[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] [<name>], [[Show information about OSPF network topology]])
 
index c8ed0e06d0e454f4e1ac60fb643e3a600908bfcc..ba8c2e2bc12f53c82670619a589ef075066ee686 100644 (file)
@@ -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'
index 6cea7dd0a62e8943973b399f04a16cf44a3e04d3..55527feb57de1b21008336472dbd20f114775e93 100644 (file)
@@ -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, [<name>] [\"<interface>\"], [[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, [<name>] [\"<interface>\"], [[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
index f3dc63535d6471c184c08d000d07d1580aa991cb..5c53ab1e0cd01b8d241109c98c170a4903e7cf2d 100644 (file)
@@ -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
index 6e4108799443943584f09d6c547f4c7e7723fb57..41e10dbf6ccd4d88e85193e654eb466d29961b30 100644 (file)
@@ -158,7 +158,7 @@ stat_route_opt_list:
 
 
 CF_CLI(SHOW STATIC, optproto, [<name>], [[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
 
index c899cc87e7ba45c1805c778ec25e1d9014550c4c..72b14991eee5936863b35c30321e19c18e328cc6 100644 (file)
@@ -647,7 +647,6 @@ static_show(struct proto *P)
 
   WALK_LIST(r, c->routes)
     static_show_rt(r);
-  cli_msg(0, "");
 }