FIB table add/delete API
[vpp.git] / src / vnet / mfib / mfib_test.c
index 8082a6b..3055844 100644 (file)
 #include <vnet/mfib/mfib_entry.h>
 #include <vnet/mfib/mfib_signal.h>
 #include <vnet/mfib/ip6_mfib.h>
+#include <vnet/fib/fib_path_list.h>
+#include <vnet/fib/fib_test.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/fib/mpls_fib.h>
 
 #include <vnet/dpo/replicate_dpo.h>
 #include <vnet/adj/adj_mcast.h>
@@ -200,8 +204,8 @@ mfib_test_validate_rep_v (const replicate_t *rep,
         if (DPO_RECEIVE != dt)
         {
             MFIB_TEST_REP((ai == dpo->dpoi_index),
-                          "bucket %d stacks on %U",
-                          bucket,
+                          "bucket %d [exp:%d] stacks on %U",
+                          bucket, ai,
                           format_dpo_id, dpo, 0);
         }
     }
@@ -337,7 +341,7 @@ mfib_test_i (fib_protocol_t PROTO,
              const mfib_prefix_t *pfx_star_g_slash_m)
 {
     fib_node_index_t mfei, mfei_dflt, mfei_no_f, mfei_s_g, mfei_g_1, mfei_g_2, mfei_g_3, mfei_g_m;
-    u32 fib_index, n_entries, n_itfs, n_reps;
+    u32 fib_index, n_entries, n_itfs, n_reps, n_pls;
     fib_node_index_t ai_1, ai_2, ai_3;
     test_main_t *tm;
 
@@ -347,6 +351,7 @@ mfib_test_i (fib_protocol_t PROTO,
     n_entries = pool_elts(mfib_entry_pool);
     n_itfs = pool_elts(mfib_itf_pool);
     n_reps = pool_elts(replicate_pool);
+    n_pls = fib_path_list_pool_size();
     tm = &test_main;
 
     ai_1 = adj_mcast_add_or_lock(PROTO,
@@ -362,7 +367,7 @@ mfib_test_i (fib_protocol_t PROTO,
     MFIB_TEST(3 == adj_mcast_db_size(), "3 MCAST adjs");
 
     /* Find or create FIB table 11 */
-    fib_index = mfib_table_find_or_create_and_lock(PROTO, 11);
+    fib_index = mfib_table_find_or_create_and_lock(PROTO, 11, MFIB_SOURCE_API);
 
     mfib_prefix_t pfx_dft = {
         .fp_len = 0,
@@ -383,7 +388,7 @@ mfib_test_i (fib_protocol_t PROTO,
 
 
     fib_route_path_t path_via_if0 = {
-        .frp_proto = PROTO,
+        .frp_proto = fib_proto_to_dpo(PROTO),
         .frp_addr = zero_addr,
         .frp_sw_if_index = tm->hw[0]->sw_if_index,
         .frp_fib_index = ~0,
@@ -407,7 +412,7 @@ mfib_test_i (fib_protocol_t PROTO,
                                      MFIB_ITF_FLAG_ACCEPT));
 
     fib_route_path_t path_via_if1 = {
-        .frp_proto = PROTO,
+        .frp_proto = fib_proto_to_dpo(PROTO),
         .frp_addr = zero_addr,
         .frp_sw_if_index = tm->hw[1]->sw_if_index,
         .frp_fib_index = ~0,
@@ -415,7 +420,7 @@ mfib_test_i (fib_protocol_t PROTO,
         .frp_flags = 0,
     };
     fib_route_path_t path_via_if2 = {
-        .frp_proto = PROTO,
+        .frp_proto = fib_proto_to_dpo(PROTO),
         .frp_addr = zero_addr,
         .frp_sw_if_index = tm->hw[2]->sw_if_index,
         .frp_fib_index = ~0,
@@ -423,7 +428,7 @@ mfib_test_i (fib_protocol_t PROTO,
         .frp_flags = 0,
     };
     fib_route_path_t path_via_if3 = {
-        .frp_proto = PROTO,
+        .frp_proto = fib_proto_to_dpo(PROTO),
         .frp_addr = zero_addr,
         .frp_sw_if_index = tm->hw[3]->sw_if_index,
         .frp_fib_index = ~0,
@@ -431,7 +436,7 @@ mfib_test_i (fib_protocol_t PROTO,
         .frp_flags = 0,
     };
     fib_route_path_t path_for_us = {
-        .frp_proto = PROTO,
+        .frp_proto = fib_proto_to_dpo(PROTO),
         .frp_addr = zero_addr,
         .frp_sw_if_index = 0xffffffff,
         .frp_fib_index = ~0,
@@ -732,6 +737,7 @@ mfib_test_i (fib_protocol_t PROTO,
     mfib_table_entry_update(fib_index,
                             pfx_s_g,
                             MFIB_SOURCE_API,
+                            MFIB_RPF_ID_NONE,
                             MFIB_ENTRY_FLAG_SIGNAL);
     MFIB_TEST(mfib_test_entry(mfei,
                               MFIB_ENTRY_FLAG_SIGNAL,
@@ -822,6 +828,7 @@ mfib_test_i (fib_protocol_t PROTO,
     mfib_table_entry_update(fib_index,
                             pfx_s_g,
                             MFIB_SOURCE_API,
+                            MFIB_RPF_ID_NONE,
                             (MFIB_ENTRY_FLAG_SIGNAL |
                              MFIB_ENTRY_FLAG_CONNECTED));
     MFIB_TEST(mfib_test_entry(mfei,
@@ -963,6 +970,7 @@ mfib_test_i (fib_protocol_t PROTO,
     mfib_table_entry_update(fib_index,
                             pfx_s_g,
                             MFIB_SOURCE_API,
+                            MFIB_RPF_ID_NONE,
                             MFIB_ENTRY_FLAG_NONE);
     mfei = mfib_table_lookup_exact_match(fib_index,
                                          pfx_s_g);
@@ -1023,10 +1031,170 @@ mfib_test_i (fib_protocol_t PROTO,
               "%U Gone",
               format_mfib_prefix, pfx_star_g_slash_m);
 
+    /*
+     * Add a prefix as a special/exclusive route
+     */
+    dpo_id_t td = DPO_INVALID;
+    index_t repi = replicate_create(1, fib_proto_to_dpo(PROTO));
+
+    dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_2);
+    replicate_set_bucket(repi, 0, &td);
+
+    mfei = mfib_table_entry_special_add(fib_index,
+                                        pfx_star_g_3,
+                                        MFIB_SOURCE_SRv6,
+                                        MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
+                                        repi);
+    MFIB_TEST(mfib_test_entry(mfei,
+                              (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
+                               MFIB_ENTRY_FLAG_EXCLUSIVE),
+                              1,
+                              DPO_ADJACENCY_MCAST, ai_2),
+              "%U exclusive replicate OK",
+              format_mfib_prefix, pfx_star_g_3);
+
+    /*
+     * update a special/exclusive route
+     */
+    index_t repi2 = replicate_create(1, fib_proto_to_dpo(PROTO));
+
+    dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_1);
+    replicate_set_bucket(repi2, 0, &td);
+
+    mfei = mfib_table_entry_special_add(fib_index,
+                                        pfx_star_g_3,
+                                        MFIB_SOURCE_SRv6,
+                                        MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
+                                        repi2);
+    MFIB_TEST(mfib_test_entry(mfei,
+                              (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
+                               MFIB_ENTRY_FLAG_EXCLUSIVE),
+                              1,
+                              DPO_ADJACENCY_MCAST, ai_1),
+              "%U exclusive update replicate OK",
+              format_mfib_prefix, pfx_star_g_3);
+
+    mfib_table_entry_delete(fib_index,
+                            pfx_star_g_3,
+                            MFIB_SOURCE_SRv6);
+    dpo_reset(&td);
+
+    /*
+     * A Multicast LSP. This a mLDP head-end
+     */
+    fib_node_index_t ai_mpls_10_10_10_1, lfei;
+    ip46_address_t nh_10_10_10_1 = {
+       .ip4 = {
+           .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
+       },
+    };
+    ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                             VNET_LINK_MPLS,
+                                             &nh_10_10_10_1,
+                                             tm->hw[0]->sw_if_index);
+
+    fib_prefix_t pfx_3500 = {
+       .fp_len = 21,
+       .fp_proto = FIB_PROTOCOL_MPLS,
+       .fp_label = 3500,
+       .fp_eos = MPLS_EOS,
+       .fp_payload_proto = DPO_PROTO_IP4,
+    };
+    fib_test_rep_bucket_t mc_0 = {
+        .type = FT_REP_LABEL_O_ADJ,
+       .label_o_adj = {
+           .adj = ai_mpls_10_10_10_1,
+           .label = 3300,
+           .eos = MPLS_EOS,
+       },
+    };
+    mpls_label_t *l3300 = NULL;
+    vec_add1(l3300, 3300);
+
+    /*
+     * MPLS enable an interface so we get the MPLS table created
+     */
+    mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
+    mpls_sw_interface_enable_disable(&mpls_main,
+                                     tm->hw[0]->sw_if_index,
+                                     1, 0);
+
+    lfei = fib_table_entry_update_one_path(0, // default MPLS Table
+                                           &pfx_3500,
+                                           FIB_SOURCE_API,
+                                           FIB_ENTRY_FLAG_MULTICAST,
+                                           DPO_PROTO_IP4,
+                                           &nh_10_10_10_1,
+                                           tm->hw[0]->sw_if_index,
+                                           ~0, // invalid fib index
+                                           1,
+                                           l3300,
+                                           FIB_ROUTE_PATH_FLAG_NONE);
+    MFIB_TEST(fib_test_validate_entry(lfei,
+                                      FIB_FORW_CHAIN_TYPE_MPLS_EOS,
+                                      1,
+                                      &mc_0),
+              "3500 via replicate over 10.10.10.1");
+
+    /*
+     * An (S,G) that resolves via the mLDP head-end
+     */
+    fib_route_path_t path_via_mldp = {
+        .frp_proto = DPO_PROTO_MPLS,
+        .frp_local_label = pfx_3500.fp_label,
+        .frp_eos = MPLS_EOS,
+        .frp_sw_if_index = 0xffffffff,
+        .frp_fib_index = 0,
+        .frp_weight = 1,
+        .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
+    };
+    dpo_id_t mldp_dpo = DPO_INVALID;
+
+    fib_entry_contribute_forwarding(lfei,
+                                    FIB_FORW_CHAIN_TYPE_MPLS_EOS,
+                                    &mldp_dpo);
+
+    mfei = mfib_table_entry_path_update(fib_index,
+                                        pfx_s_g,
+                                        MFIB_SOURCE_API,
+                                        &path_via_mldp,
+                                        MFIB_ITF_FLAG_FORWARD);
+
+    MFIB_TEST(mfib_test_entry(mfei,
+                              MFIB_ENTRY_FLAG_NONE,
+                              1,
+                              DPO_REPLICATE, mldp_dpo.dpoi_index),
+              "%U over-mLDP replicate OK",
+              format_mfib_prefix, pfx_s_g);
+
+    /*
+     * add a for-us path. this tests two types of non-attached paths on one entry
+     */
+    mfei = mfib_table_entry_path_update(fib_index,
+                                        pfx_s_g,
+                                        MFIB_SOURCE_API,
+                                        &path_for_us,
+                                        MFIB_ITF_FLAG_FORWARD);
+    MFIB_TEST(mfib_test_entry(mfei,
+                              MFIB_ENTRY_FLAG_NONE,
+                              2,
+                              DPO_REPLICATE, mldp_dpo.dpoi_index,
+                              DPO_RECEIVE, 0),
+              "%U mLDP+for-us replicate OK",
+              format_mfib_prefix, pfx_s_g);
+
+    mfib_table_entry_delete(fib_index,
+                            pfx_s_g,
+                            MFIB_SOURCE_API);
+    fib_table_entry_delete(0,
+                           &pfx_3500,
+                           FIB_SOURCE_API);
+    dpo_reset(&mldp_dpo);
+
     /*
      * Unlock the table - it's the last lock so should be gone thereafter
      */
-    mfib_table_unlock(fib_index, PROTO);
+    mfib_table_unlock(fib_index, PROTO, MFIB_SOURCE_API);
 
     MFIB_TEST((FIB_NODE_INDEX_INVALID ==
                mfib_table_find(PROTO, fib_index)),
@@ -1036,10 +1204,20 @@ mfib_test_i (fib_protocol_t PROTO,
     adj_unlock(ai_2);
     adj_unlock(ai_3);
 
+    /*
+     * MPLS disable the interface
+     */
+    mpls_sw_interface_enable_disable(&mpls_main,
+                                     tm->hw[0]->sw_if_index,
+                                     0, 0);
+    mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
+
     /*
      * test we've leaked no resources
      */
     MFIB_TEST(0 == adj_mcast_db_size(), "%d MCAST adjs", adj_mcast_db_size());
+    MFIB_TEST(n_pls == fib_path_list_pool_size(), "%d=%d path-lists",
+              n_pls, fib_path_list_pool_size());
     MFIB_TEST(n_reps == pool_elts(replicate_pool), "%d=%d replicates",
               n_reps, pool_elts(replicate_pool));
     MFIB_TEST(n_entries == pool_elts(mfib_entry_pool),
@@ -1214,7 +1392,7 @@ mfib_test (vlib_main_t * vm,
 
 VLIB_CLI_COMMAND (test_fib_command, static) = {
     .path = "test mfib",
-    .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
+    .short_help = "mfib unit tests - DO NOT RUN ON A LIVE SYSTEM",
     .function = mfib_test,
 };