Solve chicken-and-egg problems with protocol startup. We now queue all inactive

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.
This commit is contained in:
Martin Mares 1998-10-17 11:05:18 +00:00
parent d92882be9b
commit 47b793064c
7 changed files with 62 additions and 8 deletions

View 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 void
if_init(void) if_init(void)
{ {

View file

@ -13,6 +13,8 @@
extern list iface_list; extern list iface_list;
struct proto;
struct iface { struct iface {
node n; node n;
char name[16]; char name[16];
@ -51,6 +53,7 @@ void if_dump(struct iface *);
void if_dump_all(void); void if_dump_all(void);
void if_update(struct iface *); void if_update(struct iface *);
void if_end_update(void); void if_end_update(void);
void if_feed_baby(struct proto *);
/* /*
* Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen * Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen

View file

@ -15,9 +15,12 @@
#include "lib/resource.h" #include "lib/resource.h"
#include "lib/lists.h" #include "lib/lists.h"
#include "nest/confile.h" #include "nest/confile.h"
#include "nest/route.h"
#include "nest/iface.h"
list protocol_list; list protocol_list;
list proto_list; list proto_list;
list inactive_proto_list;
void * void *
proto_new(struct protocol *pr, unsigned size) proto_new(struct protocol *pr, unsigned size)
@ -30,7 +33,7 @@ proto_new(struct protocol *pr, unsigned size)
p->name = pr->name; p->name = pr->name;
p->debug = pr->debug; p->debug = pr->debug;
p->pool = rp_new(&root_pool, pr->name); p->pool = rp_new(&root_pool, pr->name);
add_tail(&proto_list, &p->n); add_tail(&inactive_proto_list, &p->n);
return p; return p;
} }
@ -40,6 +43,7 @@ protos_preconfig(void)
struct protocol *p; struct protocol *p;
init_list(&proto_list); init_list(&proto_list);
init_list(&inactive_proto_list);
debug("Protocol preconfig\n"); debug("Protocol preconfig\n");
WALK_LIST(p, protocol_list) 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 void
protos_start(void) protos_start(void)
{ {
struct proto *p; struct proto *p, *n;
debug("Protocol start\n"); debug("Protocol start\n");
WALK_LIST(p, proto_list) WALK_LIST_DELSAFE(p, n, inactive_proto_list)
{ {
debug("...%s\n", p->name); debug("...%s\n", p->name);
if (p->start) proto_start(p);
p->start(p);
} }
} }
@ -89,6 +102,8 @@ protos_dump_all(void)
if (p->dump) if (p->dump)
p->dump(p); p->dump(p);
} }
WALK_LIST(p, inactive_proto_list)
debug(" inactive %s\n", p->name);
} }
void void

View file

@ -58,6 +58,7 @@ struct proto {
unsigned debug; /* Debugging flags */ unsigned debug; /* Debugging flags */
pool *pool; /* Local objects */ pool *pool; /* Local objects */
unsigned preference; /* Default route preference */ unsigned preference; /* Default route preference */
int ready; /* Already initialized */
void (*if_notify)(struct proto *, unsigned flags, struct iface *new, struct iface *old); 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); 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); void *proto_new(struct protocol *, unsigned size);
extern list proto_list; extern list proto_list, inactive_proto_list;
#endif #endif

View file

@ -126,6 +126,7 @@ void rte_update(net *net, struct proto *p, rte *new);
void rte_dump(net *, rte *); void rte_dump(net *, rte *);
void rt_dump(rtable *); void rt_dump(rtable *);
void rt_dump_all(void); void rt_dump_all(void);
void rt_feed_baby(struct proto *p);
/* /*
* Route Attributes * Route Attributes

View file

@ -116,6 +116,28 @@ rte_announce(net *net, rte *new, rte *old)
p->rt_notify(p, net, new, 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 static inline void
rte_free(rte *e) rte_free(rte *e)
{ {

View file

@ -82,10 +82,10 @@ main(void)
signal_init(); signal_init();
protos_start();
scan_if_init(); scan_if_init();
protos_start();
handle_sigusr(0); handle_sigusr(0);
debug("Entering I/O loop.\n"); debug("Entering I/O loop.\n");