From e304fd4bcf5813b581a39078a25a5cf6916b9f29 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 20 Feb 2010 00:03:31 +0100 Subject: [PATCH] Implements pattern match for 'show protocols' command. And generally consolidates protocol commands. --- conf/cf-lex.l | 1 + conf/confbase.Y | 1 + nest/config.Y | 41 ++++---- nest/proto.c | 256 ++++++++++++++++++++++++------------------------ nest/protocol.h | 31 +++--- 5 files changed, 173 insertions(+), 157 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 optsym %type r_args %type echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport -%type proto_patt +%type 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, [], [[Show routing protocols]]) -{ proto_show($3, 0); } ; +CF_CLI(SHOW PROTOCOLS, proto_patt2, [ | \"\"], [[Show routing protocols]]) +{ proto_apply_cmd($3, proto_cmd_show, 0); } ; -CF_CLI(SHOW PROTOCOLS ALL, optsym, [], [[Show routing protocol details]]) -{ proto_show($4, 1); } ; +CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [ | \"\"], [[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, | \"\" | all, [[Disable protocol]]) -{ proto_xxable($2, XX_DISABLE); } ; +{ proto_apply_cmd($2, proto_cmd_disable, 0); } ; CF_CLI(ENABLE, proto_patt, | \"\" | all, [[Enable protocol]]) -{ proto_xxable($2, XX_ENABLE); } ; +{ proto_apply_cmd($2, proto_cmd_enable, 0); } ; CF_CLI(RESTART, proto_patt, | \"\" | all, [[Restart protocol]]) -{ proto_xxable($2, XX_RESTART); } ; +{ proto_apply_cmd($2, proto_cmd_restart, 0); } ; CF_CLI(RELOAD, proto_patt, | \"\" | all, [[Reload protocol]]) -{ proto_xxable($2, XX_RELOAD); } ; +{ proto_apply_cmd($2, proto_cmd_reload, CMD_RELOAD); } ; CF_CLI(RELOAD IN, proto_patt, | \"\" | 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, | \"\" | 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, ( | | 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, ( | | 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(-8, "%s: already disabled", p->name); + return; + } + + 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) { cli_msg(9002, "%s is not a protocol", s->name); return; } - cli_msg(-2002, "name proto table state since info"); - if (s) - proto_do_show(((struct proto_config *)s->def)->proto, verbose); - else - { - WALK_PROTO_LIST(p) - proto_do_show(p, verbose); - WALK_PROTO_LIST_END; - } + + 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); -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 +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 *); + +#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)