X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_test.c;h=e26cc674a88be3b77f2cf554989d119f6adc7310;hb=609e121;hp=56e885ccdaf38c068fa2a0eda862ea8798cb474c;hpb=2303cb181b51f63c909cd506125c1f832432865a;p=vpp.git diff --git a/src/vnet/fib/fib_test.c b/src/vnet/fib/fib_test.c index 56e885ccdaf..e26cc674a88 100644 --- a/src/vnet/fib/fib_test.c +++ b/src/vnet/fib/fib_test.c @@ -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); @@ -526,11 +528,11 @@ fib_test_validate_lb_v (const load_balance_t *lb, } break; case FT_LB_ADJ: - FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) || - (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); + res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) || + (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index), "bucket %d stacks on adj %d", bucket, @@ -540,7 +542,7 @@ fib_test_validate_lb_v (const load_balance_t *lb, { const mpls_disp_dpo_t *mdd; - FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type), + res = FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); @@ -549,11 +551,11 @@ fib_test_validate_lb_v (const load_balance_t *lb, dpo = &mdd->mdd_dpo; - FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) || - (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); + res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) || + (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index), "bucket %d stacks on adj %d", bucket, @@ -561,30 +563,30 @@ fib_test_validate_lb_v (const load_balance_t *lb, break; } case FT_LB_INTF: - FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); + res = FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index), "bucket %d stacks on adj %d", bucket, exp->adj.adj); break; case FT_LB_L2: - FIB_TEST_I((DPO_DVR == dpo->dpoi_type), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); + res = FIB_TEST_I((DPO_DVR == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index), "bucket %d stacks on adj %d", bucket, exp->adj.adj); break; case FT_LB_O_LB: - FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); + res = FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index), "bucket %d stacks on lb %d not %d", bucket, @@ -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();