Implements pattern match for 'show protocols' command.
And generally consolidates protocol commands.
This commit is contained in:
parent
dfd48621d1
commit
e304fd4bcf
5 changed files with 173 additions and 157 deletions
|
@ -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"
|
||||
|
|
|
@ -42,6 +42,7 @@ CF_DECLS
|
|||
void *g;
|
||||
bird_clock_t time;
|
||||
struct prefix px;
|
||||
struct proto_spec ps;
|
||||
struct timeformat *tf;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
256
nest/proto.c
256
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, "");
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue