Protocol engine bug fixes:
o Make proto_config->table always point to the right table even if it should be the default one. o When shutting down, kill protocol in reverse order of their priority. o When stopping a protocol down, disconnect it from routing tables immediately instead of waiting for the delayed protocol flush event. Also added a protocol instance counter (used by KRT code in very magic ways).
This commit is contained in:
parent
b6628a8c98
commit
9d8856897f
2 changed files with 17 additions and 4 deletions
20
nest/proto.c
20
nest/proto.c
|
@ -86,7 +86,7 @@ proto_new(struct proto_config *c, unsigned size)
|
||||||
p->preference = c->preference;
|
p->preference = c->preference;
|
||||||
p->disabled = c->disabled;
|
p->disabled = c->disabled;
|
||||||
p->proto = pr;
|
p->proto = pr;
|
||||||
p->table = (c->table ? : c->global->master_rtc)->table;
|
p->table = c->table->table;
|
||||||
p->in_filter = c->in_filter;
|
p->in_filter = c->in_filter;
|
||||||
p->out_filter = c->out_filter;
|
p->out_filter = c->out_filter;
|
||||||
return p;
|
return p;
|
||||||
|
@ -139,6 +139,7 @@ proto_config_new(struct protocol *pr, unsigned size)
|
||||||
c->debug = pr->debug;
|
c->debug = pr->debug;
|
||||||
c->name = pr->name;
|
c->name = pr->name;
|
||||||
c->out_filter = FILTER_REJECT;
|
c->out_filter = FILTER_REJECT;
|
||||||
|
c->table = c->global->master_rtc;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +196,15 @@ protos_commit(struct 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);
|
||||||
|
/*
|
||||||
|
* HACK ALERT! In case of multiple kernel routing tables,
|
||||||
|
* the kernel syncer acts as multiple protocols which cooperate
|
||||||
|
* with each other. In order to speed up their initialization,
|
||||||
|
* we need to know when we're initializing the last one, hence
|
||||||
|
* the startup counter.
|
||||||
|
*/
|
||||||
|
if (!q->disabled)
|
||||||
|
p->startup_counter++;
|
||||||
}
|
}
|
||||||
debug("\n");
|
debug("\n");
|
||||||
}
|
}
|
||||||
|
@ -211,6 +221,8 @@ 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);
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
@ -250,13 +262,13 @@ protos_shutdown(void)
|
||||||
struct proto *p, *n;
|
struct proto *p, *n;
|
||||||
|
|
||||||
debug("Protocol shutdown\n");
|
debug("Protocol shutdown\n");
|
||||||
WALK_LIST_DELSAFE(p, n, inactive_proto_list)
|
WALK_LIST_BACKWARDS_DELSAFE(p, n, inactive_proto_list)
|
||||||
if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN)
|
if (p->core_state != FS_HUNGRY || p->proto_state != PS_DOWN)
|
||||||
{
|
{
|
||||||
proto_shutdown_counter++;
|
proto_shutdown_counter++;
|
||||||
proto_set_goal(p, FS_HUNGRY);
|
proto_set_goal(p, FS_HUNGRY);
|
||||||
}
|
}
|
||||||
WALK_LIST_DELSAFE(p, n, proto_list)
|
WALK_LIST_BACKWARDS_DELSAFE(p, n, proto_list)
|
||||||
{
|
{
|
||||||
proto_shutdown_counter++;
|
proto_shutdown_counter++;
|
||||||
proto_set_goal(p, FS_HUNGRY);
|
proto_set_goal(p, FS_HUNGRY);
|
||||||
|
@ -375,6 +387,7 @@ proto_notify_state(struct proto *p, unsigned ps)
|
||||||
{
|
{
|
||||||
schedule_flush:
|
schedule_flush:
|
||||||
DBG("%s: Scheduling flush\n", p->name);
|
DBG("%s: Scheduling flush\n", p->name);
|
||||||
|
proto_flush_hooks(p);
|
||||||
cs = FS_FLUSHING;
|
cs = FS_FLUSHING;
|
||||||
ev_schedule(proto_flush_event);
|
ev_schedule(proto_flush_event);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +411,6 @@ proto_flush_all(void *unused)
|
||||||
while ((p = HEAD(flush_proto_list))->n.next)
|
while ((p = HEAD(flush_proto_list))->n.next)
|
||||||
{
|
{
|
||||||
DBG("Flushing protocol %s\n", p->name);
|
DBG("Flushing protocol %s\n", p->name);
|
||||||
proto_flush_hooks(p);
|
|
||||||
rfree(p->pool);
|
rfree(p->pool);
|
||||||
p->pool = NULL;
|
p->pool = NULL;
|
||||||
p->core_state = FS_HUNGRY;
|
p->core_state = FS_HUNGRY;
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct protocol {
|
||||||
unsigned debug; /* Default debugging flags */
|
unsigned debug; /* Default debugging flags */
|
||||||
int priority; /* Protocol priority (usually 0) */
|
int priority; /* Protocol priority (usually 0) */
|
||||||
int name_counter; /* Counter for automatic name generation */
|
int name_counter; /* Counter for automatic name generation */
|
||||||
|
int startup_counter; /* Number of instances waiting for initialization */
|
||||||
|
|
||||||
void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
|
void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
|
||||||
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
||||||
|
|
Loading…
Reference in a new issue