summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-02-20 00:03:31 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2010-02-20 00:08:07 +0100
commite304fd4bcf5813b581a39078a25a5cf6916b9f29 (patch)
treed32f60be5488cc53543bcdece93cdedbd0ad8a8a
parentdfd48621d1a54f2beb461fe3847fc4b2a535675e (diff)
Implements pattern match for 'show protocols' command.
And generally consolidates protocol commands.
-rw-r--r--conf/cf-lex.l1
-rw-r--r--conf/confbase.Y1
-rw-r--r--nest/config.Y41
-rw-r--r--nest/proto.c254
-rw-r--r--nest/protocol.h31
5 files changed, 172 insertions, 156 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 04b0c604..3fe3c2e6 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -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"
diff --git a/conf/confbase.Y b/conf/confbase.Y
index b65d6087..2d95a0d3 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -42,6 +42,7 @@ CF_DECLS
void *g;
bird_clock_t time;
struct prefix px;
+ struct proto_spec ps;
struct timeformat *tf;
}
diff --git a/nest/config.Y b/nest/config.Y
index 11f0a9b2..8dc8c713 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -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
diff --git a/nest/proto.c b/nest/proto.c
index 57c2aa13..7c4d32d0 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -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, "");
-}
diff --git a/nest/protocol.h b/nest/protocol.h
index 82f3766f..d652c4fb 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -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)