Reworked proto lists -- each proto is now in two lists: the global one

(proto_list) and per-type one (original lists). A lot of things simplified.

Implemented `disable', `enable' and `restart' CLI commands.
This commit is contained in:
Martin Mares 2000-01-16 23:30:06 +00:00
parent 30a6108ccc
commit f14a4becbe
6 changed files with 101 additions and 25 deletions

4
TODO
View file

@ -28,6 +28,7 @@ Core
- config: useless rules when protocols disabled - config: useless rules when protocols disabled
- config: remove protocol startup priority hacks? - config: remove protocol startup priority hacks?
- config: better datetime format - config: better datetime format
- config: avoid upper case in default protocol names
- krt: rescan interfaces when route addition fails? - krt: rescan interfaces when route addition fails?
- krt: does PERSIST mode have any sense if kernel syncer is shut down as last? - krt: does PERSIST mode have any sense if kernel syncer is shut down as last?
@ -39,14 +40,11 @@ Core
Commands Commands
~~~~~~~~ ~~~~~~~~
shutdown # order system shutdown
configure [<file>]
show <name> # show everything you know about symbol <name> show <name> # show everything you know about symbol <name>
rip ??? [<name>] rip ??? [<name>]
ospf ??? [<name>] ospf ??? [<name>]
static ??? [<name>] static ??? [<name>]
symbols symbols
(disable|enable|restart) <protocol> # or ALL?
- showing of routing table as seen by given protocol - showing of routing table as seen by given protocol
- showing of deleted routing tables and filters - showing of deleted routing tables and filters

View file

@ -16,6 +16,11 @@ Reply codes of BIRD command-line interface
0005 Reconfiguration already in progress, queueing 0005 Reconfiguration already in progress, queueing
0006 Reconfiguration ignored, shutting down 0006 Reconfiguration ignored, shutting down
0007 Shutdown ordered 0007 Shutdown ordered
0008 Already disabled
0009 Disabled
0010 Already enabled
0011 Enabled
0012 Restarted
1000 BIRD version 1000 BIRD version
1001 Interface list 1001 Interface list
@ -31,6 +36,7 @@ Reply codes of BIRD command-line interface
8000 Reply too long 8000 Reply too long
8001 Route not found 8001 Route not found
8002 Configuration file error 8002 Configuration file error
8003 No protocols match
9000 Command too long 9000 Command too long
9001 Parse error 9001 Parse error

View file

@ -30,6 +30,7 @@ CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIREC
%type <s> optsym %type <s> optsym
%type <ra> r_args %type <ra> r_args
%type <i> echo_mask echo_size %type <i> echo_mask echo_size
%type <t> proto_patt
CF_GRAMMAR CF_GRAMMAR
@ -287,6 +288,19 @@ echo_size:
} }
; ;
CF_CLI(DISABLE, proto_patt, <protocol> | <pattern> | all, [[Disable protocol]])
{ proto_xxable($2, 0); } ;
CF_CLI(ENABLE, proto_patt, <protocol> | <pattern> | all, [[Enable protocol]])
{ proto_xxable($2, 1); } ;
CF_CLI(RESTART, proto_patt, <protocol> | <pattern> | all, [[Restart protocol]])
{ proto_xxable($2, 2); } ;
proto_patt:
SYM { $$ = $1->name; }
| ALL { $$ = "*"; }
| TEXT
;
CF_CODE CF_CODE
CF_END CF_END

View file

@ -278,7 +278,7 @@ ifa_notify_change(unsigned c, struct ifa *a)
struct proto *p; struct proto *p;
debug("IFA change notification (%x) for %s:%I\n", c, a->iface->name, a->ip); debug("IFA change notification (%x) for %s:%I\n", c, a->iface->name, a->ip);
WALK_LIST(p, proto_list) WALK_LIST(p, active_proto_list)
if (p->ifa_notify) if (p->ifa_notify)
p->ifa_notify(p, c, a); p->ifa_notify(p, c, a);
} }
@ -307,7 +307,7 @@ if_notify_change(unsigned c, struct iface *i)
ifa_notify_change(IF_CHANGE_DOWN, a); ifa_notify_change(IF_CHANGE_DOWN, a);
} }
WALK_LIST(p, proto_list) WALK_LIST(p, active_proto_list)
if (p->if_notify) if (p->if_notify)
p->if_notify(p, c, i); p->if_notify(p, c, i);

View file

