]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements pattern match for 'show protocols' command.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 19 Feb 2010 23:03:31 +0000 (00:03 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 19 Feb 2010 23:08:07 +0000 (00:08 +0100)
And generally consolidates protocol commands.

conf/cf-lex.l
conf/confbase.Y
nest/config.Y
nest/proto.c
nest/protocol.h

index 04b0c6040c1cbf2a653066e3de6b910a4e0e4656..3fe3c2e61f865316a732a6cb70c062a374c6e086 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "nest/bird.h"
 #include "nest/route.h"
+#include "nest/protocol.h"
 #include "filter/filter.h"
 #include "conf/conf.h"
 #include "conf/cf-parse.tab.h"
index b65d608768db1db91dd9fd2f4dc5fa6c8b7cc823..2d95a0d3f0a45e9530701e2e8e37e40d7e4b26a4 100644 (file)
@@ -42,6 +42,7 @@ CF_DECLS
   void *g;
   bird_clock_t time;
   struct prefix px;
+  struct proto_spec ps;
   struct timeformat *tf;
 }
 
index 11f0a9b21c03ab60fb9c06826252aab53ccb65f4..8dc8c713c90eddcf50af77e7e4a46e4bc644d6ef 100644 (file)
@@ -59,7 +59,7 @@ CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT)
 %type <s> optsym
 %type <ra> r_args
 %type <i> echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport
-%type <t> proto_patt
+%type <ps> proto_patt proto_patt2
 
 CF_GRAMMAR
 
@@ -324,11 +324,11 @@ CF_CLI_HELP(SHOW, ..., [[Show status information]])
 CF_CLI(SHOW STATUS,,, [[Show router status]])
 { cmd_show_status(); } ;
 
-CF_CLI(SHOW PROTOCOLS, optsym, [<name>], [[Show routing protocols]])
-{ proto_show($3, 0); } ;
+CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
+{ proto_apply_cmd($3, proto_cmd_show, 0); } ;
 
-CF_CLI(SHOW PROTOCOLS ALL, optsym, [<name>], [[Show routing protocol details]])
-{ proto_show($4, 1); } ;
+CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
+{ proto_apply_cmd($4, proto_cmd_show, 1); } ;
 
 optsym:
    SYM
@@ -459,34 +459,39 @@ echo_size:
  ;
 
 CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
-{ proto_xxable($2, XX_DISABLE); } ;
+{ proto_apply_cmd($2, proto_cmd_disable, 0); } ;
 CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
-{ proto_xxable($2, XX_ENABLE); } ;
+{ proto_apply_cmd($2, proto_cmd_enable, 0); } ;
 CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
-{ proto_xxable($2, XX_RESTART); } ;
+{ proto_apply_cmd($2, proto_cmd_restart, 0); } ;
 CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
-{ proto_xxable($2, XX_RELOAD); } ;
+{ proto_apply_cmd($2, proto_cmd_reload, CMD_RELOAD); } ;
 CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
-{ proto_xxable($3, XX_RELOAD_IN); } ;
+{ proto_apply_cmd($3, proto_cmd_reload, CMD_RELOAD_IN); } ;
 CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
-{ proto_xxable($3, XX_RELOAD_OUT); } ;
+{ proto_apply_cmd($3, proto_cmd_reload, CMD_RELOAD_OUT); } ;
 
 CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
 CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging via BIRD logs]])
-{ proto_debug($2, 0, $3); }
- ;
+{ proto_apply_cmd($2, proto_cmd_debug, $3); } ;
 
 CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
 CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
-{ proto_debug($2, 1, $3); }
- ;
+{ proto_apply_cmd($2, proto_cmd_mrtdump, $3); } ;
 
 proto_patt:
-   SYM { $$ = $1->name; }
- | ALL { $$ = "*"; }
- | TEXT
+   SYM  { $$.ptr = $1; $$.patt = 0; }
+ | ALL  { $$.ptr = NULL; $$.patt = 1; }
+ | TEXT { $$.ptr = $1; $$.patt = 1; }
  ;
 
+proto_patt2:
+   SYM  { $$.ptr = $1; $$.patt = 0; }
+ |      { $$.ptr = NULL; $$.patt = 1; }
+ | TEXT { $$.ptr = $1; $$.patt = 1; }
+ ;
+
+
 CF_CODE
 
 CF_END
index 57c2aa13e33d87d4a6f51179bdcf7defadf58595..7c4d32d06c9f8ed69873c8f20fa43ff1f9e776a2 100644 (file)
@@ -25,12 +25,6 @@ static pool *proto_pool;
 static list protocol_list;
 static list proto_list;
 
-#define WALK_PROTO_LIST(p) do {                                                        \
-       node *nn;                                                               \
-       WALK_LIST(nn, proto_list) {                                             \
-               struct proto *p = SKIP_BACK(struct proto, glob_node, nn);
-#define WALK_PROTO_LIST_END } } while(0)
-
 #define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0)
 
 list active_proto_list;
@@ -847,11 +841,15 @@ proto_do_show_pipe_stats(struct proto *p)
          s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
 }
 
