diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/proto.c | 16 | ||||
-rw-r--r-- | nest/protocol.h | 2 | ||||
-rw-r--r-- | nest/route.h | 12 | ||||
-rw-r--r-- | nest/rt-table.c | 139 |
4 files changed, 69 insertions, 100 deletions
diff --git a/nest/proto.c b/nest/proto.c index ac0fb232..f8e1ba31 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -658,6 +658,8 @@ channel_aux_stopped(void *data) else c->in_table = NULL; + rfree(cat->tab->rp); + mb_free(cat); return channel_check_stopped(c); } @@ -666,7 +668,7 @@ static void channel_aux_import_stopped(struct rt_import_request *req) { struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, push, req); - ASSERT_DIE(cat->stop); + ASSERT_DIE(cat->tab->delete_event); } static void @@ -675,25 +677,23 @@ channel_aux_export_stopped(struct rt_export_request *req) struct channel_aux_table *cat = SKIP_BACK(struct channel_aux_table, get, req); req->hook = NULL; - if (cat->refeed_pending && !cat->stop) + if (cat->refeed_pending && !cat->tab->delete_event) { cat->refeed_pending = 0; rt_request_export(cat->tab, req); } else - ASSERT_DIE(cat->stop); + ASSERT_DIE(cat->tab->delete_event); } static void channel_aux_stop(struct channel_aux_table *cat) { - cat->stop = 1; - rt_stop_import(&cat->push, channel_aux_import_stopped); rt_stop_export(&cat->get, channel_aux_export_stopped); - cat->tab->deleted = channel_aux_stopped; - cat->tab->del_data = cat; + cat->tab->delete_event = ev_new_init(cat->tab->rp, channel_aux_stopped, cat); + rt_unlock_table(cat->tab); } @@ -886,7 +886,6 @@ channel_setup_in_table(struct channel *c, int best) c->in_table->c = c; c->in_table->tab = rt_setup(c->proto->pool, &cat->tab_cf); - self_link(&c->in_table->tab->n); rt_lock_table(c->in_table->tab); rt_request_import(c->in_table->tab, &c->in_table->push); @@ -929,7 +928,6 @@ channel_setup_out_table(struct channel *c) c->out_table->c = c; c->out_table->tab = rt_setup(c->proto->pool, &cat->tab_cf); - self_link(&c->out_table->tab->n); rt_lock_table(c->out_table->tab); rt_request_import(c->out_table->tab, &c->out_table->push); diff --git a/nest/protocol.h b/nest/protocol.h index 2fbd607c..981ca96a 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -568,7 +568,7 @@ struct channel_aux_table { struct rt_import_request push; struct rt_export_request get; rtable *tab; - u8 stop; + event *stop; u8 refeed_pending; }; diff --git a/nest/route.h b/nest/route.h index 7c5fd02f..88a56073 100644 --- a/nest/route.h +++ b/nest/route.h @@ -147,6 +147,7 @@ void fit_copy(struct fib *f, struct fib_iterator *dst, struct fib_iterator *src) struct rtable_config { node n; char *name; + struct config *config; struct rtable *table; struct proto_config *krt_attached; /* Kernel syncer attached to this table */ uint addr_type; /* Type of address data stored in table (NET_*) */ @@ -175,17 +176,17 @@ typedef struct rtable { struct hmap id_map; struct hostcache *hostcache; struct rtable_config *config; /* Configuration of this table */ - void (*deleted)(void *); /* Table should free itself. Call this when it is done. */ - void *del_data; - struct event *rt_event; /* Routing table event */ + struct event *prune_event; /* Event to prune abandoned routes */ + struct event *ec_event; /* Event to prune finished exports */ + struct event *hcu_event; /* Event to update host cache */ + struct event *nhu_event; /* Event to update next hops */ + struct event *delete_event; /* Event to delete the table */ btime last_rt_change; /* Last time when route changed */ btime base_settle_time; /* Start time of rtable settling interval */ btime gc_time; /* Time of last GC */ int gc_counter; /* Number of operations since last GC */ byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */ - byte hcu_scheduled; /* Hostcache update is scheduled */ byte nhu_state; /* Next Hop Update state */ - byte export_used; /* Export journal setup scheduled */ struct fib_iterator prune_fit; /* Rtable prune FIB iterator */ struct fib_iterator nhu_fit; /* Next Hop Update FIB iterator */ struct tbf rl_pipe; /* Rate limiting token buffer for pipe collisions */ @@ -475,7 +476,6 @@ void rt_unlock_table(rtable *); void rt_subscribe(rtable *tab, struct rt_subscription *s); void rt_unsubscribe(struct rt_subscription *s); rtable *rt_setup(pool *, struct rtable_config *); -static inline void rt_shutdown(rtable *r) { rfree(r->rp); } static inline net *net_find(rtable *tab, const net_addr *addr) { return (net *) fib_find(&tab->fib, addr); } static inline net *net_find_valid(rtable *tab, const net_addr *addr) diff --git a/nest/rt-table.c b/nest/rt-table.c index 9c12ef56..6dd6587e 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -65,14 +65,14 @@ struct rt_export_block { static void rt_free_hostcache(rtable *tab); static void rt_notify_hostcache(rtable *tab, net *net); -static void rt_update_hostcache(rtable *tab); -static void rt_next_hop_update(rtable *tab); -static inline void rt_prune_table(rtable *tab); +static void rt_update_hostcache(void *tab); +static void rt_next_hop_update(void *tab); +static inline void rt_prune_table(void *tab); static inline void rt_schedule_notify(rtable *tab); static void rt_feed_channel(void *); static inline void rt_export_used(rtable *tab); -static void rt_export_cleanup(rtable *tab); +static void rt_export_cleanup(void *tab); static inline void rte_update_lock(void); static inline void rte_update_unlock(void); @@ -1860,7 +1860,7 @@ rte_dump(struct rte_storage *e) void rt_dump(rtable *t) { - debug("Dump of routing table <%s>%s\n", t->name, t->deleted ? " (deleted)" : ""); + debug("Dump of routing table <%s>%s\n", t->name, t->delete_event ? " (deleted)" : ""); #ifdef DEBUGGING fib_check(&t->fib); #endif @@ -1891,9 +1891,9 @@ rt_dump_all(void) void rt_dump_hooks(rtable *tab) { - debug("Dump of hooks in routing table <%s>%s\n", tab->name, tab->deleted ? " (deleted)" : ""); + debug("Dump of hooks in routing table <%s>%s\n", tab->name, tab->delete_event ? " (deleted)" : ""); debug(" nhu_state=%u hcu_scheduled=%u use_count=%d rt_count=%u\n", - tab->nhu_state, tab->hcu_scheduled, tab->use_count, tab->rt_count); + tab->nhu_state, ev_active(tab->hcu_event), tab->use_count, tab->rt_count); debug(" last_rt_change=%t gc_time=%t gc_counter=%d prune_state=%u\n", tab->last_rt_change, tab->gc_time, tab->gc_counter, tab->prune_state); @@ -1931,20 +1931,10 @@ rt_dump_hooks_all(void) } static inline void -rt_schedule_hcu(rtable *tab) -{ - if (tab->hcu_scheduled) - return; - - tab->hcu_scheduled = 1; - ev_schedule(tab->rt_event); -} - -static inline void rt_schedule_nhu(rtable *tab) { if (tab->nhu_state == NHU_CLEAN) - ev_schedule(tab->rt_event); + ev_schedule(tab->nhu_event); /* state change: * NHU_CLEAN -> NHU_SCHEDULED @@ -1957,7 +1947,7 @@ void rt_schedule_prune(rtable *tab) { if (tab->prune_state == 0) - ev_schedule(tab->rt_event); + ev_schedule(tab->prune_event); /* state change 0->1, 2->3 */ tab->prune_state |= 1; @@ -1969,36 +1959,9 @@ rt_export_used(rtable *tab) if (config->table_debug) log(L_TRACE "%s: Export cleanup requested", tab->name); - if (tab->export_used) - return; - - tab->export_used = 1; - ev_schedule(tab->rt_event); + ev_schedule(tab->ec_event); } -static void -rt_event(void *ptr) -{ - rtable *tab = ptr; - - rt_lock_table(tab); - - if (tab->export_used) - rt_export_cleanup(tab); - - if (tab->hcu_scheduled) - rt_update_hostcache(tab); - - if (tab->nhu_state) - rt_next_hop_update(tab); - - if (tab->prune_state) - rt_prune_table(tab); - - rt_unlock_table(tab); -} - - static inline btime rt_settled_time(rtable *tab) { @@ -2078,13 +2041,9 @@ rt_free(resource *_r) DBG("Deleting routing table %s\n", r->name); ASSERT_DIE(r->use_count == 0); - ASSERT_DIE(r->deleted); - - r->config->table = NULL; - rem_node(&r->n); - - if (r->hostcache) - rt_free_hostcache(r); + ASSERT_DIE(r->rt_count == 0); + ASSERT_DIE(EMPTY_LIST(r->imports)); + ASSERT_DIE(EMPTY_LIST(r->exports)); /* Freed automagically by the resource pool fib_free(&r->fib); @@ -2142,7 +2101,11 @@ rt_setup(pool *pp, struct rtable_config *cf) init_list(&t->pending_exports); init_list(&t->subscribers); - t->rt_event = ev_new_init(p, rt_event, t); + t->ec_event = ev_new_init(p, rt_export_cleanup, t); + t->prune_event = ev_new_init(p, rt_prune_table, t); + t->hcu_event = ev_new_init(p, rt_update_hostcache, t); + t->nhu_event = ev_new_init(p, rt_next_hop_update, t); + t->export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0); t->last_rt_change = t->gc_time = current_time(); t->next_export_seq = 1; @@ -2167,7 +2130,6 @@ rt_init(void) init_list(&routing_tables); } - /** * rt_prune_table - prune a routing table * @@ -2183,8 +2145,9 @@ rt_init(void) * iteration. */ static void -rt_prune_table(rtable *tab) +rt_prune_table(void *data) { + rtable *tab = data; struct fib_iterator *fit = &tab->prune_fit; int limit = 512; @@ -2232,7 +2195,7 @@ again: if (limit <= 0) { FIB_ITERATE_PUT(fit); - ev_schedule(tab->rt_event); + ev_schedule(tab->prune_event); return; } @@ -2288,9 +2251,9 @@ again: } static void -rt_export_cleanup(rtable *tab) +rt_export_cleanup(void *data) { - tab->export_used = 0; + rtable *tab = data; u64 min_seq = ~((u64) 0); struct rt_pending_export *last_export_to_free = NULL; @@ -2447,9 +2410,6 @@ done:; imports_stopped = 1; } - if (tab->export_used) - ev_schedule(tab->rt_event); - if (imports_stopped) { if (config->table_debug) @@ -2683,8 +2643,9 @@ rt_next_hop_update_net(rtable *tab, net *n) } static void -rt_next_hop_update(rtable *tab) +rt_next_hop_update(void *data) { + rtable *tab = data; struct fib_iterator *fit = &tab->nhu_fit; int max_feed = 32; @@ -2702,7 +2663,7 @@ rt_next_hop_update(rtable *tab) if (max_feed <= 0) { FIB_ITERATE_PUT(fit); - ev_schedule(tab->rt_event); + ev_schedule(tab->nhu_event); return; } max_feed -= rt_next_hop_update_net(tab, n); @@ -2716,7 +2677,7 @@ rt_next_hop_update(rtable *tab) tab->nhu_state &= 1; if (tab->nhu_state != NHU_CLEAN) - ev_schedule(tab->rt_event); + ev_schedule(tab->nhu_event); } @@ -2738,6 +2699,7 @@ rt_new_table(struct symbol *s, uint addr_type) c->gc_min_time = 5; c->min_settle_time = 1 S; c->max_settle_time = 20 S; + c->config = new_config; add_tail(&new_config->tables, &c->n); @@ -2773,17 +2735,12 @@ rt_lock_table(rtable *r) void rt_unlock_table(rtable *r) { - if (!--r->use_count && r->deleted) - { - void *del_data = r->del_data; - void (*deleted)(void *) = r->deleted; - - /* Delete the routing table by freeing its pool */ - rt_shutdown(r); - deleted(del_data); - } + if (!--r->use_count && r->delete_event) + /* Delete the routing table by freeing its pool */ + ev_schedule(r->delete_event); } + static struct rtable_config * rt_find_table_config(struct config *cf, char *name) { @@ -2791,7 +2748,23 @@ rt_find_table_config(struct config *cf, char *name) return (sym && (sym->class == SYM_TABLE)) ? sym->table : NULL; } -static void rt_config_del_obstacle(void *data) { config_del_obstacle(data); } +static void +rt_done(void *data) +{ + rtable *t = data; + struct rtable_config *tc = t->config; + struct config *c = tc->config; + + tc->table = NULL; + rem_node(&t->n); + + if (t->hostcache) + rt_free_hostcache(t); + + rfree(t->rp); + + config_del_obstacle(c); +} /** * rt_commit - commit new routing table configuration @@ -2816,7 +2789,7 @@ rt_commit(struct config *new, struct config *old) WALK_LIST(o, old->tables) { rtable *ot = o->table; - if (!ot->deleted) + if (!ot->delete_event) { r = rt_find_table_config(new, o->name); if (r && (r->addr_type == o->addr_type) && !new->shutdown) @@ -2832,8 +2805,7 @@ rt_commit(struct config *new, struct config *old) { DBG("\t%s: deleted\n", o->name); rt_lock_table(ot); - ot->deleted = rt_config_del_obstacle; - ot->del_data = old; + ot->delete_event = ev_new_init(ot->rp, rt_done, ot); config_add_obstacle(old); rt_unlock_table(ot); } @@ -3060,11 +3032,11 @@ rt_free_hostcache(rtable *tab) static void rt_notify_hostcache(rtable *tab, net *net) { - if (tab->hcu_scheduled) + if (ev_active(tab->hcu_event)) return; if (trie_match_net(tab->hostcache->trie, net->n.addr)) - rt_schedule_hcu(tab); + ev_schedule(tab->hcu_event); } static int @@ -3161,8 +3133,9 @@ done: } static void -rt_update_hostcache(rtable *tab) +rt_update_hostcache(void *data) { + rtable *tab = data; struct hostcache *hc = tab->hostcache; struct hostentry *he; node *n, *x; @@ -3183,8 +3156,6 @@ rt_update_hostcache(rtable *tab) if (rt_update_hostentry(tab, he)) rt_schedule_nhu(he->tab); } - - tab->hcu_scheduled = 0; } struct hostentry * |