mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Protocols have now assigned startup phases
For now, there are 4 phases: Necessary (device), Connector (kernel, pipe), Generator (static, rpki) and Regular. Started and reconfigured are from Necessary to Regular, shutdown backwards. This way, kernel can flush routes before actually being shutdown.
This commit is contained in:
parent
5ab182d8d1
commit
e65a5257b2
78
nest/proto.c
78
nest/proto.c
@ -1134,6 +1134,7 @@ proto_cleanup(struct proto *p)
|
|||||||
|
|
||||||
p->active = 0;
|
p->active = 0;
|
||||||
proto_log_state_change(p);
|
proto_log_state_change(p);
|
||||||
|
|
||||||
proto_rethink_goal(p);
|
proto_rethink_goal(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1422,6 +1423,18 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct protos_commit_request {
|
||||||
|
struct config *new;
|
||||||
|
struct config *old;
|
||||||
|
enum protocol_startup phase;
|
||||||
|
int force_reconfig;
|
||||||
|
int type;
|
||||||
|
} protos_commit_request;
|
||||||
|
|
||||||
|
static int proto_rethink_goal_pending = 0;
|
||||||
|
|
||||||
|
static void protos_do_commit(struct config *new, struct config *old, int force_reconfig, int type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* protos_commit - commit new protocol configuration
|
* protos_commit - commit new protocol configuration
|
||||||
* @new: new configuration
|
* @new: new configuration
|
||||||
@ -1453,15 +1466,39 @@ proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config
|
|||||||
void
|
void
|
||||||
protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
|
protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
|
||||||
{
|
{
|
||||||
|
protos_commit_request = (struct protos_commit_request) {
|
||||||
|
.new = new,
|
||||||
|
.old = old,
|
||||||
|
.phase = (new->shutdown && !new->gr_down) ? PROTOCOL_STARTUP_REGULAR : PROTOCOL_STARTUP_NECESSARY,
|
||||||
|
.force_reconfig = force_reconfig,
|
||||||
|
.type = type,
|
||||||
|
};
|
||||||
|
|
||||||
|
protos_do_commit(new, old, force_reconfig, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
protos_do_commit(struct config *new, struct config *old, int force_reconfig, int type)
|
||||||
|
{
|
||||||
|
enum protocol_startup phase = protos_commit_request.phase;
|
||||||
struct proto_config *oc, *nc;
|
struct proto_config *oc, *nc;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
|
|
||||||
|
if ((phase < PROTOCOL_STARTUP_REGULAR) || (phase > PROTOCOL_STARTUP_NECESSARY))
|
||||||
|
{
|
||||||
|
protos_commit_request = (struct protos_commit_request) {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DBG("protos_commit:\n");
|
DBG("protos_commit:\n");
|
||||||
if (old)
|
if (old)
|
||||||
{
|
{
|
||||||
WALK_LIST(oc, old->protos)
|
WALK_LIST(oc, old->protos)
|
||||||
{
|
{
|
||||||
|
if (oc->protocol->startup != phase)
|
||||||
|
continue;
|
||||||
|
|
||||||
p = oc->proto;
|
p = oc->proto;
|
||||||
sym = cf_find_symbol(new, oc->name);
|
sym = cf_find_symbol(new, oc->name);
|
||||||
|
|
||||||
@ -1541,11 +1578,10 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proto *first_dev_proto = NULL;
|
|
||||||
struct proto *after = NULL;
|
struct proto *after = NULL;
|
||||||
|
|
||||||
WALK_LIST(nc, new->protos)
|
WALK_LIST(nc, new->protos)
|
||||||
if (!nc->proto)
|
if ((nc->protocol->startup == phase) && !nc->proto)
|
||||||
{
|
{
|
||||||
/* Not a first-time configuration */
|
/* Not a first-time configuration */
|
||||||
if (old)
|
if (old)
|
||||||
@ -1554,18 +1590,13 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
|
|||||||
p = proto_init(nc, after);
|
p = proto_init(nc, after);
|
||||||
after = p;
|
after = p;
|
||||||
|
|
||||||
if (p->proto == &proto_unix_iface)
|
proto_rethink_goal(p);
|
||||||
first_dev_proto = p;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
after = nc->proto;
|
after = nc->proto;
|
||||||
|
|
||||||
DBG("Protocol start\n");
|
DBG("Protocol start\n");
|
||||||
|
|
||||||
/* Start device protocol first */
|
|
||||||
if (first_dev_proto)
|
|
||||||
proto_rethink_goal(first_dev_proto);
|
|
||||||
|
|
||||||
/* Determine router ID for the first time - it has to be here and not in
|
/* Determine router ID for the first time - it has to be here and not in
|
||||||
global_commit() because it is postponed after start of device protocol */
|
global_commit() because it is postponed after start of device protocol */
|
||||||
if (!config->router_id)
|
if (!config->router_id)
|
||||||
@ -1575,9 +1606,15 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
|
|||||||
die("Cannot determine router ID, please configure it manually");
|
die("Cannot determine router ID, please configure it manually");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start all new protocols */
|
/* Commit next round of protocols */
|
||||||
WALK_TLIST_DELSAFE(proto, p, &global_proto_list)
|
if (new->shutdown && !new->gr_down)
|
||||||
proto_rethink_goal(p);
|
protos_commit_request.phase++;
|
||||||
|
else
|
||||||
|
protos_commit_request.phase--;
|
||||||
|
|
||||||
|
/* If something is pending, the next round will be called asynchronously from proto_rethink_goal(). */
|
||||||
|
if (!proto_rethink_goal_pending)
|
||||||
|
protos_do_commit(new, old, force_reconfig, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1589,12 +1626,19 @@ proto_shutdown(struct proto *p)
|
|||||||
DBG("Kicking %s down\n", p->name);
|
DBG("Kicking %s down\n", p->name);
|
||||||
PD(p, "Shutting down");
|
PD(p, "Shutting down");
|
||||||
proto_notify_state(p, (p->proto->shutdown ? p->proto->shutdown(p) : PS_DOWN));
|
proto_notify_state(p, (p->proto->shutdown ? p->proto->shutdown(p) : PS_DOWN));
|
||||||
|
if (p->reconfiguring)
|
||||||
|
{
|
||||||
|
proto_rethink_goal_pending++;
|
||||||
|
p->reconfiguring = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
proto_rethink_goal(struct proto *p)
|
proto_rethink_goal(struct proto *p)
|
||||||
{
|
{
|
||||||
|
int goal_pending = (p->reconfiguring == 2);
|
||||||
|
|
||||||
if (p->reconfiguring && !p->active)
|
if (p->reconfiguring && !p->active)
|
||||||
{
|
{
|
||||||
struct proto_config *nc = p->cf_new;
|
struct proto_config *nc = p->cf_new;
|
||||||
@ -1609,7 +1653,8 @@ proto_rethink_goal(struct proto *p)
|
|||||||
mb_free(p->message);
|
mb_free(p->message);
|
||||||
mb_free(p);
|
mb_free(p);
|
||||||
if (!nc)
|
if (!nc)
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
p = proto_init(nc, after);
|
p = proto_init(nc, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1621,6 +1666,15 @@ proto_rethink_goal(struct proto *p)
|
|||||||
}
|
}
|
||||||
else if (!p->active)
|
else if (!p->active)
|
||||||
proto_start(p);
|
proto_start(p);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (goal_pending && !--proto_rethink_goal_pending)
|
||||||
|
protos_do_commit(
|
||||||
|
protos_commit_request.new,
|
||||||
|
protos_commit_request.old,
|
||||||
|
protos_commit_request.force_reconfig,
|
||||||
|
protos_commit_request.type
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proto *
|
struct proto *
|
||||||
|
@ -40,12 +40,20 @@ struct symbol;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
enum protocol_startup {
|
||||||
|
PROTOCOL_STARTUP_REGULAR = 0, /* Regular network routing protocol, start last */
|
||||||
|
PROTOCOL_STARTUP_GENERATOR = 1, /* Static route generator, start ahead of regulars */
|
||||||
|
PROTOCOL_STARTUP_CONNECTOR = 2, /* Data connector, start first */
|
||||||
|
PROTOCOL_STARTUP_NECESSARY = 3, /* Vital auxiliary data, start zeroth */
|
||||||
|
};
|
||||||
|
|
||||||
struct protocol {
|
struct protocol {
|
||||||
node n;
|
node n;
|
||||||
char *name;
|
char *name;
|
||||||
char *template; /* Template for automatic generation of names */
|
char *template; /* Template for automatic generation of names */
|
||||||
int name_counter; /* Counter for automatic name generation */
|
int name_counter; /* Counter for automatic name generation */
|
||||||
uint preference; /* Default protocol preference */
|
uint preference; /* Default protocol preference */
|
||||||
|
enum protocol_startup startup; /* When to start / stop this protocol */
|
||||||
uint channel_mask; /* Mask of accepted channel types (NB_*) */
|
uint channel_mask; /* Mask of accepted channel types (NB_*) */
|
||||||
uint proto_size; /* Size of protocol data structure */
|
uint proto_size; /* Size of protocol data structure */
|
||||||
uint config_size; /* Size of protocol config data structure */
|
uint config_size; /* Size of protocol config data structure */
|
||||||
|
@ -334,6 +334,7 @@ struct protocol proto_pipe = {
|
|||||||
.template = "pipe%d",
|
.template = "pipe%d",
|
||||||
.proto_size = sizeof(struct pipe_proto),
|
.proto_size = sizeof(struct pipe_proto),
|
||||||
.config_size = sizeof(struct pipe_config),
|
.config_size = sizeof(struct pipe_config),
|
||||||
|
.startup = PROTOCOL_STARTUP_CONNECTOR,
|
||||||
.postconfig = pipe_postconfig,
|
.postconfig = pipe_postconfig,
|
||||||
.init = pipe_init,
|
.init = pipe_init,
|
||||||
.reconfigure = pipe_reconfigure,
|
.reconfigure = pipe_reconfigure,
|
||||||
|
@ -994,6 +994,7 @@ struct protocol proto_rpki = {
|
|||||||
.preference = DEF_PREF_RPKI,
|
.preference = DEF_PREF_RPKI,
|
||||||
.proto_size = sizeof(struct rpki_proto),
|
.proto_size = sizeof(struct rpki_proto),
|
||||||
.config_size = sizeof(struct rpki_config),
|
.config_size = sizeof(struct rpki_config),
|
||||||
|
.startup = PROTOCOL_STARTUP_GENERATOR,
|
||||||
.init = rpki_init,
|
.init = rpki_init,
|
||||||
.start = rpki_start,
|
.start = rpki_start,
|
||||||
.postconfig = rpki_postconfig,
|
.postconfig = rpki_postconfig,
|
||||||
|
@ -775,6 +775,7 @@ struct protocol proto_static = {
|
|||||||
.channel_mask = NB_ANY,
|
.channel_mask = NB_ANY,
|
||||||
.proto_size = sizeof(struct static_proto),
|
.proto_size = sizeof(struct static_proto),
|
||||||
.config_size = sizeof(struct static_config),
|
.config_size = sizeof(struct static_config),
|
||||||
|
.startup = PROTOCOL_STARTUP_GENERATOR,
|
||||||
.postconfig = static_postconfig,
|
.postconfig = static_postconfig,
|
||||||
.init = static_init,
|
.init = static_init,
|
||||||
.dump = static_dump,
|
.dump = static_dump,
|
||||||
|
@ -243,6 +243,7 @@ struct protocol proto_unix_iface = {
|
|||||||
.template = "device%d",
|
.template = "device%d",
|
||||||
.proto_size = sizeof(struct kif_proto),
|
.proto_size = sizeof(struct kif_proto),
|
||||||
.config_size = sizeof(struct kif_config),
|
.config_size = sizeof(struct kif_config),
|
||||||
|
.startup = PROTOCOL_STARTUP_NECESSARY,
|
||||||
.preconfig = kif_preconfig,
|
.preconfig = kif_preconfig,
|
||||||
.init = kif_init,
|
.init = kif_init,
|
||||||
.start = kif_start,
|
.start = kif_start,
|
||||||
@ -993,6 +994,7 @@ struct protocol proto_unix_kernel = {
|
|||||||
.channel_mask = NB_IP | MAYBE_IP6_SADR | MAYBE_MPLS,
|
.channel_mask = NB_IP | MAYBE_IP6_SADR | MAYBE_MPLS,
|
||||||
.proto_size = sizeof(struct krt_proto),
|
.proto_size = sizeof(struct krt_proto),
|
||||||
.config_size = sizeof(struct krt_config),
|
.config_size = sizeof(struct krt_config),
|
||||||
|
.startup = PROTOCOL_STARTUP_CONNECTOR,
|
||||||
.preconfig = krt_preconfig,
|
.preconfig = krt_preconfig,
|
||||||
.postconfig = krt_postconfig,
|
.postconfig = krt_postconfig,
|
||||||
.init = krt_init,
|
.init = krt_init,
|
||||||
|
Loading…
Reference in New Issue
Block a user