summaryrefslogtreecommitdiff
path: root/nest/rt-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r--nest/rt-table.c75
1 files changed, 46 insertions, 29 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c
index b18727b1..f1e3c8f7 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2027,7 +2027,7 @@ rt_export_stopped(struct rt_export_hook *hook)
rem_node(&hook->n);
/* Free the hook itself together with its pool */
- rfree(hook->pool);
+ rp_free(hook->pool);
}
static inline void
@@ -2131,7 +2131,7 @@ rt_table_export_start_locked(struct rtable_private *tab, struct rt_export_reques
struct rt_exporter *re = &tab->exporter.e;
rt_lock_table(tab);
- req->hook = rt_alloc_export(re, sizeof(struct rt_table_export_hook));
+ req->hook = rt_alloc_export(re, req->pool, sizeof(struct rt_table_export_hook));
req->hook->req = req;
struct rt_table_export_hook *hook = SKIP_BACK(struct rt_table_export_hook, h, req->hook);
@@ -2212,9 +2212,9 @@ rt_request_export_other(struct rt_exporter *re, struct rt_export_request *req)
}
struct rt_export_hook *
-rt_alloc_export(struct rt_exporter *re, uint size)
+rt_alloc_export(struct rt_exporter *re, pool *pp, uint size)
{
- pool *p = rp_new(re->rp, "Export hook");
+ pool *p = rp_new(pp, pp->domain, "Export hook");
struct rt_export_hook *hook = mb_allocz(p, size);
hook->pool = p;
@@ -2709,13 +2709,14 @@ rt_flowspec_link(rtable *src_pub, rtable *dst_pub)
if (!ln)
{
- pool *p = src->rp;
+ pool *p = birdloop_pool(dst_pub->loop);
ln = mb_allocz(p, sizeof(struct rt_flowspec_link));
ln->src = src_pub;
ln->dst = dst_pub;
ln->req = (struct rt_export_request) {
.name = mb_sprintf(p, "%s.flowspec.notifier", dst_pub->name),
.list = birdloop_event_list(dst_pub->loop),
+ .pool = p,
.trace_routes = src->config->debug,
.dump_req = rt_flowspec_dump_req,
.log_state_change = rt_flowspec_log_state_change,
@@ -2781,8 +2782,6 @@ rt_free(resource *_r)
{
struct rtable_private *r = SKIP_BACK(struct rtable_private, r, _r);
- DOMAIN_FREE(rtable, r->lock);
-
DBG("Deleting routing table %s\n", r->name);
ASSERT_DIE(r->use_count == 0);
@@ -2845,10 +2844,22 @@ rt_setup(pool *pp, struct rtable_config *cf)
{
ASSERT_DIE(birdloop_inside(&main_birdloop));
- pool *p = rp_newf(pp, "Routing table %s", cf->name);
+ /* Start the service thread */
+ struct birdloop *loop = birdloop_new(pp, DOMAIN_ORDER(service), 0, "Routing table service %s", cf->name);
+ birdloop_enter(loop);
+ pool *sp = birdloop_pool(loop);
+
+ /* Create the table domain and pool */
+ DOMAIN(rtable) dom = DOMAIN_NEW(rtable, cf->name);
+ LOCK_DOMAIN(rtable, dom);
+ pool *p = rp_newf(sp, dom.rtable, "Routing table data %s", cf->name);
+
+ /* Create the actual table */
struct rtable_private *t = ralloc(p, &rt_class);
t->rp = p;
+ t->loop = loop;
+ t->lock = dom;
t->rte_slab = sl_new(p, sizeof(struct rte_storage));
@@ -2859,8 +2870,6 @@ rt_setup(pool *pp, struct rtable_config *cf)
if (t->id >= rtable_max_id)
rtable_max_id = t->id + 1;
- t->lock = DOMAIN_NEW(rtable, t->name);
-
fib_init(&t->fib, p, t->addr_type, sizeof(net), OFFSETOF(net, n), 0, NULL);
if (cf->trie_used)
@@ -2906,9 +2915,9 @@ rt_setup(pool *pp, struct rtable_config *cf)
t->flowspec_trie->ipv4 = (t->addr_type == NET_FLOW4);
}
- /* Start the service thread */
- t->loop = birdloop_new(p, DOMAIN_ORDER(service), mb_sprintf(p, "Routing table %s", t->name), 0);
- birdloop_enter(t->loop);
+ UNLOCK_DOMAIN(rtable, dom);
+
+ /* Setup the service thread flag handler */
birdloop_flag_set_handler(t->loop, &t->fh);
birdloop_leave(t->loop);
@@ -2925,7 +2934,7 @@ void
rt_init(void)
{
rta_init();
- rt_table_pool = rp_new(&root_pool, "Routing tables");
+ rt_table_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Routing tables");
init_list(&routing_tables);
init_list(&deleted_routing_tables);
ev_init_list(&rt_cork.queue, &main_birdloop, "Route cork release");
@@ -4063,21 +4072,23 @@ rt_shutdown(void *tab_)
static void
rt_delete(void *tab_)
{
- birdloop_enter(&main_birdloop);
+ ASSERT_DIE(birdloop_inside(&main_birdloop));
/* We assume that nobody holds the table reference now as use_count is zero.
* Anyway the last holder may still hold the lock. Therefore we lock and
* unlock it the last time to be sure that nobody is there. */
struct rtable_private *tab = RT_LOCK((rtable *) tab_);
struct config *conf = tab->deleted;
+ DOMAIN(rtable) dom = tab->lock;
RT_UNLOCK(RT_PUB(tab));
+ /* Everything is freed by freeing the loop */
birdloop_free(tab->loop);
- rfree(tab->rp);
config_del_obstacle(conf);
- birdloop_leave(&main_birdloop);
+ /* Also drop the domain */
+ DOMAIN_FREE(rtable, dom);
}
@@ -4632,18 +4643,9 @@ rt_init_hostcache(struct rtable_private *tab)
.data = tab,
};
- hc->req = (struct rt_export_request) {
- .name = mb_sprintf(tab->rp, "%s.hcu.notifier", tab->name),
- .list = birdloop_event_list(tab->loop),
- .trace_routes = tab->config->debug,
- .dump_req = hc_notify_dump_req,
- .log_state_change = hc_notify_log_state_change,
- .export_one = hc_notify_export_one,
- };
-
- rt_table_export_start_locked(tab, &hc->req);
-
tab->hostcache = hc;
+
+ ev_send_loop(tab->loop, &hc->update);
}
static void
@@ -4771,9 +4773,24 @@ rt_update_hostcache(void *data)
RT_LOCKED((rtable *) data, tab)
{
-
struct hostcache *hc = tab->hostcache;
+ /* Finish initialization */
+ if (!hc->req.name)
+ {
+ hc->req = (struct rt_export_request) {
+ .name = mb_sprintf(tab->rp, "%s.hcu.notifier", tab->name),
+ .list = birdloop_event_list(tab->loop),
+ .pool = tab->rp,
+ .trace_routes = tab->config->debug,
+ .dump_req = hc_notify_dump_req,
+ .log_state_change = hc_notify_log_state_change,
+ .export_one = hc_notify_export_one,
+ };
+
+ rt_table_export_start_locked(tab, &hc->req);
+ }
+
/* Shutdown shortcut */
if (!hc->req.hook)
RT_RETURN(tab);