diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2022-02-04 05:34:02 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2022-02-06 23:27:13 +0100 |
commit | 5a89edc6fd0b03716ccb77084e8d1a1910f52ab0 (patch) | |
tree | 9f2c066f1aab2cfbffb0d695e1050b8b39f20e0d /nest/rt-show.c | |
parent | de6318f70a06854a324b436b3a4cca0b3d60024b (diff) |
Nest: Implement locking of prefix tries during walks
The prune loop may may rebuild the prefix trie and therefore invalidate
walk state for asynchronous walks (used in 'show route in' cmd). Fix it
by adding locking that keeps the old trie in memory until current walks
are done.
In future this could be improved by rebuilding trie walk states (by
lookup for last found prefix) after the prefix trie rebuild.
Diffstat (limited to 'nest/rt-show.c')
-rw-r--r-- | nest/rt-show.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/nest/rt-show.c b/nest/rt-show.c index ea1f918c..f8b7ba51 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -222,6 +222,9 @@ rt_show_cleanup(struct cli *c) if (d->table_open && !d->trie_walk) fit_get(&d->tab->table->fib, &d->fit); + if (d->walk_lock) + rt_unlock_trie(d->tab->table, d->walk_lock); + /* Unlock referenced tables */ WALK_LIST(tab, d->tables) rt_unlock_table(tab->table); @@ -257,7 +260,10 @@ rt_show_cont(struct cli *c) d->walk_state = lp_allocz(c->parser_pool, sizeof (struct f_trie_walk_state)); if (d->trie_walk) + { + d->walk_lock = rt_lock_trie(tab); trie_walk_init(d->walk_state, tab->trie, d->addr); + } else FIB_ITERATE_INIT(&d->fit, &tab->fib); @@ -288,6 +294,9 @@ rt_show_cont(struct cli *c) if (!--max) return; } + + rt_unlock_trie(tab, d->walk_lock); + d->walk_lock = NULL; } else { |