summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vnet/vnet/fib/fib_path_list.c31
-rw-r--r--vnet/vnet/fib/fib_test.c43
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
@@ -2635,6 +2635,49 @@ fib_test_v4 (void)
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
* all of which are via 10.10.10.1, Itf1