Commit f14a4bec authored by Martin Mareš's avatar Martin Mareš

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.
parent 30a6108c
......@@ -28,6 +28,7 @@ Core
- config: useless rules when protocols disabled
- config: remove protocol startup priority hacks?
- config: better datetime format
- config: avoid upper case in default protocol names
- krt: rescan interfaces when route addition fails?
- krt: does PERSIST mode have any sense if kernel syncer is shut down as last?
......@@ -39,14 +40,11 @@ Core
Commands
~~~~~~~~
shutdown # order system shutdown
configure [<file>]
show <name> # show everything you know about symbol <name>
rip ??? [<name>]
ospf ??? [<name>]
static ??? [<name>]
symbols
(disable|enable|restart) <protocol> # or ALL?
- showing of routing table as seen by given protocol
- showing of deleted routing tables and filters
......
......@@ -16,6 +16,11 @@ Reply codes of BIRD command-line interface
0005 Reconfiguration already in progress, queueing
0006 Reconfiguration ignored, shutting down
0007 Shutdown ordered
0008 Already disabled
0009 Disabled
0010 Already enabled
0011 Enabled
0012 Restarted
1000 BIRD version
1001 Interface list
......@@ -31,6 +36,7 @@ Reply codes of BIRD command-line interface
8000 Reply too long
8001 Route not found
8002 Configuration file error
8003 No protocols match
9000 Command too long
9001 Parse error
......
......@@ -30,6 +30,7 @@ CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIREC
%type <s> optsym
%type <ra> r_args
%type <i> echo_mask echo_size
%type <t> proto_patt
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_END
......@@ -278,7 +278,7 @@ ifa_notify_change(unsigned c, struct ifa *a)
struct proto *p;
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)
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);
}
WALK_LIST(p, proto_list)
WALK_LIST(p, active_proto_list)
if (p->if_notify)
p->if_notify(p, c, i);
......
......@@ -15,6 +15,7 @@
#include "lib/resource.h"
#include "lib/lists.h"
#include "lib/event.h"
#include "lib/string.h"
#include "conf/conf.h"
#include "nest/route.h"
#include "nest/iface.h"
......@@ -24,8 +25,15 @@
static pool *proto_pool;
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 initial_proto_list;
static list flush_proto_list;
......@@ -64,7 +72,7 @@ proto_relink(struct proto *p)
switch (p->core_state)
{
case FS_HAPPY:
l = &proto_list;
l = &active_proto_list;
break;
case FS_FLUSHING:
l = &flush_proto_list;
......@@ -153,6 +161,7 @@ protos_preconfig(struct config *c)
struct protocol *p;
init_list(&proto_list);
init_list(&active_proto_list);
init_list(&inactive_proto_list);
init_list(&initial_proto_list);
init_list(&flush_proto_list);
......@@ -194,6 +203,7 @@ proto_init(struct proto_config *c)
q->proto_state = PS_DOWN;
q->core_state = FS_HUNGRY;
proto_enqueue(&initial_proto_list, q);
add_tail(&proto_list, &q->glob_node);
/*
* HACK ALERT! In case of multiple kernel routing tables,
* 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);
config_del_obstacle(p->cf->global);
rem_node(&p->n);
rem_node(&p->glob_node);
mb_free(p);
if (!nc)
return;
......@@ -303,8 +314,8 @@ proto_rethink_goal(struct proto *p)
if (p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN)
{
DBG("Kicking %s up\n", p->name);
ASSERT(q->startup_counter > 0);
q->startup_counter--;
if (q->startup_counter > 0) /* FIXME: Kill the startup counter hack! */
q->startup_counter--;
proto_init_instance(p);
proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
}
......@@ -326,7 +337,7 @@ protos_dump_all(void)
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,
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]);
WALK_LIST(p, initial_proto_list)
debug(" initial %s\n", p->name);
WALK_LIST(p, flush_proto_list)
debug(" flushing %s\n", p->name);
}
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
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);
else
{
proto_do_show_list(&proto_list, verbose);
proto_do_show_list(&flush_proto_list, verbose);
proto_do_show_list(&inactive_proto_list, verbose);
WALK_PROTO_LIST(p)
proto_do_show(p, verbose);
WALK_PROTO_LIST_END;
}
cli_msg(0, "");
}
......@@ -559,7 +563,7 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
else
{
p = NULL;
WALK_LIST(q, proto_list)
WALK_LIST(q, active_proto_list)
if (q->proto == pr)
{
if (p)
......@@ -571,3 +575,54 @@ 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 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, "");
}
......@@ -87,7 +87,8 @@ struct proto_config {
};
struct proto {
node n;
node n; /* Node in *_proto_list */
node glob_node; /* Node in global proto_list */
struct protocol *proto; /* Protocol */
struct proto_config *cf; /* Configuration data */
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_new(struct proto_config *, unsigned size);
void *proto_config_new(struct protocol *, unsigned size);
void proto_show(struct symbol *, int);
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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment