diff options
author | Neale Ranns <nranns@cisco.com> | 2020-05-29 10:19:41 -0400 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2020-05-29 20:27:06 +0000 |
commit | 22391fa92b95ee0376eb372450d6315523c8a9ae (patch) | |
tree | 298c9450f93ef39ccdc6d984c7be8a30cdc2edde /src/vnet | |
parent | adf6209cbeeaafce9d4b0a19cd50f74ba3699906 (diff) |
fib: Safe adj walk
Type: fix
the hash walk does not give the same guarantees as the bihash so
walk in a safe manner.
Change-Id: Idfe48c3a84ab3a341d887f7d196bc81ba34ae8b0
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/adj/adj_nbr.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/vnet/adj/adj_nbr.c b/src/vnet/adj/adj_nbr.c index 55c76bd86bf..78bf6df5324 100644 --- a/src/vnet/adj/adj_nbr.c +++ b/src/vnet/adj/adj_nbr.c @@ -554,21 +554,28 @@ adj_nbr_walk (u32 sw_if_index, adj_walk_cb_t cb, void *ctx) { + adj_index_t ai, *ais, *aip; adj_nbr_key_t *key; - adj_index_t ai; if (!ADJ_NBR_ITF_OK(adj_nh_proto, sw_if_index)) return; - if (adj_nbr_tables[adj_nh_proto][sw_if_index] || - hash_elts(adj_nbr_tables[adj_nh_proto][sw_if_index])) + ais = NULL; + + /* elements may be removed from the table during the walk, so + * collect the set first then process them */ + hash_foreach_mem (key, ai, adj_nbr_tables[adj_nh_proto][sw_if_index], + ({ + vec_add1(ais, ai); + })); + + vec_foreach(aip, ais) { - hash_foreach_mem (key, ai, adj_nbr_tables[adj_nh_proto][sw_if_index], - ({ - ASSERT(key); - cb(ai, ctx); - })); + /* An adj may be deleted during the walk so check first */ + if (!pool_is_free_index(adj_pool, *aip)) + cb(*aip, ctx); } + vec_free(ais); } /** |