summaryrefslogtreecommitdiff
path: root/nest/rt-show.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-07-12 10:36:10 +0200
committerMaria Matejka <mq@ucw.cz>2022-07-12 12:22:41 +0200
commit080cbd1219ba86dd44712d0d24ceae884b34ec4b (patch)
tree86bf2e0153ab7365224d454b145e1ae5fac6c1d6 /nest/rt-show.c
parent4ef2262bd575b071e43c30d0199398a5f6ac27a5 (diff)
Route refresh in tables uses a stale counter.
Until now, we were marking routes as REF_STALE and REF_DISCARD to cleanup old routes after route refresh. This needed a synchronous route table walk at both beginning and the end of route refresh routine, marking the routes by the flags. We avoid these walks by using a stale counter. Every route contains: u8 stale_cycle; Every import hook contains: u8 stale_set; u8 stale_valid; u8 stale_pruned; u8 stale_pruning; In base_state, stale_set == stale_valid == stale_pruned == stale_pruning and all routes' stale_cycle also have the same value. The route refresh looks like follows: + ----------- + --------- + ----------- + ------------- + ------------ + | | stale_set | stale_valid | stale_pruning | stale_pruned | | Base | x | x | x | x | | Begin | x+1 | x | x | x | ... now routes are being inserted with stale_cycle == (x+1) | End | x+1 | x+1 | x | x | ... now table pruning routine is scheduled | Prune begin | x+1 | x+1 | x+1 | x | ... now routes with stale_cycle not between stale_set and stale_valid are deleted | Prune end | x+1 | x+1 | x+1 | x+1 | + ----------- + --------- + ----------- + ------------- + ------------ + The pruning routine is asynchronous and may have high latency in high-load environments. Therefore, multiple route refresh requests may happen before the pruning routine starts, leading to this situation: | Prune begin | x+k | x+k | x -> x+k | x | ... or even | Prune begin | x+k+1 | x+k | x -> x+k | x | ... if the prune event starts while another route refresh is running. In such a case, the pruning routine still deletes routes not fitting between stale_set and and stale_valid, effectively pruning the remnants of all unpruned route refreshes from before: | Prune end | x+k | x+k | x+k | x+k | In extremely rare cases, there may happen too many route refreshes before any route prune routine finishes. If the difference between stale_valid and stale_pruned becomes more than 128 when requesting for another route refresh, the routine walks the table synchronously and resets all the stale values to a base state, while logging a warning.
Diffstat (limited to 'nest/rt-show.c')
-rw-r--r--nest/rt-show.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/nest/rt-show.c b/nest/rt-show.c
index c3294518..dd0fe595 100644
--- a/nest/rt-show.c
+++ b/nest/rt-show.c
@@ -77,7 +77,11 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
e->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info);
if (d->verbose)
+ {
ea_show_list(c, a);
+ cli_printf(c, -1008, "\tInternal route handling values: %uL %uG %uS",
+ e->src->private_id, e->src->global_id, e->stale_cycle);
+ }
else if (dest == RTD_UNICAST)
ea_show_nexthop_list(c, nhad);
else if (had)