static char *proto_state_name(struct proto *p);
static void
-proto_enqueue(list *l, struct proto *p)
-{
- add_tail(l, &p->n);
-}
-
-static void
-proto_set_core_state(struct proto *p, uint state)
+proto_relink(struct proto *p)
{
list *l = NULL;
- p->core_state = state;
-
- if (p->debug & D_STATES)
- {
- char *name = proto_state_name(p);
- if (name != p->last_state_name_announced)
- {
- p->last_state_name_announced = name;
- PD(p, "State changed to %s", proto_state_name(p));
- }
- }
- else
- p->last_state_name_announced = NULL;
-
- rem_node(&p->n);
switch (p->core_state)
{
case FS_HUNGRY:
default:
ASSERT(0);
}
- proto_enqueue(l, p);
+
+ rem_node(&p->n);
+ add_tail(l, &p->n);
+}
+
+static void
+proto_log_state_change(struct proto *p)
+{
+ if (p->debug & D_STATES)
+ {
+ char *name = proto_state_name(p);
+ if (name != p->last_state_name_announced)
+ {
+ p->last_state_name_announced = name;
+ PD(p, "State changed to %s", proto_state_name(p));
+ }
+ }
+ else
+ p->last_state_name_announced = NULL;
}
+
/**
* proto_new - create a new protocol instance
* @c: protocol configuration
q->export_state = ES_DOWN;
q->last_state_change = now;
- proto_enqueue(&initial_proto_list, q);
+ add_tail(&initial_proto_list, &q->n);
+
if (p == &proto_unix_iface)
initial_device_proto = q;
/* Resume postponed export of routes */
if ((p->proto_state == PS_UP) && p->gr_wait)
+ {
proto_want_export_up(p);
+ proto_log_state_change(p);
+ }
/* Cleanup */
p->gr_recovery = 0;
{
DBG("Feeding protocol %s finished\n", p->name);
p->export_state = ES_READY;
+ proto_log_state_change(p);
if (p->feed_done)
p->feed_done(p);
DBG("Flushing protocol %s\n", p->name);
p->flushing = 0;
- proto_set_core_state(p, FS_HUNGRY);
+ p->core_state = FS_HUNGRY;
+ proto_relink(p);
+ proto_log_state_change(p);
if (p->proto_state == PS_DOWN)
proto_fell_down(p);
goto again;
p->stats.exp_routes = 0;
proto_schedule_feed(p, 0);
+ proto_log_state_change(p);
}
static const char *
proto_reset_limit(p->main_ahook->out_limit);
}
- proto_set_core_state(p, FS_HAPPY);
+ p->core_state = FS_HAPPY;
+ proto_relink(p);
}
static void
ASSERT(p->core_state == CS_HAPPY);
ASSERT(p->export_state == ES_DOWN);
- proto_set_core_state(p, FS_FLUSHING);
+ p->core_state = FS_FLUSHING;
+ proto_relink(p);
proto_schedule_flush_loop();
if (!p->proto->multitable)
if (cs == FS_HUNGRY) /* Shutdown finished */
{
+ proto_log_state_change(p);
proto_fell_down(p);
return; /* The protocol might have ceased to exist */
}
default:
bug("%s: Invalid state %d", p->name, ps);
}
+
+ proto_log_state_change(p);
}
/*
case ES_READY: return "up";
default: return "???";
}
- case P(PS_STOP, FS_HUNGRY): return "stop";
- case P(PS_STOP, FS_FLUSHING):
+ case P(PS_STOP, FS_HUNGRY):
+ case P(PS_STOP, FS_FLUSHING): return "stop";
case P(PS_DOWN, FS_FLUSHING): return "flush";
default: return "???";
}