diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/iface.c | 12 | ||||
-rw-r--r-- | nest/iface.h | 3 | ||||
-rw-r--r-- | nest/proto.c | 25 | ||||
-rw-r--r-- | nest/protocol.h | 3 | ||||
-rw-r--r-- | nest/route.h | 1 | ||||
-rw-r--r-- | nest/rt-table.c | 22 |
6 files changed, 60 insertions, 6 deletions
diff --git a/nest/iface.c b/nest/iface.c index 591733a1..f6f33a99 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -313,6 +313,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) { if_pool = rp_new(&root_pool, "Interfaces"); diff --git a/nest/iface.h b/nest/iface.h index b1984b39..101e0282 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -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 diff --git a/nest/proto.c b/nest/proto.c index 478eb77b..6db5a0ef 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -15,9 +15,12 @@ #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 diff --git a/nest/protocol.h b/nest/protocol.h index 92bcbbe1..ec4408fd 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -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 diff --git a/nest/route.h b/nest/route.h index 8e335b22..1bd20b63 100644 --- a/nest/route.h +++ b/nest/route.h @@ -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 diff --git a/nest/rt-table.c b/nest/rt-table.c index 1d0c29c8..dc72c6b1 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -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) { |