fib: fix crash on exporter tracker remove 22/33822/3
authorVladislav Grishenko <themiron@yandex-team.ru>
Sat, 18 Sep 2021 12:32:17 +0000 (17:32 +0500)
committerNeale Ranns <neale@graphiant.com>
Mon, 27 Sep 2021 11:13:13 +0000 (11:13 +0000)
Exported entries are tracked only when the prefix found in the export
FIB is really attached, exporter tracker is not set if the export
entry is not valid for export, ex. for special FIB entries - default
route, zeronet, mcast and broadcast prefixes.
When imported entries need to be purged, such unset exporter tracker is
being removed by non-initialized index with absent delegate entries,
causing corresponding assert and crash.

Type: fix
Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
Change-Id: Ib24a2e7853a03a960577872480213e1e8097da5a

src/plugins/unittest/fib_test.c
src/vnet/fib/fib_attached_export.c

index f62f232..f5ee4ae 100644 (file)
@@ -5310,7 +5310,7 @@ fib_test_ae (void)
 {
     const dpo_id_t *dpo, *dpo_drop;
     const u32 fib_index = 0;
-    fib_node_index_t fei;
+    fib_node_index_t dfrt, fei;
     test_main_t *tm;
     ip4_main_t *im;
     int res;
@@ -5410,6 +5410,44 @@ fib_test_ae (void)
     import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
                                                           11,
                                                           FIB_SOURCE_CLI);
+    /*
+     * Add default route in the import FIB
+     */
+    fib_prefix_t pfx_0_0_0_0_s_0 = {
+        .fp_len = 0,
+        .fp_proto = FIB_PROTOCOL_IP4,
+        .fp_addr = {
+            .ip4 = {
+                {0}
+            },
+        },
+    };
+
+    dfrt = fib_table_lookup(import_fib_index1, &pfx_0_0_0_0_s_0);
+    FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
+
+    fib_table_entry_path_add(import_fib_index1,
+                             &pfx_0_0_0_0_s_0,
+                             FIB_SOURCE_API,
+                             FIB_ENTRY_FLAG_NONE,
+                             DPO_PROTO_IP4,
+                             NULL,
+                             tm->hw[0]->sw_if_index,
+                             ~0, // invalid fib index
+                             1,
+                             NULL,
+                             FIB_ROUTE_PATH_FLAG_NONE);
+    fei = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
+    FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "default route present");
+    FIB_TEST((fei != dfrt), "default route added");
+
+    /*
+     * delete default route and check for the presence in the import table
+     */
+    fib_table_entry_delete(import_fib_index1, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
+    fei = fib_table_lookup(import_fib_index1, &pfx_0_0_0_0_s_0);
+    FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "default route present");
+    FIB_TEST((fei == dfrt), "default route removed");
 
     /*
      * Add an attached route in the import FIB
index 5ea96fd..206d10e 100644 (file)
@@ -106,8 +106,7 @@ fib_entry_ae_add_or_lock (fib_node_index_t connected)
     {
         fed = fib_entry_delegate_find_or_add(entry,
                                              FIB_ENTRY_DELEGATE_ATTACHED_EXPORT);
-       pool_get(fib_ae_export_pool, export);
-       clib_memset(export, 0, sizeof(*export));
+       pool_get_zero(fib_ae_export_pool, export);
 
        fed->fd_index = (export - fib_ae_export_pool);
        export->faee_ei = connected;
@@ -249,13 +248,14 @@ fib_attached_export_import (fib_entry_t *fib_entry,
      */
     fei = fib_entry_get_index(fib_entry);
 
-    pool_get(fib_ae_import_pool, import);
+    pool_get_zero(fib_ae_import_pool, import);
 
     import->faei_import_fib = fib_entry->fe_fib_index;
     import->faei_export_fib = export_fib;
     import->faei_prefix = fib_entry->fe_prefix;
     import->faei_import_entry = fib_entry_get_index(fib_entry);
     import->faei_export_sibling = ~0;
+    import->faei_exporter = FIB_NODE_INDEX_INVALID;
 
     /*
      * do an exact match in the export table
@@ -273,7 +273,6 @@ fib_attached_export_import (fib_entry_t *fib_entry,
        import->faei_export_entry =
            fib_table_lookup(import->faei_export_fib,
                             &import->faei_prefix);
-       import->faei_exporter = FIB_NODE_INDEX_INVALID;
     }
     else
     {