diff --git a/nest/rt-table.c b/nest/rt-table.c index 95248635..08d67331 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1432,6 +1432,14 @@ rt_announce_exports(timer *tm) } } +static void +rt_kick_announce_exports(void *_tab) +{ + RT_LOCKED((rtable *) _tab, tab) + if (!tm_active(tab->export_timer)) + tm_start(tab->export_timer, tab->config->export_settle_time); +} + static void rt_import_announce_exports(void *_hook) { @@ -1455,9 +1463,7 @@ rt_import_announce_exports(void *_hook) } rt_trace(tab, D_EVENTS, "Announcing exports after imports from %s", hook->req->name); - - if (!tm_active(tab->exporter.export_timer)) - tm_start(tab->exporter.export_timer, tab->config->export_settle_time); + ev_schedule(tab->export_event); } } @@ -2703,6 +2709,8 @@ rt_setup(pool *pp, struct rtable_config *cf) t->rt_event = ev_new_init(p, rt_event, t); t->nhu_event = ev_new_init(p, rt_next_hop_update, t); + t->export_event = ev_new_init(p, rt_kick_announce_exports, t); + t->export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0); t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0); t->last_rt_change = t->gc_time = current_time(); @@ -2712,7 +2720,6 @@ rt_setup(pool *pp, struct rtable_config *cf) .addr_type = t->addr_type, .rp = t->rp, }, - .export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0), .next_seq = 1, }; @@ -2852,8 +2859,8 @@ again: FIB_ITERATE_END; rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer"); - if (!tm_active(tab->exporter.export_timer)) - tm_start(tab->exporter.export_timer, tab->config->export_settle_time); + if (!tm_active(tab->export_timer)) + tm_start(tab->export_timer, tab->config->export_settle_time); #ifdef DEBUGGING fib_check(&tab->fib); @@ -3078,8 +3085,8 @@ done:; ev_schedule(tab->rt_event); - if (EMPTY_LIST(tab->exporter.pending) && tm_active(tab->exporter.export_timer)) - tm_stop(tab->exporter.export_timer); + if (EMPTY_LIST(tab->exporter.pending) && tm_active(tab->export_timer)) + tm_stop(tab->export_timer); } static void @@ -3704,8 +3711,8 @@ rt_next_hop_update(void *_tab) rt_trace(tab, D_STATES, "Next hop updater corked"); if ((tab->nhu_state & NHU_RUNNING) && !EMPTY_LIST(tab->exporter.pending) - && !tm_active(tab->exporter.export_timer)) - tm_start(tab->exporter.export_timer, tab->config->export_settle_time); + && !tm_active(tab->export_timer)) + tm_start(tab->export_timer, tab->config->export_settle_time); tab->nhu_corked = tab->nhu_state; tab->nhu_state = 0; @@ -3744,8 +3751,8 @@ rt_next_hop_update(void *_tab) /* Finished NHU, cleanup */ rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer"); - if (!tm_active(tab->exporter.export_timer)) - tm_start(tab->exporter.export_timer, tab->config->export_settle_time); + if (!tm_active(tab->export_timer)) + tm_start(tab->export_timer, tab->config->export_settle_time); /* State change: * NHU_DIRTY -> NHU_SCHEDULED diff --git a/nest/rt.h b/nest/rt.h index 3a8489e8..23231c0b 100644 --- a/nest/rt.h +++ b/nest/rt.h @@ -85,7 +85,6 @@ struct rt_exporter { struct rt_table_exporter { struct rt_exporter e; list pending; /* List of packed struct rt_pending_export */ - struct timer *export_timer; struct rt_pending_export *first; /* First export to announce */ u64 next_seq; /* The next export will have this ID */ @@ -129,6 +128,8 @@ struct rtable_private { */ struct event *rt_event; /* Routing table event */ struct event *nhu_event; /* Specific event for next hop update */ + struct event *export_event; /* Event for export batching */ + struct timer *export_timer; /* Timer for export batching */ struct timer *prune_timer; /* Timer for periodic pruning / GC */ btime last_rt_change; /* Last time when route changed */ btime gc_time; /* Time of last GC */