@ -15,6 +15,7 @@
#include "lib/resource.h" #include "lib/resource.h"
#include "lib/lists.h" #include "lib/lists.h"
#include "lib/event.h" #include "lib/event.h"
#include "lib/string.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "nest/route.h" #include "nest/route.h"
#include "nest/iface.h" #include "nest/iface.h"
@ -24,8 +25,15 @@
static pool *proto_pool; static pool *proto_pool;
list protocol_list; list protocol_list;
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)
list active_proto_list;
static list inactive_proto_list; static list inactive_proto_list;
static list initial_proto_list; static list initial_proto_list;
static list flush_proto_list; static list flush_proto_list;
@ -64,7 +72,7 @@ proto_relink(struct proto *p)
switch (p->core_state) switch (p->core_state)
{ {
case FS_HAPPY: case FS_HAPPY:
l = &proto_list; l = &active_proto_list;
break; break;
case FS_FLUSHING: case FS_FLUSHING:
l = &flush_proto_list; l = &flush_proto_list;
@ -153,6 +161,7 @@ protos_preconfig(struct config *c)
struct protocol *p; struct protocol *p;
init_list(&proto_list); init_list(&proto_list);
init_list(&active_proto_list);
init_list(&inactive_proto_list); init_list(&inactive_proto_list);
init_list(&initial_proto_list); init_list(&initial_proto_list);
init_list(&flush_proto_list); init_list(&flush_proto_list);
@ -194,6 +203,7 @@ proto_init(struct proto_config *c)
q->proto_state = PS_DOWN; q->proto_state = PS_DOWN;
q->core_state = FS_HUNGRY; q->core_state = FS_HUNGRY;
proto_enqueue(&initial_proto_list, q); proto_enqueue(&initial_proto_list, q);
add_tail(&proto_list, &q->glob_node);
/* /*
* HACK ALERT! In case of multiple kernel routing tables, * HACK ALERT! In case of multiple kernel routing tables,
* the kernel syncer acts as multiple protocols which cooperate * the kernel syncer acts as multiple protocols which cooperate
@ -282,6 +292,7 @@ proto_rethink_goal(struct proto *p)
DBG("%s has shut down for reconfiguration\n", p->name); DBG("%s has shut down for reconfiguration\n", p->name);
config_del_obstacle(p->cf->global); config_del_obstacle(p->cf->global);
rem_node(&p->n); rem_node(&p->n);
rem_node(&p->glob_node);
mb_free(p); mb_free(p);
if (!nc) if (!nc)
return; return;
@ -303,7 +314,7 @@ proto_rethink_goal(struct proto *p)
if (p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN) if (p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN)
{ {
DBG("Kicking %s up\n", p->name); DBG("Kicking %s up\n", p->name);
ASSERT(q->startup_counter > 0); if (q->startup_counter > 0) /* FIXME: Kill the startup counter hack! */
q->startup_counter--; q->startup_counter--;
proto_init_instance(p); proto_init_instance(p);
proto_notify_state(p, (q->start ? q->start(p) : PS_UP)); proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
@ -326,7 +337,7 @@ protos_dump_all(void)
debug("Protocols:\n"); debug("Protocols:\n");
WALK_LIST(p, proto_list) WALK_LIST(p, active_proto_list)
{ {
debug(" protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority, debug(" protocol %s (pri=%d): state %s/%s\n", p->name, p->proto->priority,
p_states[p->proto_state], c_states[p->core_state]); p_states[p->proto_state], c_states[p->core_state]);
@ -343,6 +354,8 @@ protos_dump_all(void)
debug(" inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]); debug(" inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]);
WALK_LIST(p, initial_proto_list) WALK_LIST(p, initial_proto_list)
debug(" initial %s\n", p->name); debug(" initial %s\n", p->name);
WALK_LIST(p, flush_proto_list)
debug(" flushing %s\n", p->name);
} }
void void
@ -514,15 +527,6 @@ proto_do_show(struct proto *p, int verbose)
} }
} }
static void
proto_do_show_list(list *l, int verbose)
{
struct proto *p;
WALK_LIST(p, *l)
proto_do_show(p, verbose);
}
void void
proto_show(struct symbol *s, int verbose) proto_show(struct symbol *s, int verbose)
{ {
@ -536,9 +540,9 @@ proto_show(struct symbol *s, int verbose)
proto_do_show(((struct proto_config *)s->def)->proto, verbose); proto_do_show(((struct proto_config *)s->def)->proto, verbose);
else else
{ {
proto_do_show_list(&proto_list, verbose); WALK_PROTO_LIST(p)
proto_do_show_list(&flush_proto_list, verbose); proto_do_show(p, verbose);
proto_do_show_list(&inactive_proto_list, verbose); WALK_PROTO_LIST_END;
} }
cli_msg(0, ""); cli_msg(0, "");
} }
@ -559,7 +563,7 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
else else
{ {
p = NULL; p = NULL;
WALK_LIST(q, proto_list) WALK_LIST(q, active_proto_list)
if (q->proto == pr) if (q->proto == pr)
{ {
if (p) if (p)
@ -571,3 +575,54 @@ 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 0:
if (p->disabled)
cli_msg(-8, "%s: already disabled", p->name);
else
{
cli_msg(-9, "%s: disabled", p->name);
p->disabled = 1;
}
break;
case 1:
if (!p->disabled)
cli_msg(-10, "%s: already enabled", p->name);
else
{
cli_msg(-11, "%s: enabled", p->name);
p->disabled = 0;
}
break;
case 2:
if (p->disabled)
cli_msg(-8, "%s: already disabled", p->name);
else
{
p->disabled = 1;
proto_rethink_goal(p);
p->disabled = 0;
cli_msg(-12, "%s: restarted", p->name);
}
break;
default:
ASSERT(0);
}
proto_rethink_goal(p);
}
WALK_PROTO_LIST_END;
if (!cnt)
cli_msg(8003, "No protocols match");
else
cli_msg(0, "");
}

View file

@ -87,7 +87,8 @@ struct proto_config {
}; };
struct proto { struct proto {
node n; node n; /* Node in *_proto_list */
node glob_node; /* Node in global proto_list */
struct protocol *proto; /* Protocol */ struct protocol *proto; /* Protocol */
struct proto_config *cf; /* Configuration data */ struct proto_config *cf; /* Configuration data */
struct proto_config *cf_new; /* Configuration we want to switch to after shutdown (NULL=delete) */ struct proto_config *cf_new; /* Configuration we want to switch to after shutdown (NULL=delete) */
@ -151,10 +152,12 @@ struct proto {
void proto_build(struct proto_config *); void proto_build(struct proto_config *);
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_show(struct symbol *, int); void proto_show(struct symbol *, int);
struct proto *proto_get_named(struct symbol *, struct protocol *); struct proto *proto_get_named(struct symbol *, struct protocol *);
void proto_xxable(char *, int);
extern list proto_list; extern list active_proto_list;
/* /*
* Each protocol instance runs two different state machines: * Each protocol instance runs two different state machines: