Trivial: Cleanup missing va_ends.
[vpp.git] / src / vnet / fib / fib_test.c
index e46f670..e26cc67 100644 (file)
@@ -212,7 +212,8 @@ fib_test_mk_intf (u32 ninterfaces)
 #define FIB_TEST_RPF(_cond, _comment, _args...)         \
     {                                                   \
         if (FIB_TEST_I(_cond, _comment, ##_args)) {     \
-            return (1);                                 \
+            res = 1;                                    \
+            goto cleanup;                               \
         }                                               \
     }
 
@@ -258,6 +259,7 @@ fib_test_urpf_is_equal (fib_node_index_t fei,
 
     dpo_reset(&dpo);
 
+cleanup:
     va_end(ap);
 
     return (res);
@@ -640,9 +642,9 @@ fib_test_validate_lb (const dpo_id_t *dpo,
     res = 0;
     va_start(ap, n_buckets);
 
-    if (FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
-                   "Entry links to %U",
-                   format_dpo_type, dpo->dpoi_type))
+    if (!FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
+                    "Entry links to %U",
+                    format_dpo_type, dpo->dpoi_type))
     {
         lb = load_balance_get(dpo->dpoi_index);
 
@@ -650,7 +652,7 @@ fib_test_validate_lb (const dpo_id_t *dpo,
     }
     else
     {
-        res = 0;
+        res = 1;
     }
 
     va_end(ap);
@@ -665,16 +667,15 @@ fib_test_validate_entry (fib_node_index_t fei,
                          ...)
 {
     dpo_id_t dpo = DPO_INVALID;
-    fib_prefix_t pfx;
+    const fib_prefix_t *pfx;
     index_t fw_lbi;
     u32 fib_index;
     va_list ap;
     int res;
 
-    va_start(ap, n_buckets);
 
     res = 0;
-    fib_entry_get_prefix(fei, &pfx);
+    pfx = fib_entry_get_prefix(fei);
     fib_index = fib_entry_get_fib_index(fei);
     fib_entry_contribute_forwarding(fei, fct, &dpo);
 
@@ -682,8 +683,10 @@ fib_test_validate_entry (fib_node_index_t fei,
     {
         const replicate_t *rep;
 
+        va_start(ap, n_buckets);
         rep = replicate_get(dpo.dpoi_index);
         res = fib_test_validate_rep_v(rep, n_buckets, &ap);
+        va_end (ap);
     }
     else
     {
@@ -691,11 +694,13 @@ fib_test_validate_entry (fib_node_index_t fei,
 
         FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
                     "%U Entry links to %U",
-                    format_fib_prefix, &pfx,
+                    format_fib_prefix, pfx,
                     format_dpo_type, dpo.dpoi_type);
 
+        va_start(ap, n_buckets);
         lb = load_balance_get(dpo.dpoi_index);
         res = fib_test_validate_lb_v(lb, n_buckets, &ap);
+        va_end(ap);
 
         /*
          * ensure that the LB contributed by the entry is the
@@ -703,13 +708,13 @@ fib_test_validate_entry (fib_node_index_t fei,
          */
         if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
         {
-            switch (pfx.fp_proto)
+            switch (pfx->fp_proto)
             {
             case FIB_PROTOCOL_IP4:
-                fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
+                fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx->fp_addr.ip4);
                 break;
             case FIB_PROTOCOL_IP6:
-                fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
+                fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx->fp_addr.ip6);
                 break;
             case FIB_PROTOCOL_MPLS:
                 {
@@ -717,8 +722,8 @@ fib_test_validate_entry (fib_node_index_t fei,
                         .label_exp_s_ttl = 0,
                     };
 
-                    vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
-                    vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
+                    vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx->fp_label);
+                    vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx->fp_eos);
                     hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
 
                     fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
@@ -736,8 +741,6 @@ fib_test_validate_entry (fib_node_index_t fei,
 
     dpo_reset(&dpo);
 
-    va_end(ap);
-
     return (res);
 }
 
@@ -851,9 +854,6 @@ fib_test_v4 (void)
     /*
      * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
      */
-    if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
-        PNBR += 2;
-
     FIB_TEST((0 == fib_path_list_db_size()),   "path list DB is empty");
     FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
              fib_path_list_pool_size());
@@ -4375,9 +4375,6 @@ fib_test_v6 (void)
     /*
      * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
      */
-    if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
-        PNPS += 2;
-
     FIB_TEST((0 == fib_path_list_db_size()),   "path list DB is empty");
     FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
              fib_path_list_pool_size());
@@ -8204,7 +8201,7 @@ fib_test_bfd (void)
     /*
      * whilst the BFD session is not signalled, the adj is up
      */
-    FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
+    FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on uninit session");
 
     /*
      * bring the BFD session up
@@ -8220,7 +8217,6 @@ fib_test_bfd (void)
     adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
     FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
 
-
     /*
      * add an attached next hop FIB entry via the down adj
      */
@@ -10125,6 +10121,330 @@ fib_test_inherit (void)
     return (res);
 }
 
+static int
+fib_test_sticky (void)
+{
+    fib_route_path_t *r_paths = NULL;
+    test_main_t *tm = &test_main;
+    u32 ii, lb_count, pl_count;
+    dpo_id_t dpo = DPO_INVALID;
+    fib_node_index_t pl_index;
+    int res = 0;
+#define N_PATHS 16
+
+    fib_test_lb_bucket_t buckets[N_PATHS];
+    bfd_session_t bfds[N_PATHS] = {{0}};
+
+    lb_count = pool_elts(load_balance_pool);
+    pl_count = fib_path_list_pool_size();
+
+    for (ii = 0; ii < N_PATHS; ii++)
+    {
+        ip46_address_t nh = {
+            .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
+        };
+        adj_index_t ai;
+
+        ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+                                 VNET_LINK_IP4,
+                                 &nh, tm->hw[0]->sw_if_index);
+
+        buckets[ii].type = FT_LB_ADJ;
+        buckets[ii].adj.adj = ai;
+
+        bfds[ii].udp.key.peer_addr = nh;
+        bfds[ii].udp.key.sw_if_index = tm->hw[0]->sw_if_index;
+        bfds[ii].hop_type = BFD_HOP_TYPE_SINGLE;
+        bfds[ii].local_state = BFD_STATE_init;
+        adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfds[ii]);
+        bfds[ii].local_state = BFD_STATE_up;
+        adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[ii]);
+    }
+
+    for (ii = 0; ii < N_PATHS; ii++)
+    {
+        fib_route_path_t r_path = {
+            .frp_proto = DPO_PROTO_IP4,
+            .frp_addr = {
+                .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
+            },
+            .frp_sw_if_index = tm->hw[0]->sw_if_index,
+            .frp_weight = 1,
+            .frp_fib_index = ~0,
+        };
+        vec_add1(r_paths, r_path);
+    };
+
+    pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths);
+    fib_path_list_lock(pl_index);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[0],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[3],
+                                   &buckets[4],
+                                   &buckets[5],
+                                   &buckets[6],
+                                   &buckets[7],
+                                   &buckets[8],
+                                   &buckets[9],
+                                   &buckets[10],
+                                   &buckets[11],
+                                   &buckets[12],
+                                   &buckets[13],
+                                   &buckets[14],
+                                   &buckets[15]),
+             "Setup OK");
+
+    /* take down paths */
+    bfds[0].local_state = BFD_STATE_down;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[3],
+                                   &buckets[4],
+                                   &buckets[5],
+                                   &buckets[6],
+                                   &buckets[7],
+                                   &buckets[8],
+                                   &buckets[9],
+                                   &buckets[10],
+                                   &buckets[11],
+                                   &buckets[12],
+                                   &buckets[13],
+                                   &buckets[14],
+                                   &buckets[15]),
+             "Failed at shut-down path 0");
+
+    bfds[7].local_state = BFD_STATE_down;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[3],
+                                   &buckets[4],
+                                   &buckets[5],
+                                   &buckets[6],
+                                   &buckets[2],
+                                   &buckets[8],
+                                   &buckets[9],
+                                   &buckets[10],
+                                   &buckets[11],
+                                   &buckets[12],
+                                   &buckets[13],
+                                   &buckets[14],
+                                   &buckets[15]),
+             "Failed at shut-down path 7");
+
+    /* paths back up */
+    bfds[0].local_state = BFD_STATE_up;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
+    bfds[7].local_state = BFD_STATE_up;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[0],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[3],
+                                   &buckets[4],
+                                   &buckets[5],
+                                   &buckets[6],
+                                   &buckets[7],
+                                   &buckets[8],
+                                   &buckets[9],
+                                   &buckets[10],
+                                   &buckets[11],
+                                   &buckets[12],
+                                   &buckets[13],
+                                   &buckets[14],
+                                   &buckets[15]),
+             "recovery OK");
+
+    fib_path_list_unlock(pl_index);
+
+    /*
+     * non-power of 2 number of buckets
+     */
+    fib_route_path_t *r_paths2 = NULL;
+
+    r_paths2 = vec_dup(r_paths);
+    _vec_len(r_paths2) = 3;
+
+    pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths2);
+    fib_path_list_lock(pl_index);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2]),
+             "non-power of 2");
+
+    bfds[1].local_state = BFD_STATE_down;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    /*
+     * path 1's buckets alternate between path 0 and 2
+     */
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[2],
+                                   &buckets[0],
+                                   &buckets[2],
+                                   &buckets[0],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2]),
+             "non-power of 2");
+    bfds[1].local_state = BFD_STATE_up;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
+
+    fib_path_list_unlock(pl_index);
+
+    /*
+     * unequal cost
+     */
+    fib_route_path_t *r_paths3 = NULL;
+
+    r_paths3 = vec_dup(r_paths);
+    _vec_len(r_paths3) = 3;
+
+    r_paths3[0].frp_weight = 3;
+
+    pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths3);
+    fib_path_list_lock(pl_index);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[1],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0]),
+             "UCMP");
+
+    bfds[1].local_state = BFD_STATE_down;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
+
+    fib_path_list_contribute_forwarding(pl_index,
+                                        FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+                                        FIB_PATH_LIST_FWD_FLAG_STICKY,
+                                        &dpo);
+    /* No attempt to Un-equal distribute the down path's buckets */
+    FIB_TEST(!fib_test_validate_lb(&dpo,
+                                   16,
+                                   &buckets[2],
+                                   &buckets[0],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[2],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0],
+                                   &buckets[0]),
+             "UCMP");
+    bfds[1].local_state = BFD_STATE_up;
+    adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
+
+    dpo_reset(&dpo);
+    fib_path_list_unlock(pl_index);
+
+    vec_free(r_paths);
+    vec_free(r_paths2);
+    vec_free(r_paths3);
+
+    FIB_TEST(lb_count == pool_elts(load_balance_pool), "no leaked LBs");
+    FIB_TEST(pl_count == fib_path_list_pool_size(), "no leaked PLs");
+
+    return 0;
+}
+
 static clib_error_t *
 fib_test (vlib_main_t * vm,
           unformat_input_t * input,
@@ -10182,6 +10502,10 @@ fib_test (vlib_main_t * vm,
     {
         res += fib_test_inherit();
     }
+    else if (unformat (input, "sticky"))
+    {
+        res += fib_test_sticky();
+    }
     else
     {
         res += fib_test_v4();