]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Protocol engine bug fixes:
authorMartin Mares <mj@ucw.cz>
Tue, 3 Aug 1999 19:31:54 +0000 (19:31 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 3 Aug 1999 19:31:54 +0000 (19:31 +0000)
   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).

nest/proto.c
nest/protocol.h

index 3199fee26e2618a0c7811015abbba630321711ac..bbf5d59814fd243a64222dfa50b0986aba92da08 100644 (file)
@@ -86,7 +86,7 @@ proto_new(struct proto_config *c, unsigned size)
   p->preference = c->preference;
   p->disabled = c->disabled;
   p->proto = pr;
-  p->table = (c->table ? : c->global->master_rtc)->table;
+  p->table = c->table->table;
   p->in_filter = c->in_filter;
   p->out_filter = c->out_filter;
   return p;
@@ -139,6 +139,7 @@ proto_config_new(struct protocol *pr, unsigned size)
   c->debug = pr->debug;
   c->name = pr->name;
   c->out_filter = FILTER_REJECT;
+  c->table = c->global->master_rtc;
   return c;
 }
 
@@ -195,6 +196,15 @@ protos_commit(struct config *c)
       q->proto_state = PS_DOWN;
       q->core_state = FS_HUNGRY;
       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");
 }
@@ -211,6 +221,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--;
          proto_init_instance(p);
          proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
        }
@@ -250,13 +262,13 @@ protos_shutdown(void)
   struct proto *p, *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)
     {
       proto_shutdown_counter++;
       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_set_goal(p, FS_HUNGRY);
@@ -375,6 +387,7 @@ proto_notify_state(struct proto *p, unsigned ps)
        {
        schedule_flush:
          DBG("%s: Scheduling flush\n", p->name);
+         proto_flush_hooks(p);
          cs = FS_FLUSHING;
          ev_schedule(proto_flush_event);
        }
@@ -398,7 +411,6 @@ proto_flush_all(void *unused)
   while ((p = HEAD(flush_proto_list))->n.next)
     {
       DBG("Flushing protocol %s\n", p->name);
-      proto_flush_hooks(p);
       rfree(p->pool);
       p->pool = NULL;
       p->core_state = FS_HUNGRY;
index 84c46fa812a144991b8cc9e125608433fac802fc..8d2f8cfa3c2b549b99f1112bcecf67d4d31d4150 100644 (file)
@@ -34,6 +34,7 @@ struct protocol {
   unsigned debug;                      /* Default debugging flags */
   int priority;                                /* Protocol priority (usually 0) */
   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 (*postconfig)(struct proto_config *);                   /* After configuring each instance */