-static void
-proto_do_show(struct proto *p, int verbose)
+void
+proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
 {
   byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
 
+  /* First protocol - show header */
+  if (!cnt)
+    cli_msg(-2002, "name     proto    table    state  since       info");
+
   buf[0] = 0;
   if (p->proto->get_status)
     p->proto->get_status(p, buf);
@@ -886,25 +884,136 @@ proto_do_show(struct proto *p, int verbose)
 }
 
 void
-proto_show(struct symbol *s, int verbose)
+proto_cmd_disable(struct proto *p, unsigned int arg UNUSED, int cnt UNUSED)
 {
-  if (s && s->class != SYM_PROTO)
+  if (p->disabled)
     {
-      cli_msg(9002, "%s is not a protocol", s->name);
+      cli_msg(-8, "%s: already disabled", p->name);
       return;
     }
-  cli_msg(-2002, "name     proto    table    state  since       info");
-  if (s)
-    proto_do_show(((struct proto_config *)s->def)->proto, verbose);
-  else
+
+  log(L_INFO "Disabling protocol %s", p->name);
+  p->disabled = 1;
+  proto_rethink_goal(p);
+  cli_msg(-9, "%s: disabled", p->name);
+}
+
+void
+proto_cmd_enable(struct proto *p, unsigned int arg UNUSED, int cnt UNUSED)
+{
+  if (!p->disabled)
+    {
+      cli_msg(-10, "%s: already enabled", p->name);
+      return;
+    }
+
+  log(L_INFO "Enabling protocol %s", p->name);
+  p->disabled = 0;
+  proto_rethink_goal(p);
+  cli_msg(-11, "%s: enabled", p->name);
+}
+
+void
+proto_cmd_restart(struct proto *p, unsigned int arg UNUSED, int cnt UNUSED)
+{
+  if (p->disabled)
+    {
+      cli_msg(-8, "%s: already disabled", p->name);
+      return;
+    }
+
+  log(L_INFO "Restarting protocol %s", p->name);
+  p->disabled = 1;
+  proto_rethink_goal(p);
+  p->disabled = 0;
+  proto_rethink_goal(p);
+  cli_msg(-12, "%s: restarted", p->name);
+}
+
+void
+proto_cmd_reload(struct proto *p, unsigned int dir, int cnt UNUSED)
+{
+  if (p->disabled)
+    {
+      cli_msg(-8, "%s: already disabled", p->name);
+      return;
+    }
+
+  /* If the protocol in not UP, it has no routes */
+  if (p->proto_state != PS_UP)
+    return;
+
+  log(L_INFO "Reloading protocol %s", p->name);
+
+  /* re-importing routes */
+  if (dir != CMD_RELOAD_OUT)
+    if (! (p->reload_routes && p->reload_routes(p)))
+      {
+       cli_msg(-8006, "%s: reload failed", p->name);
+       return;
+      }
+                
+  /* re-exporting routes */
+  if (dir != CMD_RELOAD_IN)
+    proto_request_feeding(p);
+
+  cli_msg(-15, "%s: reloading", p->name);
+}
+
+void
+proto_cmd_debug(struct proto *p, unsigned int mask, int cnt UNUSED)
+{
+  p->debug = mask;
+}
+
+void
+proto_cmd_mrtdump(struct proto *p, unsigned int mask, int cnt UNUSED)
+{
+  p->mrtdump = mask;
+}
+
+static void
+proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, unsigned int, int), unsigned int arg)
+{
+  if (s->class != SYM_PROTO)
     {
-      WALK_PROTO_LIST(p)
-       proto_do_show(p, verbose);
-      WALK_PROTO_LIST_END;
+      cli_msg(9002, "%s is not a protocol", s->name);
+      return;
     }
+
+  cmd(((struct proto_config *)s->def)->proto, arg, 0);
   cli_msg(0, "");
 }
 
+static void
+proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, unsigned int, int), unsigned int arg)
+{
+  int cnt = 0;
+
+  node *nn;
+  WALK_LIST(nn, proto_list)
+    {
+      struct proto *p = SKIP_BACK(struct proto, glob_node, nn);
+
+      if (!patt || patmatch(patt, p->name))
+       cmd(p, arg, cnt++);
+    }
+
+  if (!cnt)
+    cli_msg(8003, "No protocols match");
+  else
+    cli_msg(0, "");
+}
+
+void
+proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int), unsigned int arg)
+{
+  if (ps.patt)
+    proto_apply_cmd_patt(ps.ptr, cmd, arg);
+  else
+    proto_apply_cmd_symbol(ps.ptr, cmd, arg);
+}
+
 struct proto *
 proto_get_named(struct symbol *sym, struct protocol *pr)
 {
@@ -933,112 +1042,3 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
     }
   return p;
 }
