From bcc889cd0892a4dba9a06fc3c0ba49356c7220a4 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 3 Nov 2016 14:15:28 -0700 Subject: [PATCH] Crash when adding duplicate paths Change-Id: Icd29c9013ae70f5444eb940aff4f08589e755f48 Signed-off-by: Neale Ranns --- vnet/vnet/fib/fib_path_list.c | 31 +++++++++++++++++++++++-------- vnet/vnet/fib/fib_test.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/vnet/vnet/fib/fib_path_list.c b/vnet/vnet/fib/fib_path_list.c index 5cd5096b7d8..4d695d63d51 100644 --- a/vnet/vnet/fib/fib_path_list.c +++ b/vnet/vnet/fib/fib_path_list.c @@ -762,8 +762,9 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index, fib_path_list_flags_t flags, const fib_route_path_t *rpaths) { - fib_node_index_t path_index, path_list_index, *orig_path_index; + fib_node_index_t path_index, new_path_index, *orig_path_index; fib_path_list_t *path_list, *orig_path_list; + fib_node_index_t path_list_index; fib_node_index_t pi; ASSERT(1 == vec_len(rpaths)); @@ -784,16 +785,30 @@ fib_path_list_copy_and_path_add (fib_node_index_t orig_path_list_index, vec_validate(path_list->fpl_paths, vec_len(orig_path_list->fpl_paths)); pi = 0; + new_path_index = fib_path_create(path_list_index, + path_list->fpl_nh_proto, + fib_path_list_flags_2_path_flags(flags), + rpaths); + vec_foreach (orig_path_index, orig_path_list->fpl_paths) { - path_index = fib_path_copy(*orig_path_index, path_list_index); - path_list->fpl_paths[pi++] = path_index; + /* + * don't add duplicate paths + * In the unlikely event the path is a duplicate, then we'll + * find a matching path-list later and this one will be toast. + */ + if (0 != fib_path_cmp(new_path_index, *orig_path_index)) + { + path_index = fib_path_copy(*orig_path_index, path_list_index); + path_list->fpl_paths[pi++] = path_index; + } + else + { + _vec_len(path_list->fpl_paths) = vec_len(orig_path_list->fpl_paths); + } } - path_index = fib_path_create(path_list_index, - path_list->fpl_nh_proto, - fib_path_list_flags_2_path_flags(flags), - rpaths); - path_list->fpl_paths[pi] = path_index; + + path_list->fpl_paths[pi] = new_path_index; /* * we sort the paths since the key for the path-list is diff --git a/vnet/vnet/fib/fib_test.c b/vnet/vnet/fib/fib_test.c index 49fc318cbb7..78b9ec49c11 100644 --- a/vnet/vnet/fib/fib_test.c +++ b/vnet/vnet/fib/fib_test.c @@ -2634,6 +2634,49 @@ fib_test_v4 (void) FIB_TEST((NBR+7 == fib_entry_pool_size()), "entry pool size is %d", fib_entry_pool_size()); + /* + * Duplicate paths: + * add a recursive with duplicate paths. Expect the duplicate to be ignored. + */ + fib_prefix_t pfx_34_1_1_1_s_32 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0x22010101), + }, + }; + fib_prefix_t pfx_34_34_1_1_s_32 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0x22220101), + }, + }; + fei = fib_table_entry_path_add(fib_index, + &pfx_34_1_1_1_s_32, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_NONE, + FIB_PROTOCOL_IP4, + &pfx_34_34_1_1_s_32.fp_addr, + ~0, + fib_index, + 1, + MPLS_LABEL_INVALID, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_entry_path_add(fib_index, + &pfx_34_1_1_1_s_32, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_NONE, + FIB_PROTOCOL_IP4, + &pfx_34_34_1_1_s_32.fp_addr, + ~0, + fib_index, + 1, + MPLS_LABEL_INVALID, + FIB_ROUTE_PATH_FLAG_NONE); + FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0); + fib_table_entry_delete_index(fei, FIB_SOURCE_API); + /* * CLEANUP * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32 -- 2.16.6