aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2020-05-29 10:19:41 -0400
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-06-03 17:52:01 +0000
commit4e4d3fd016473cbac0cae4505a6aabec07108de5 (patch)
tree1612dc6315c4ebce36212677bf51d2ac5eae716b
parent5e69119cdda353988cbd138665193231daf271c9 (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> (cherry picked from commit 22391fa92b95ee0376eb372450d6315523c8a9ae)
-rw-r--r--src/vnet/adj/adj_nbr.c23
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);
}
/**