Crash when adding duplicate paths 92/3692/2
authorNeale Ranns <nranns@cisco.com>
Thu, 3 Nov 2016 21:15:28 +0000 (14:15 -0700)
committerDave Barach <openvpp@barachs.net>
Thu, 3 Nov 2016 22:15:15 +0000 (22:15 +0000)
Change-Id: Icd29c9013ae70f5444eb940aff4f08589e755f48
Signed-off-by: Neale Ranns <nranns@cisco.com>
vnet/vnet/fib/fib_path_list.c
vnet/vnet/fib/fib_test.c

index 5cd5096..4d695d6 100644 (file)
@@ -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
index 49fc318..78b9ec4 100644 (file)
@@ -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