diff options
-rw-r--r-- | doc/bird.sgml | 7 | ||||
-rw-r--r-- | nest/rt-table.c | 36 | ||||
-rw-r--r-- | nest/rt.h | 5 |
3 files changed, 26 insertions, 22 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 54d67e89..9399137c 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -699,6 +699,13 @@ to set options. threshold, the more memory can get used. In most cases, the defaults should work for you. Default: 128, 512. + <tag><label id="rtable-export-settle-time">export settle time <m/time/ <m/time/</tag> + Minimum and maximum settle times, respectively, for export announcements. + When multiple routes are changing, this mechanism waits for the changes + to settle before waking up sleeping export threads but if the changes are coming + steadily, BIRD isn't waiting forever; at most the maximum time. + Default values: <cf/1 ms 100 ms/. You have to always provide both values. + <tag><label id="rtable-debug">debug all|off|{ states|routes|events [, <m/.../] }</tag> Set table debugging options. Each table can write some trace messages into log with category <cf/trace/. You can request <cf/all/ trace messages diff --git a/nest/rt-table.c b/nest/rt-table.c index b8dc6866..051bc949 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1423,9 +1423,9 @@ rt_send_export_event(struct rt_export_hook *hook) } static void -rt_announce_exports(timer *tm) +rt_announce_exports(struct settle *s) { - RT_LOCKED((rtable *) tm->data, tab) + RT_LOCKED(RT_PUB(SKIP_BACK(struct rtable_private, export_settle, s)), tab) if (!EMPTY_LIST(tab->exporter.pending)) { struct rt_export_hook *c; node *n; @@ -1440,13 +1440,6 @@ rt_announce_exports(timer *tm) } static void -rt_kick_announce_exports(struct rtable_private *tab) -{ - if (!tm_active(tab->export_timer)) - tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop); -} - -static void rt_import_announce_exports(void *_hook) { struct rt_import_hook *hook = _hook; @@ -2521,7 +2514,7 @@ rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags) rt_next_hop_update(tab); if (flags & RTF_EXPORT) - rt_kick_announce_exports(tab); + settle_kick(&tab->export_settle, tab->loop); if (flags & RTF_CLEANUP) { @@ -2789,10 +2782,11 @@ rt_setup(pool *pp, struct rtable_config *cf) t->fh = (struct birdloop_flag_handler) { .hook = rt_flag_handler, }; t->nhu_uncork_event = ev_new_init(p, rt_nhu_uncork, 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(); + t->export_settle = SETTLE_INIT(&cf->export_settle, rt_announce_exports, NULL); + t->exporter = (struct rt_table_exporter) { .e = { .class = &rt_table_exporter_class, @@ -2944,8 +2938,7 @@ again: FIB_ITERATE_END; rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer"); - if (!tm_active(tab->export_timer)) - tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop); + settle_kick(&tab->export_settle, tab->loop); #ifdef DEBUGGING fib_check(&tab->fib); @@ -3172,7 +3165,7 @@ done:; birdloop_flag(tab->loop, RTF_CLEANUP); if (EMPTY_LIST(tab->exporter.pending)) - tm_stop(tab->export_timer); + settle_cancel(&tab->export_settle); } static void @@ -3806,9 +3799,8 @@ rt_next_hop_update(struct rtable_private *tab) { rt_trace(tab, D_STATES, "Next hop updater corked"); if ((tab->nhu_state & NHU_RUNNING) - && !EMPTY_LIST(tab->exporter.pending) - && !tm_active(tab->export_timer)) - tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop); + && !EMPTY_LIST(tab->exporter.pending)) + settle_kick(&tab->export_settle, tab->loop); tab->nhu_corked = tab->nhu_state; tab->nhu_state = 0; @@ -3846,9 +3838,7 @@ rt_next_hop_update(struct rtable_private *tab) /* Finished NHU, cleanup */ rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer"); - - if (!tm_active(tab->export_timer)) - tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop); + settle_kick(&tab->export_settle, tab->loop); /* State change: * NHU_DIRTY -> NHU_SCHEDULED @@ -3900,6 +3890,10 @@ rt_new_table(struct symbol *s, uint addr_type) c->gc_period = (uint) -1; /* set in rt_postconfig() */ c->cork_threshold.low = 128; c->cork_threshold.high = 512; + c->export_settle = (struct settle_config) { + .min = 1 MS, + .max = 100 MS, + }; c->debug = new_config->table_debug; add_tail(&new_config->tables, &c->n); @@ -4011,6 +4005,8 @@ rt_reconfigure(struct rtable_private *tab, struct rtable_config *new, struct rta tab->name = new->name; tab->config = new; + tab->export_settle.cf = new->export_settle; + if (tab->hostcache) tab->hostcache->req.trace_routes = new->debug; @@ -20,6 +20,7 @@ #include "lib/event.h" #include "lib/rcu.h" #include "lib/io-loop.h" +#include "lib/settle.h" #include <stdatomic.h> @@ -62,8 +63,8 @@ struct rtable_config { byte sorted; /* Routes of network are sorted according to rte_better() */ byte trie_used; /* Rtable has attached trie */ byte debug; /* Whether to log */ - btime export_settle_time; /* Delay before exports are announced */ struct rt_cork_threshold cork_threshold; /* Cork threshold values */ + struct settle_config export_settle; /* Export announcement settler */ }; struct rt_export_hook; @@ -129,7 +130,7 @@ struct rtable_private { * obstacle from this routing table. */ struct event *nhu_uncork_event; /* Helper event to schedule NHU on uncork */ - struct timer *export_timer; /* Timer for export batching */ + struct settle export_settle; /* Export batching settle timer */ struct timer *prune_timer; /* Timer for periodic pruning / GC */ struct birdloop_flag_handler fh; /* Handler for simple events */ btime last_rt_change; /* Last time when route changed */ |