]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Solve chicken-and-egg problems with protocol startup. We now queue all inactive
authorMartin Mares <mj@ucw.cz>
Sat, 17 Oct 1998 11:05:18 +0000 (11:05 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 17 Oct 1998 11:05:18 +0000 (11:05 +0000)
protocols and don't send route/interface updates to them and when they come up,
we resend the whole route/interface tables privately.

Removed the "scan interface list after protocol start" work-around.

nest/iface.c
nest/iface.h
nest/proto.c
nest/protocol.h
nest/route.h
nest/rt-table.c
sysdep/unix/main.c

index 591733a1a8522149cc69f8eff27d9032044e9432..f6f33a99cc34b7920875fbd2ee936422b822367f 100644 (file)
@@ -312,6 +312,18 @@ if_end_update(void)
       }
 }
 
+void
+if_feed_baby(struct proto *p)
+{
+  struct iface *i;
+
+  if (!p->if_notify)
+    return;
+  debug("Announcing interfaces to new protocol %s\n", p->name);
+  WALK_LIST(i, iface_list)
+    p->if_notify(p, IF_CHANGE_CREATE | ((i->flags & IF_UP) ? IF_CHANGE_UP : 0), NULL, i);
+}
+
 void
 if_init(void)
 {
index b1984b398025a8c7ebc9502e45ba47f43ac155fe..101e0282c1bba58afa16473662fd0e977997ac56 100644 (file)
@@ -13,6 +13,8 @@
 
 extern list iface_list;
 
+struct proto;
+
 struct iface {
   node n;
   char name[16];
@@ -51,6 +53,7 @@ void if_dump(struct iface *);
 void if_dump_all(void);
 void if_update(struct iface *);
 void if_end_update(void);
+void if_feed_baby(struct proto *);
 
 /*
  *     Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen
index 478eb77bb38c74a8cc3c0b1e820bbf2226ac4a1e..6db5a0ef84a15ac01c063b5e26493f45c5727a23 100644 (file)
 #include "lib/resource.h"
 #include "lib/lists.h"
 #include "nest/confile.h"
+#include "nest/route.h"
+#include "nest/iface.h"
 
 list protocol_list;
 list proto_list;
+list inactive_proto_list;
 
 void *
 proto_new(struct protocol *pr, unsigned size)
@@ -30,7 +33,7 @@ proto_new(struct protocol *pr, unsigned size)
   p->name = pr->name;
   p->debug = pr->debug;
   p->pool = rp_new(&root_pool, pr->name);
-  add_tail(&proto_list, &p->n);
+  add_tail(&inactive_proto_list, &p->n);
   return p;
 }
 
@@ -40,6 +43,7 @@ protos_preconfig(void)
   struct protocol *p;
 
   init_list(&proto_list);
+  init_list(&inactive_proto_list);
   debug("Protocol preconfig\n");
   WALK_LIST(p, protocol_list)
     {
@@ -61,18 +65,27 @@ protos_postconfig(void)
     }
 }
 
+static void
+proto_start(struct proto *p)
+{
+  rem_node(&p->n);
+  if (p->start)
+    p->start(p);
+  if_feed_baby(p);
+  rt_feed_baby(p);
+  add_tail(&proto_list, &p->n);
+}
 
 void
 protos_start(void)
 {
-  struct proto *p;
+  struct proto *p, *n;
 
   debug("Protocol start\n");
-  WALK_LIST(p, proto_list)
+  WALK_LIST_DELSAFE(p, n, inactive_proto_list)
     {
       debug("...%s\n", p->name);
-      if (p->start)
-       p->start(p);
+      proto_start(p);
     }
 }
 
@@ -89,6 +102,8 @@ protos_dump_all(void)
       if (p->dump)
        p->dump(p);
     }
+  WALK_LIST(p, inactive_proto_list)
+    debug("  inactive %s\n", p->name);
 }
 
 void
index 92bcbbe1bdca47792a3b0a13bac9406a306bab86..ec4408fde434e4e8e12596c366104b2338d8824d 100644 (file)
@@ -58,6 +58,7 @@ struct proto {
   unsigned debug;                      /* Debugging flags */
   pool *pool;                          /* Local objects */
   unsigned preference;                 /* Default route preference */
+  int ready;                           /* Already initialized */
 
   void (*if_notify)(struct proto *, unsigned flags, struct iface *new, struct iface *old);
   void (*rt_notify)(struct proto *, struct network *net, struct rte *new, struct rte *old);
@@ -79,6 +80,6 @@ struct proto {
 
 void *proto_new(struct protocol *, unsigned size);
 
-extern list proto_list;
+extern list proto_list, inactive_proto_list;
 
 #endif
index 8e335b226213007f5a64fe42f0b69dcb3f835db4..1bd20b634a27f2cc274724c2b04e291c9bbe0e27 100644 (file)
@@ -126,6 +126,7 @@ void rte_update(net *net, struct proto *p, rte *new);
 void rte_dump(net *, rte *);
 void rt_dump(rtable *);
 void rt_dump_all(void);
+void rt_feed_baby(struct proto *p);
 
 /*
  *     Route Attributes
index 1d0c29c8e79939fd76d1afaf40a18b6a6e29af6b..dc72c6b1a91de4093f3b2cb892570d35a89bd867 100644 (file)
@@ -116,6 +116,28 @@ rte_announce(net *net, rte *new, rte *old)
        p->rt_notify(p, net, new, old);
 }
 
+void
+rt_feed_baby(struct proto *p)
+{
+  rtable *t = &master_table;
+
+  if (!p->rt_notify)
+    return;
+  debug("Announcing routes to new protocol %s\n", p->name);
+  while (t)
+    {
+      FIB_WALK(&t->fib, fn)
+       {
+         net *n = (net *) fn;
+         rte *e;
+         for(e=n->routes; e; e=e->next)
+           p->rt_notify(p, n, e, NULL);
+       }
+      FIB_WALK_END;
+      t = t->sibling;
+    }
+}
+
 static inline void
 rte_free(rte *e)
 {
index ce3768c216696d006b10049d60c553a5bc2fd38a..b57e94e5b80e356c2993655ccb9b2395f411b4ce 100644 (file)
@@ -82,10 +82,10 @@ main(void)
 
   signal_init();
 
-  protos_start();
-
   scan_if_init();
 
+  protos_start();
+
   handle_sigusr(0);
 
   debug("Entering I/O loop.\n");