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/bird.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
|
#include "nest/protocol.h"
|
||||||
#include "filter/filter.h"
|
#include "filter/filter.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "conf/cf-parse.tab.h"
|
#include "conf/cf-parse.tab.h"
|
||||||
|
|
|
@ -42,6 +42,7 @@ CF_DECLS
|
||||||
void *g;
|
void *g;
|
||||||
bird_clock_t time;
|
bird_clock_t time;
|
||||||
struct prefix px;
|
struct prefix px;
|
||||||
|
struct proto_spec ps;
|
||||||
struct timeformat *tf;
|
struct timeformat *tf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT)
|
||||||
%type <s> optsym
|
%type <s> optsym
|
||||||
%type <ra> r_args
|
%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 <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
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -324,11 +324,11 @@ CF_CLI_HELP(SHOW, ..., [[Show status information]])
|
||||||
CF_CLI(SHOW STATUS,,, [[Show router status]])
|
CF_CLI(SHOW STATUS,,, [[Show router status]])
|
||||||
{ cmd_show_status(); } ;
|
{ cmd_show_status(); } ;
|
||||||
|
|
||||||
CF_CLI(SHOW PROTOCOLS, optsym, [<name>], [[Show routing protocols]])
|
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
|
||||||
{ proto_show($3, 0); } ;
|
{ proto_apply_cmd($3, proto_cmd_show, 0); } ;
|
||||||
|
|
||||||
CF_CLI(SHOW PROTOCOLS ALL, optsym, [<name>], [[Show routing protocol details]])
|
CF_CLI(SHOW PROTOCOLS ALL, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocol details]])
|
||||||
{ proto_show($4, 1); } ;
|
{ proto_apply_cmd($4, proto_cmd_show, 1); } ;
|
||||||
|
|
||||||
optsym:
|
optsym:
|
||||||
SYM
|
SYM
|
||||||
|
@ -459,34 +459,39 @@ echo_size:
|
||||||
;
|
;
|
||||||
|
|
||||||
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
|
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]])
|
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]])
|
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]])
|
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)]])
|
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)]])
|
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_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]])
|
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_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]])
|
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:
|
proto_patt:
|
||||||
SYM { $$ = $1->name; }
|
SYM { $$.ptr = $1; $$.patt = 0; }
|
||||||
| ALL { $$ = "*"; }
|
| ALL { $$.ptr = NULL; $$.patt = 1; }
|
||||||
| TEXT
|
| TEXT { $$.ptr = $1; $$.patt = 1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
proto_patt2:
|
||||||
|
SYM { $$.ptr = $1; $$.patt = 0; }
|
||||||
|
| { $$.ptr = NULL; $$.patt = 1; }
|
||||||
|
| TEXT { $$.ptr = $1; $$.patt = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
CF_CODE
|
CF_CODE
|
||||||
|
|
||||||
CF_END
|
CF_END
|
||||||
|
|
256
nest/proto.c
256
nest/proto.c
|
@ -25,12 +25,6 @@ static pool *proto_pool;
|
||||||
static list protocol_list;
|
static list protocol_list;
|
||||||
static list proto_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)
|
#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;
|
list active_proto_list;
|
||||||
|
@ -847,11 +841,15 @@ proto_do_show_pipe_stats(struct proto *p)
|
||||||
s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
|
s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
proto_do_show(struct proto *p, int verbose)
|
proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
|
||||||
{
|
{
|
||||||
byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
|
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;
|
buf[0] = 0;
|
||||||
if (p->proto->get_status)
|
if (p->proto->get_status)
|
||||||
p->proto->get_status(p, buf);
|
p->proto->get_status(p, buf);
|
||||||
|
@ -886,25 +884,136 @@ proto_do_show(struct proto *p, int verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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);
|
cli_msg(9002, "%s is not a protocol", s->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cli_msg(-2002, "name proto table state since info");
|
|
||||||
if (s)
|
cmd(((struct proto_config *)s->def)->proto, arg, 0);
|
||||||
proto_do_show(((struct proto_config *)s->def)->proto, verbose);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WALK_PROTO_LIST(p)
|
|
||||||
proto_do_show(p, verbose);
|
|
||||||
WALK_PROTO_LIST_END;
|
|
||||||
}
|
|
||||||
cli_msg(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 *
|
struct proto *
|
||||||
proto_get_named(struct symbol *sym, struct protocol *pr)
|
proto_get_named(struct symbol *sym, struct protocol *pr)
|
||||||
{
|
{
|
||||||
|
@ -933,112 +1042,3 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
|
||||||
}
|
}
|
||||||
return p;
|
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 */
|
/* Hic sunt protocol-specific data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct proto_spec {
|
||||||
|
void *ptr;
|
||||||
|
int patt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
void *proto_new(struct proto_config *, unsigned size);
|
void *proto_new(struct proto_config *, unsigned size);
|
||||||
void *proto_config_new(struct protocol *, unsigned size);
|
void *proto_config_new(struct protocol *, unsigned size);
|
||||||
|
|
||||||
void proto_request_feeding(struct proto *p);
|
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
|
void proto_cmd_show(struct proto *, unsigned int, int);
|
||||||
#define XX_ENABLE 1
|
void proto_cmd_disable(struct proto *, unsigned int, int);
|
||||||
#define XX_RESTART 2
|
void proto_cmd_enable(struct proto *, unsigned int, int);
|
||||||
#define XX_RELOAD 3
|
void proto_cmd_restart(struct proto *, unsigned int, int);
|
||||||
#define XX_RELOAD_IN 4
|
void proto_cmd_reload(struct proto *, unsigned int, int);
|
||||||
#define XX_RELOAD_OUT 5
|
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
|
static inline u32
|
||||||
proto_get_router_id(struct proto_config *pc)
|
proto_get_router_id(struct proto_config *pc)
|
||||||
|
|
Loading…
Reference in a new issue