diff options
-rw-r--r-- | doc/bird.sgml | 8 | ||||
-rw-r--r-- | nest/config.Y | 4 | ||||
-rw-r--r-- | nest/rt-table.c | 32 | ||||
-rw-r--r-- | nest/rt.h | 5 |
4 files changed, 42 insertions, 7 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 9399137c..0cfe19c4 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -706,6 +706,14 @@ to set options. 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-route-refresh-export-settle-time">route refresh export settle time <m/time/ <m/time/</tag> + Minimum and maximum settle times, respectively, for export announcements + (the same as above), valid when any channel is currently doing a route refresh. + This serves a purpose of even more aggresive change bundling, knowing that there + is some active process generating changes in a fast pace. If you don't want + this feature, set this to the same values as <ref id="rtable-export-settle-time" name="export settle time">. + Default values: <cf/100 ms 3 s/. + <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/config.Y b/nest/config.Y index a8e48cfe..f2904882 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -125,7 +125,7 @@ CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US) CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, AS) CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE) CF_KEYWORDS(CHECK, LINK) -CF_KEYWORDS(CORK, SORTED, TRIE, MIN, MAX, ROA, SETTLE, TIME, GC, THRESHOLD, PERIOD) +CF_KEYWORDS(CORK, SORTED, TRIE, MIN, MAX, ROA, ROUTE, REFRESH, SETTLE, TIME, GC, THRESHOLD, PERIOD) /* For r_args_channel */ CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC) @@ -233,6 +233,8 @@ table_opt: if ($3 > $4) cf_error("Cork low threshold must be lower than the high threshold."); this_table->cork_threshold.low = $3; this_table->cork_threshold.high = $4; } + | EXPORT SETTLE TIME settle { this_table->export_settle = $4; } + | ROUTE REFRESH EXPORT SETTLE TIME settle { this_table->export_rr_settle = $6; } | DEBUG bool { this_table->debug = $2; } ; diff --git a/nest/rt-table.c b/nest/rt-table.c index 7a21dc39..36d69d92 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -1440,6 +1440,13 @@ rt_announce_exports(struct settle *s) } static void +rt_kick_export_settle(struct rtable_private *tab) +{ + tab->export_settle.cf = tab->rr_counter ? tab->config->export_rr_settle : tab->config->export_settle; + settle_kick(&tab->export_settle, tab->loop); +} + +static void rt_import_announce_exports(void *_hook) { struct rt_import_hook *hook = _hook; @@ -2039,6 +2046,13 @@ rt_stop_import(struct rt_import_request *req, void (*stopped)(struct rt_import_r rt_schedule_prune(tab); rt_set_import_state(hook, TIS_STOP); hook->stopped = stopped; + + if (hook->stale_set != hook->stale_pruned) + tab->rr_counter -= (hook->stale_set - hook->stale_pruned - 1); + else + tab->rr_counter++; + + hook->stale_set = hook->stale_pruned = hook->stale_pruning = hook->stale_valid = 0; } } @@ -2301,6 +2315,7 @@ rt_refresh_begin(struct rt_import_request *req) e->rte.stale_cycle = 0; } FIB_WALK_END; + tab->rr_counter -= (hook->stale_set - hook->stale_pruned - 1); hook->stale_set = 1; hook->stale_valid = 0; hook->stale_pruned = 0; @@ -2311,6 +2326,7 @@ rt_refresh_begin(struct rt_import_request *req) /* Let's reserve the stale_cycle zero value for always-invalid routes */ hook->stale_set = 1; hook->stale_valid = 0; + tab->rr_counter++; } if (req->trace_routes & D_STATES) @@ -2514,7 +2530,7 @@ rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags) rt_next_hop_update(tab); if (flags & RTF_EXPORT) - settle_kick(&tab->export_settle, tab->loop); + rt_kick_export_settle(tab); if (flags & RTF_CLEANUP) { @@ -2947,7 +2963,7 @@ again: FIB_ITERATE_END; rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer"); - settle_kick(&tab->export_settle, tab->loop); + rt_kick_export_settle(tab); #ifdef DEBUGGING fib_check(&tab->fib); @@ -2997,9 +3013,11 @@ again: ih->flush_seq = tab->exporter.next_seq; rt_set_import_state(ih, TIS_WAITING); flushed_channels++; + tab->rr_counter--; } else if (ih->stale_pruning != ih->stale_pruned) { + tab->rr_counter -= (ih->stale_pruned - ih->stale_pruning); ih->stale_pruned = ih->stale_pruning; if (ih->req->trace_routes & D_STATES) log(L_TRACE "%s: table prune after refresh end [%u]", ih->req->name, ih->stale_pruned); @@ -3809,7 +3827,7 @@ 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)) - settle_kick(&tab->export_settle, tab->loop); + rt_kick_export_settle(tab); tab->nhu_corked = tab->nhu_state; tab->nhu_state = 0; @@ -3847,7 +3865,7 @@ rt_next_hop_update(struct rtable_private *tab) /* Finished NHU, cleanup */ rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer"); - settle_kick(&tab->export_settle, tab->loop); + rt_kick_export_settle(tab); /* State change: * NHU_DIRTY -> NHU_SCHEDULED @@ -3903,6 +3921,10 @@ rt_new_table(struct symbol *s, uint addr_type) .min = 1 MS, .max = 100 MS, }; + c->export_rr_settle = (struct settle_config) { + .min = 100 MS, + .max = 3 S, + }; c->debug = new_config->table_debug; add_tail(&new_config->tables, &c->n); @@ -4014,8 +4036,6 @@ 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; @@ -65,6 +65,8 @@ struct rtable_config { byte debug; /* Whether to log */ struct rt_cork_threshold cork_threshold; /* Cork threshold values */ struct settle_config export_settle; /* Export announcement settler */ + struct settle_config export_rr_settle;/* Export announcement settler config valid when any + route refresh is running */ }; struct rt_export_hook; @@ -136,6 +138,9 @@ struct rtable_private { btime last_rt_change; /* Last time when route changed */ btime gc_time; /* Time of last GC */ uint gc_counter; /* Number of operations since last GC */ + uint rr_counter; /* Number of currently running route refreshes, + in fact sum of (stale_set - stale_pruned) over all importers + + one for each TIS_FLUSHING importer */ byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */ byte prune_trie; /* Prune prefix trie during next table prune */ byte nhu_state; /* Next Hop Update state */ |