diff options
author | Neale Ranns <nranns@cisco.com> | 2020-05-26 13:12:17 +0000 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2020-05-27 16:26:34 +0000 |
commit | aecb10b97fa97b215c415ceaa3cac4c97204922f (patch) | |
tree | b729a39bb1356554d61aeab6d2e6acd5c20ced13 /src/vnet | |
parent | af3022f0e88e07a62f1f6c3ec8e121e0d4de427f (diff) |
fib: IPv6 lookup data structure MP safe when prefixes change (VPP-1881)
Type: fix
adding routes should be MP safe. When new prefixes with differrent
prefix lengths are added, adjust the sorted list in an MP safe way.
Change-Id: Ib73a3c84d01eb86d17f8e79ea2bd2505dd9afb3d
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/fib/ip6_fib.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c index 784f52c0460..8de7e2a4f9b 100644 --- a/src/vnet/fib/ip6_fib.c +++ b/src/vnet/fib/ip6_fib.c @@ -248,14 +248,29 @@ ip6_fib_table_lookup_exact_match (u32 fib_index, static void compute_prefix_lengths_in_search_order (ip6_fib_table_instance_t *table) { + u8 *old, *prefix_lengths_in_search_order = NULL; int i; - vec_reset_length (table->prefix_lengths_in_search_order); + + /* + * build the list in a scratch space then cutover so the workers + * can continue uninterrupted. + */ + old = table->prefix_lengths_in_search_order; + /* Note: bitmap reversed so this is in fact a longest prefix match */ clib_bitmap_foreach (i, table->non_empty_dst_address_length_bitmap, ({ int dst_address_length = 128 - i; - vec_add1(table->prefix_lengths_in_search_order, dst_address_length); + vec_add1(prefix_lengths_in_search_order, dst_address_length); })); + + table->prefix_lengths_in_search_order = prefix_lengths_in_search_order; + + /* + * let the workers go once round the track before we free the old set + */ + vlib_worker_wait_one_loop(); + vec_free(old); } void @@ -311,12 +326,13 @@ ip6_fib_table_entry_insert (u32 fib_index, clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1); - table->dst_address_length_refcounts[len]++; - - table->non_empty_dst_address_length_bitmap = - clib_bitmap_set (table->non_empty_dst_address_length_bitmap, - 128 - len, 1); - compute_prefix_lengths_in_search_order (table); + if (0 == table->dst_address_length_refcounts[len]++) + { + table->non_empty_dst_address_length_bitmap = + clib_bitmap_set (table->non_empty_dst_address_length_bitmap, + 128 - len, 1); + compute_prefix_lengths_in_search_order (table); + } } u32 ip6_fib_table_fwding_lookup_with_if_index (ip6_main_t * im, @@ -363,12 +379,13 @@ ip6_fib_table_fwding_dpo_update (u32 fib_index, clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1); - table->dst_address_length_refcounts[len]++; - - table->non_empty_dst_address_length_bitmap = - clib_bitmap_set (table->non_empty_dst_address_length_bitmap, - 128 - len, 1); - compute_prefix_lengths_in_search_order (table); + if (0 == table->dst_address_length_refcounts[len]++) + { + table->non_empty_dst_address_length_bitmap = + clib_bitmap_set (table->non_empty_dst_address_length_bitmap, + 128 - len, 1); + compute_prefix_lengths_in_search_order (table); + } } void |