-
-void
-proto_xxable(char *pattern, int xx)
-{
-  int cnt = 0;
-  WALK_PROTO_LIST(p)
-    if (patmatch(pattern, p->name))
-      {
-       cnt++;
-       switch (xx)
-         {
-         case XX_DISABLE:
-           if (p->disabled)
-             cli_msg(-8, "%s: already disabled", p->name);
-           else
-             {
-               log(L_INFO "Disabling protocol %s", p->name);
-               p->disabled = 1;
-               proto_rethink_goal(p);
-               cli_msg(-9, "%s: disabled", p->name);
-             }
-           break;
-
-         case XX_ENABLE:
-           if (!p->disabled)
-             cli_msg(-10, "%s: already enabled", p->name);
-           else
-             {
-               log(L_INFO "Enabling protocol %s", p->name);
-               p->disabled = 0;
-               proto_rethink_goal(p);
-               cli_msg(-11, "%s: enabled", p->name);
-             }
-           break;
-
-         case XX_RESTART:
-           if (p->disabled)
-             cli_msg(-8, "%s: already disabled", p->name);
-           else
-             {
-               log(L_INFO "Restarting protocol %s", p->name);
-               p->disabled = 1;
-               proto_rethink_goal(p);
-               p->disabled = 0;
-               proto_rethink_goal(p);
-               cli_msg(-12, "%s: restarted", p->name);
-             }
-           break;
-
-         case XX_RELOAD:
-         case XX_RELOAD_IN:
-         case XX_RELOAD_OUT:
-           if (p->disabled)
-             {
-               cli_msg(-8, "%s: already disabled", p->name);
-               break;
-             }
-
-           /* If the protocol in not UP, it has no routes */
-           if (p->proto_state != PS_UP)
-             break;
-
-           log(L_INFO "Reloading protocol %s", p->name);
-
-           /* re-importing routes */
-           if (xx != XX_RELOAD_OUT)
-             if (! (p->reload_routes && p->reload_routes(p)))
-               {
-                 cli_msg(-8006, "%s: reload failed", p->name);
-                 break;
-               }
-                
-           /* re-exporting routes */
-           if (xx != XX_RELOAD_IN)
-             proto_request_feeding(p);
-
-           cli_msg(-15, "%s: reloading", p->name);
-           break;
-
-         default:
-           ASSERT(0);
-         }
-      }
-  WALK_PROTO_LIST_END;
-  if (!cnt)
-    cli_msg(8003, "No protocols match");
-  else
-    cli_msg(0, "");
-}
-
-void
-proto_debug(char *pattern, int which, unsigned int mask)
-{
-  int cnt = 0;
-  WALK_PROTO_LIST(p)
-    if (patmatch(pattern, p->name))
-      {
-       cnt++;
-       if (which == 0)
-         p->debug = mask;
-       else
-         p->mrtdump = mask;
-      }
-  WALK_PROTO_LIST_END;
-  if (!cnt)
-    cli_msg(8003, "No protocols match");
-  else
-    cli_msg(0, "");
-}
index 82f3766f1a5d5767f6df6eac9be78926cb5a1a57..d652c4fb8bc5f3ea7edc70989358e96603f9f718 100644 (file)
@@ -195,21 +195,30 @@ struct proto {
   /* Hic sunt protocol-specific data */
 };
 
+struct proto_spec {
+  void *ptr;
+  int patt;
+};
+
+
 void *proto_new(struct proto_config *, unsigned size);
 void *proto_config_new(struct protocol *, unsigned size);
-
 void proto_request_feeding(struct proto *p);
-void proto_show(struct symbol *, int);
+
+void proto_cmd_show(struct proto *, unsigned int, int);
+void proto_cmd_disable(struct proto *, unsigned int, int);
+void proto_cmd_enable(struct proto *, unsigned int, int);
+void proto_cmd_restart(struct proto *, unsigned int, int);
+void proto_cmd_reload(struct proto *, unsigned int, int);
+void proto_cmd_debug(struct proto *, unsigned int, int);
+void proto_cmd_mrtdump(struct proto *, unsigned int, int);
+
+void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, unsigned int, int), unsigned int arg);
 struct proto *proto_get_named(struct symbol *, struct protocol *);
-void proto_xxable(char *, int);
-void proto_debug(char *, int, unsigned int);
-
-#define XX_DISABLE     0
-#define XX_ENABLE      1
-#define XX_RESTART     2
-#define XX_RELOAD      3
-#define XX_RELOAD_IN   4
-#define XX_RELOAD_OUT  5
+
+#define CMD_RELOAD     0
+#define CMD_RELOAD_IN  1
+#define CMD_RELOAD_OUT 2
 
 static inline u32
 proto_get_router_id(struct proto_config *pc)