X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_test.c;h=8f7bba0369a9b40b34bd02d1362277172bf2d16f;hb=31ed744;hp=03c9ee75f48c160977e554bcfe512b61c8d79c51;hpb=6f6311560380d0e992f710558e213df1b098ef94;p=vpp.git diff --git a/src/vnet/fib/fib_test.c b/src/vnet/fib/fib_test.c index 03c9ee75f48..8f7bba0369a 100644 --- a/src/vnet/fib/fib_test.c +++ b/src/vnet/fib/fib_test.c @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include #include #include @@ -27,7 +28,8 @@ #include #include #include -#include +#include +#include #include @@ -299,7 +301,8 @@ fib_test_validate_rep_v (const replicate_t *rep, { const mpls_label_dpo_t *mld; mpls_label_t hdr; - FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type), + FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE) + == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); @@ -353,7 +356,7 @@ fib_test_validate_rep_v (const replicate_t *rep, int fib_test_validate_lb_v (const load_balance_t *lb, - u16 n_buckets, + int n_buckets, va_list *ap) { const dpo_id_t *dpo; @@ -373,14 +376,19 @@ fib_test_validate_lb_v (const load_balance_t *lb, case FT_LB_LABEL_STACK_O_ADJ: { const mpls_label_dpo_t *mld; + mpls_label_dpo_flags_t mf; mpls_label_t hdr; u32 ii; - FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type), + mf = ((exp->label_stack_o_adj.mode == + FIB_MPLS_LSP_MODE_UNIFORM) ? + MPLS_LABEL_DPO_FLAG_UNIFORM_MODE : + MPLS_LABEL_DPO_FLAG_NONE); + FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); - + mld = mpls_label_dpo_get(dpo->dpoi_index); FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels, @@ -431,7 +439,8 @@ fib_test_validate_lb_v (const load_balance_t *lb, { const mpls_label_dpo_t *mld; mpls_label_t hdr; - FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type), + FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE) + == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); @@ -466,13 +475,18 @@ fib_test_validate_lb_v (const load_balance_t *lb, case FT_LB_LABEL_O_LB: { const mpls_label_dpo_t *mld; + mpls_label_dpo_flags_t mf; mpls_label_t hdr; - FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type), + mf = ((exp->label_o_lb.mode == + FIB_MPLS_LSP_MODE_UNIFORM) ? + MPLS_LABEL_DPO_FLAG_UNIFORM_MODE : + MPLS_LABEL_DPO_FLAG_NONE); + FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); - + mld = mpls_label_dpo_get(dpo->dpoi_index); hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl); @@ -513,6 +527,30 @@ fib_test_validate_lb_v (const load_balance_t *lb, bucket, exp->adj.adj); break; + case FT_LB_MPLS_DISP_PIPE_O_ADJ: + { + const mpls_disp_dpo_t *mdd; + + FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); + + mdd = mpls_disp_dpo_get(dpo->dpoi_index); + + 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); + FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index), + "bucket %d stacks on adj %d", + bucket, + exp->adj.adj); + break; + } case FT_LB_INTF: FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type), "bucket %d stacks on %U", @@ -524,7 +562,7 @@ fib_test_validate_lb_v (const load_balance_t *lb, exp->adj.adj); break; case FT_LB_L2: - FIB_TEST_I((DPO_L2_BRIDGE == dpo->dpoi_type), + FIB_TEST_I((DPO_DVR == dpo->dpoi_type), "bucket %d stacks on %U", bucket, format_dpo_type, dpo->dpoi_type); @@ -544,25 +582,70 @@ fib_test_validate_lb_v (const load_balance_t *lb, dpo->dpoi_index, exp->lb.lb); break; - case FT_LB_SPECIAL: - FIB_TEST_I((DPO_DROP == dpo->dpoi_type), - "bucket %d stacks on %U", - bucket, - format_dpo_type, dpo->dpoi_type); - FIB_TEST_LB((exp->special.adj == dpo->dpoi_index), - "bucket %d stacks on drop %d", + case FT_LB_BIER_TABLE: + FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); + FIB_TEST_LB((exp->bier.table == dpo->dpoi_index), + "bucket %d stacks on lb %d", + bucket, + exp->bier.table); + break; + case FT_LB_BIER_FMASK: + FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); + FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index), + "bucket %d stacks on lb %d", bucket, - exp->special.adj); + exp->bier.fmask); + break; + case FT_LB_DROP: + FIB_TEST_LB((DPO_DROP == dpo->dpoi_type), + "bucket %d stacks on %U", + bucket, + format_dpo_type, dpo->dpoi_type); break; } } return (!0); } +int +fib_test_validate_lb (const dpo_id_t *dpo, + int n_buckets, + ...) +{ + const load_balance_t *lb; + va_list ap; + int res; + + 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)) + { + lb = load_balance_get(dpo->dpoi_index); + + res = fib_test_validate_lb_v(lb, n_buckets, &ap); + } + else + { + res = !0; + } + + va_end(ap); + + return (res); +} + int fib_test_validate_entry (fib_node_index_t fei, fib_forward_chain_type_t fct, - u16 n_buckets, + int n_buckets, ...) { dpo_id_t dpo = DPO_INVALID; @@ -590,7 +673,8 @@ fib_test_validate_entry (fib_node_index_t fei, const load_balance_t *lb; FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type), - "Entry links to %U", + "%U Entry links to %U", + format_fib_prefix, &pfx, format_dpo_type, dpo.dpoi_type); lb = load_balance_get(dpo.dpoi_index); @@ -627,7 +711,7 @@ fib_test_validate_entry (fib_node_index_t fei, fw_lbi = 0; } FIB_TEST_LB((fw_lbi == dpo.dpoi_index), - "Contributed LB = FW LB: %U\n %U", + "Contributed LB = FW LB:\n fwd:%U\n cont:%U", format_load_balance, fw_lbi, 0, format_load_balance, dpo.dpoi_index, 0); } @@ -3543,6 +3627,49 @@ fib_test_v4 (void) "4.4.4.4/32 is deag in %d %U", lkd->lkd_fib_index, format_dpo_id, dpo, 0); + FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input), + "4.4.4.4/32 is source deag in %d %U", + lkd->lkd_input, + format_dpo_id, dpo, 0); + + fib_table_entry_delete(fib_index, + &pfx_4_4_4_4_s_32, + FIB_SOURCE_API); + FIB_TEST(FIB_NODE_INDEX_INVALID == + fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32), + "4.4.4.4/32 removed"); + vec_free(r_paths); + + /* + * A route deag route in a source lookup table + */ + fib_table_entry_path_add(fib_index, + &pfx_4_4_4_4_s_32, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_NONE, + DPO_PROTO_IP4, + &zero_addr, + ~0, + fib_index, + 1, + NULL, + FIB_ROUTE_PATH_SOURCE_LOOKUP); + + fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32); + FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present"); + + dpo = fib_entry_contribute_ip_forwarding(fei); + dpo = load_balance_get_bucket(dpo->dpoi_index, 0); + lkd = lookup_dpo_get(dpo->dpoi_index); + + FIB_TEST((fib_index == lkd->lkd_fib_index), + "4.4.4.4/32 is deag in %d %U", + lkd->lkd_fib_index, + format_dpo_id, dpo, 0); + FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input), + "4.4.4.4/32 is source deag in %d %U", + lkd->lkd_input, + format_dpo_id, dpo, 0); fib_table_entry_delete(fib_index, &pfx_4_4_4_4_s_32, @@ -4002,25 +4129,25 @@ fib_test_v4 (void) format_ip_flow_hash_config, lb->lb_hash_config); /* - * A route via an L2 Bridge + * A route via DVR DPO */ fei = fib_table_entry_path_add(fib_index, &pfx_10_10_10_3_s_32, FIB_SOURCE_API, FIB_ENTRY_FLAG_NONE, - DPO_PROTO_ETHERNET, + DPO_PROTO_IP4, &zero_addr, tm->hw[0]->sw_if_index, ~0, 1, NULL, - FIB_ROUTE_PATH_FLAG_NONE); - dpo_id_t l2_dpo = DPO_INVALID; - l2_bridge_dpo_add_or_lock(tm->hw[0]->sw_if_index, &l2_dpo); + FIB_ROUTE_PATH_DVR); + dpo_id_t dvr_dpo = DPO_INVALID; + dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo); fib_test_lb_bucket_t ip_o_l2 = { .type = FT_LB_L2, .adj = { - .adj = l2_dpo.dpoi_index, + .adj = dvr_dpo.dpoi_index, }, }; @@ -4032,13 +4159,13 @@ fib_test_v4 (void) fib_table_entry_path_remove(fib_index, &pfx_10_10_10_3_s_32, FIB_SOURCE_API, - DPO_PROTO_ETHERNET, + DPO_PROTO_IP4, &zero_addr, tm->hw[0]->sw_if_index, fib_index, 1, - FIB_ROUTE_PATH_FLAG_NONE); - dpo_reset(&l2_dpo); + FIB_ROUTE_PATH_DVR); + dpo_reset(&dvr_dpo); /* * CLEANUP @@ -4139,8 +4266,8 @@ fib_test_v4 (void) pool_elts(load_balance_map_pool)); FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d", pool_elts(load_balance_pool)); - FIB_TEST((0 == pool_elts(l2_bridge_dpo_pool)), "L2 DPO pool size is %d", - pool_elts(l2_bridge_dpo_pool)); + FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d", + pool_elts(dvr_dpo_pool)); return 0; } @@ -6217,8 +6344,10 @@ fib_test_label (void) .eos = MPLS_NON_EOS, }, }; - mpls_label_t *l99 = NULL; - vec_add1(l99, 99); + fib_mpls_label_t *l99 = NULL, fml99 = { + .fml_value = 99, + }; + vec_add1(l99, fml99); fib_table_entry_update_one_path(fib_index, &pfx_1_1_1_1_s_32, @@ -6256,8 +6385,10 @@ fib_test_label (void) .adj = ai_mpls_10_10_11_1, }, }; - mpls_label_t *l_imp_null = NULL; - vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL); + fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = { + .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL, + }; + vec_add1(l_imp_null, fml_imp_null); fei = fib_table_entry_path_add(fib_index, &pfx_1_1_1_1_s_32, @@ -6297,6 +6428,12 @@ fib_test_label (void) .fp_label = 24001, .fp_eos = MPLS_NON_EOS, }; + fib_test_lb_bucket_t disp_o_10_10_11_1 = { + .type = FT_LB_MPLS_DISP_PIPE_O_ADJ, + .adj = { + .adj = ai_v4_10_10_11_1, + }, + }; /* * The EOS entry should link to both the paths, @@ -6310,10 +6447,10 @@ fib_test_label (void) FIB_FORW_CHAIN_TYPE_MPLS_EOS, 2, &l99_eos_o_10_10_10_1, - &a_o_10_10_11_1), + &disp_o_10_10_11_1), "24001/eos LB 2 buckets via: " "label 99 over 10.10.10.1, " - "adj over 10.10.11.1"); + "mpls disp adj over 10.10.11.1"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, @@ -6336,6 +6473,13 @@ fib_test_label (void) .adj = ai_v4_10_10_11_2, }, }; + fib_test_lb_bucket_t disp_o_10_10_11_2 = { + .type = FT_LB_MPLS_DISP_PIPE_O_ADJ, + .adj = { + .adj = ai_v4_10_10_11_2, + }, + }; + fei = fib_table_entry_path_add(fib_index, &pfx_1_1_1_1_s_32, @@ -6412,24 +6556,27 @@ fib_test_label (void) .lb = non_eos_1_1_1_1.dpoi_index, .label = 1600, .eos = MPLS_EOS, + .mode = FIB_MPLS_LSP_MODE_UNIFORM, }, }; - mpls_label_t *l1600 = NULL; - vec_add1(l1600, 1600); + fib_mpls_label_t *l1600 = NULL, fml1600 = { + .fml_value = 1600, + .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM, + }; + vec_add1(l1600, fml1600); - fib_table_entry_update_one_path(fib_index, - &pfx_2_2_2_2_s_32, - FIB_SOURCE_API, - FIB_ENTRY_FLAG_NONE, - DPO_PROTO_IP4, - &pfx_1_1_1_1_s_32.fp_addr, - ~0, - fib_index, - 1, - l1600, - FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_entry_update_one_path(fib_index, + &pfx_2_2_2_2_s_32, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_NONE, + DPO_PROTO_IP4, + &pfx_1_1_1_1_s_32.fp_addr, + ~0, + fib_index, + 1, + l1600, + FIB_ROUTE_PATH_FLAG_NONE); - fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32); FIB_TEST(fib_test_validate_entry(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, @@ -6484,11 +6631,11 @@ fib_test_label (void) FIB_TEST(fib_test_validate_entry(fei, FIB_FORW_CHAIN_TYPE_MPLS_EOS, 2, - &a_o_10_10_11_1, - &adj_o_10_10_11_2), + &disp_o_10_10_11_1, + &disp_o_10_10_11_2), "24001/eos LB 2 buckets via: " - "adj over 10.10.11.1, ", - "adj-v4 over 10.10.11.2"); + "mpls-disp adj over 10.10.11.1, ", + "mpls-disp adj-v4 over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_24001_neos); @@ -6561,20 +6708,20 @@ fib_test_label (void) &l99_eos_o_10_10_10_1, &l99_eos_o_10_10_10_1, &l99_eos_o_10_10_10_1, - &a_o_10_10_11_1, - &a_o_10_10_11_1, - &a_o_10_10_11_1, - &a_o_10_10_11_1, - &a_o_10_10_11_1, - &adj_o_10_10_11_2, - &adj_o_10_10_11_2, - &adj_o_10_10_11_2, - &adj_o_10_10_11_2, - &adj_o_10_10_11_2), + &disp_o_10_10_11_1, + &disp_o_10_10_11_1, + &disp_o_10_10_11_1, + &disp_o_10_10_11_1, + &disp_o_10_10_11_1, + &disp_o_10_10_11_2, + &disp_o_10_10_11_2, + &disp_o_10_10_11_2, + &disp_o_10_10_11_2, + &disp_o_10_10_11_2), "24001/eos LB 16 buckets via: " "label 99 over 10.10.10.1, " - "adj over 10.10.11.1", - "adj-v4 over 10.10.11.2"); + "MPLS disp adj over 10.10.11.1", + "MPLS disp adj-v4 over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_24001_neos); @@ -6615,11 +6762,11 @@ fib_test_label (void) FIB_TEST(fib_test_validate_entry(fei, FIB_FORW_CHAIN_TYPE_MPLS_EOS, 2, - &a_o_10_10_11_1, - &adj_o_10_10_11_2), + &disp_o_10_10_11_1, + &disp_o_10_10_11_2), "24001/eos LB 2 buckets via: " - "adj over 10.10.11.1, " - "adj-v4 over 10.10.11.2"); + "MPLS disp adj over 10.10.11.1, " + "MPLS disp adj-v4 over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_24001_neos); @@ -6635,13 +6782,10 @@ fib_test_label (void) * remove the other path with a valid label */ fib_test_lb_bucket_t bucket_drop = { - .type = FT_LB_SPECIAL, - .special = { - .adj = DPO_PROTO_IP4, - }, + .type = FT_LB_DROP, }; fib_test_lb_bucket_t mpls_bucket_drop = { - .type = FT_LB_SPECIAL, + .type = FT_LB_DROP, .special = { .adj = DPO_PROTO_MPLS, }, @@ -6670,9 +6814,9 @@ fib_test_label (void) FIB_TEST(fib_test_validate_entry(fei, FIB_FORW_CHAIN_TYPE_MPLS_EOS, 1, - &adj_o_10_10_11_2), + &disp_o_10_10_11_2), "24001/eos LB 1 buckets via: " - "adj over 10.10.11.2"); + "MPLS disp adj over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_24001_neos); @@ -6686,7 +6830,7 @@ fib_test_label (void) * add back the path with the valid label */ l99 = NULL; - vec_add1(l99, 99); + vec_add1(l99, fml99); fib_table_entry_path_add(fib_index, &pfx_1_1_1_1_s_32, @@ -6716,10 +6860,10 @@ fib_test_label (void) FIB_FORW_CHAIN_TYPE_MPLS_EOS, 2, &l99_eos_o_10_10_10_1, - &adj_o_10_10_11_2), + &disp_o_10_10_11_2), "24001/eos LB 2 buckets via: " "label 99 over 10.10.10.1, " - "adj over 10.10.11.2"); + "MPLS disp adj over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_24001_neos); @@ -6761,10 +6905,10 @@ fib_test_label (void) FIB_FORW_CHAIN_TYPE_MPLS_EOS, 2, &l99_eos_o_10_10_10_1, - &adj_o_10_10_11_2), + &disp_o_10_10_11_2), "25005/eos LB 2 buckets via: " "label 99 over 10.10.10.1, " - "adj over 10.10.11.2"); + "MPLS disp adj over 10.10.11.2"); fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID, &pfx_25005_neos); @@ -6816,8 +6960,10 @@ fib_test_label (void) .eos = MPLS_EOS, }, }; - mpls_label_t *l101 = NULL; - vec_add1(l101, 101); + fib_mpls_label_t *l101 = NULL, fml101 = { + .fml_value = 101, + }; + vec_add1(l101, fml101); fei = fib_table_entry_update_one_path(fib_index, &pfx_1_1_1_2_s_32, @@ -6856,8 +7002,10 @@ fib_test_label (void) .eos = MPLS_EOS, }, }; - mpls_label_t *l1601 = NULL; - vec_add1(l1601, 1601); + fib_mpls_label_t *l1601 = NULL, fml1601 = { + .fml_value = 1601, + }; + vec_add1(l1601, fml1601); l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index; @@ -6887,7 +7035,7 @@ fib_test_label (void) * the LB for the recursive can use an imp-null */ l_imp_null = NULL; - vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL); + vec_add1(l_imp_null, fml_imp_null); fei = fib_table_entry_update_one_path(fib_index, &pfx_1_1_1_2_s_32, @@ -7051,11 +7199,11 @@ fib_test_label (void) .eos = MPLS_EOS, }, }; - mpls_label_t *label_stack = NULL; + fib_mpls_label_t *label_stack = NULL; vec_validate(label_stack, 7); for (ii = 0; ii < 8; ii++) { - label_stack[ii] = ii + 200; + label_stack[ii].fml_value = ii + 200; } fei = fib_table_entry_update_one_path(fib_index, @@ -8130,12 +8278,13 @@ static int lfib_test (void) { const mpls_label_t deag_label = 50; + dpo_id_t dpo = DPO_INVALID; + const mpls_disp_dpo_t *mdd; const u32 lfib_index = 0; const u32 fib_index = 0; - dpo_id_t dpo = DPO_INVALID; + const lookup_dpo_t *lkd; const dpo_id_t *dpo1; fib_node_index_t lfe; - lookup_dpo_t *lkd; test_main_t *tm; int lb_count; adj_index_t ai_mpls_10_10_10_1; @@ -8202,7 +8351,6 @@ lfib_test (void) format_mpls_eos_bit, MPLS_EOS, format_dpo_proto, lkd->lkd_proto); - /* * A route deag route for EOS */ @@ -8233,7 +8381,14 @@ lfib_test (void) FIB_FORW_CHAIN_TYPE_MPLS_EOS, &dpo); dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0); - lkd = lookup_dpo_get(dpo1->dpoi_index); + mdd = mpls_disp_dpo_get(dpo1->dpoi_index); + + FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode), + "%U/%U disp is pipe mode", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS); + + lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index); FIB_TEST((fib_index == lkd->lkd_fib_index), "%U/%U is deag in %d %U", @@ -8258,6 +8413,70 @@ lfib_test (void) "%U/%U not present", format_mpls_unicast_label, deag_label, format_mpls_eos_bit, MPLS_EOS); + dpo_reset(&dpo); + + /* + * A route deag route for EOS with LSP mode uniform + */ + fib_mpls_label_t *l_pops = NULL, l_pop = { + .fml_value = MPLS_LABEL_POP, + .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM, + }; + vec_add1(l_pops, l_pop); + lfe = fib_table_entry_path_add(lfib_index, + &pfx, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_NONE, + DPO_PROTO_IP4, + &zero_addr, + ~0, + fib_index, + 1, + l_pops, + FIB_ROUTE_PATH_FLAG_NONE); + + FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)), + "%U/%U present", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS); + + fib_entry_contribute_forwarding(lfe, + FIB_FORW_CHAIN_TYPE_MPLS_EOS, + &dpo); + dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0); + mdd = mpls_disp_dpo_get(dpo1->dpoi_index); + + FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode), + "%U/%U disp is uniform mode", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS); + + lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index); + + FIB_TEST((fib_index == lkd->lkd_fib_index), + "%U/%U is deag in %d %U", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS, + lkd->lkd_fib_index, + format_dpo_id, &dpo, 0); + FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input), + "%U/%U is dst deag", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS); + FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto), + "%U/%U is %U dst deag", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS, + format_dpo_proto, lkd->lkd_proto); + + fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI); + + FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index, + &pfx)), + "%U/%U not present", + format_mpls_unicast_label, deag_label, + format_mpls_eos_bit, MPLS_EOS); + dpo_reset(&dpo); /* * A route deag route for non-EOS @@ -8335,11 +8554,15 @@ lfib_test (void) }; dpo_id_t neos_1200 = DPO_INVALID; dpo_id_t ip_1200 = DPO_INVALID; - mpls_label_t *l200 = NULL; - vec_add1(l200, 200); - vec_add1(l200, 300); - vec_add1(l200, 400); - vec_add1(l200, 500); + fib_mpls_label_t *l200 = NULL; + u32 ii; + for (ii = 0; ii < 4; ii++) + { + fib_mpls_label_t fml = { + .fml_value = 200 + (ii * 100), + }; + vec_add1(l200, fml); + }; lfe = fib_table_entry_update_one_path(fib_index, &pfx_1200, @@ -8398,8 +8621,10 @@ lfib_test (void) .ip4.as_u32 = clib_host_to_net_u32(0x02020204), }, }; - mpls_label_t *l999 = NULL; - vec_add1(l999, 999); + fib_mpls_label_t *l999 = NULL, fml_999 = { + .fml_value = 999, + }; + vec_add1(l999, fml_999); rpaths[0].frp_label_stack = l999, fib_table_entry_path_add2(fib_index, @@ -8454,13 +8679,13 @@ lfib_test (void) * A recursive via a label that does not exist */ fib_test_lb_bucket_t bucket_drop = { - .type = FT_LB_SPECIAL, + .type = FT_LB_DROP, .special = { .adj = DPO_PROTO_IP4, }, }; fib_test_lb_bucket_t mpls_bucket_drop = { - .type = FT_LB_SPECIAL, + .type = FT_LB_DROP, .special = { .adj = DPO_PROTO_MPLS, }, @@ -8565,8 +8790,10 @@ lfib_test (void) .adj = idpo.dpoi_index, }, }; - mpls_label_t *l3300 = NULL; - vec_add1(l3300, 3300); + fib_mpls_label_t *l3300 = NULL, fml_3300 = { + .fml_value = 3300, + }; + vec_add1(l3300, fml_3300); lfe = fib_table_entry_update_one_path(lfib_index, &pfx_3500, @@ -8647,6 +8874,9 @@ lfib_test (void) 0, 1); mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API); + FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool), + "mpls_disp_dpo resources freed %d of %d", + 0, pool_elts(mpls_disp_dpo_pool)); FIB_TEST(lb_count == pool_elts(load_balance_pool), "Load-balance resources freed %d of %d", lb_count, pool_elts(load_balance_pool)); @@ -8657,34 +8887,824 @@ lfib_test (void) return (0); } -static clib_error_t * -fib_test (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd_arg) +static int +fib_test_inherit (void) { - int res; + fib_node_index_t fei; + test_main_t *tm; + int n_feis; - res = 0; - fib_test_mk_intf(4); + n_feis = fib_entry_pool_size(); + tm = &test_main; - if (unformat (input, "debug")) - { - fib_test_do_debug = 1; - } + const ip46_address_t nh_10_10_10_1 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01), + }; + const ip46_address_t nh_10_10_10_2 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02), + }; + const ip46_address_t nh_10_10_10_16 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10), + }; + const ip46_address_t nh_10_10_10_20 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14), + }; + const ip46_address_t nh_10_10_10_21 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15), + }; + const ip46_address_t nh_10_10_10_22 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16), + }; + const ip46_address_t nh_10_10_10_255 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff), + }; + const ip46_address_t nh_10_10_10_0 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00), + }; + const ip46_address_t nh_10_10_0_0 = { + .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000), + }; - if (unformat (input, "ip")) - { - res += fib_test_v4(); - res += fib_test_v6(); - } - else if (unformat (input, "label")) - { - res += fib_test_label(); - } - else if (unformat (input, "ae")) - { - res += fib_test_ae(); - } + /* + * prefixes at the base of a sub-tree + */ + const fib_prefix_t pfx_10_10_10_21_s_32 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_21, + }; + const fib_prefix_t pfx_10_10_10_22_s_32 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_22, + }; + const fib_prefix_t pfx_10_10_10_255_s_32 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_255, + }; + + fib_table_entry_special_add(0, + &pfx_10_10_10_21_s_32, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + fib_table_entry_special_add(0, + &pfx_10_10_10_22_s_32, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + fib_table_entry_special_add(0, + &pfx_10_10_10_255_s_32, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + + /* + * source an entry that pushes its state down the sub-tree + */ + const fib_prefix_t pfx_10_10_10_16_s_28 = { + .fp_len = 28, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_16, + }; + fib_table_entry_update_one_path(0, + &pfx_10_10_10_16_s_28, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + + /* + * this covering entry and all those below it should have + * the same forwarding information. + */ + adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4, + VNET_LINK_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index); + fib_test_lb_bucket_t adj_o_10_10_10_1 = { + .type = FT_LB_ADJ, + .adj = { + .adj = ai_10_10_10_1, + }, + }; + + fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_16_s_28); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_255_s_32); + + /* + * remove the inherting cover - covereds go back to drop + */ + fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API); + + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_21_s_32); + + /* + * source an entry that pushes its state down the sub-tree + */ + const fib_prefix_t pfx_10_10_10_0_s_24 = { + .fp_len = 24, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_0, + }; + fib_table_entry_update_one_path(0, + &pfx_10_10_10_0_s_24, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + + /* + * whole sub-tree now covered + */ + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_0_s_24); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_255_s_32); + + /* + * insert a more specific into the sub-tree - expect inheritance + * this one is directly covered by the root + */ + fib_table_entry_special_add(0, + &pfx_10_10_10_16_s_28, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_16_s_28); + + /* + * insert a more specific into the sub-tree - expect inheritance + * this one is indirectly covered by the root + */ + const fib_prefix_t pfx_10_10_10_20_s_30 = { + .fp_len = 30, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_10_20, + }; + fib_table_entry_special_add(0, + &pfx_10_10_10_20_s_30, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_20_s_30); + + /* + * remove the prefix from the middle of the sub-tree + * the inherited source will be the only one remaining - expect + * it to be withdrawn and hence the prefix is removed. + */ + fib_table_entry_special_remove(0, + &pfx_10_10_10_20_s_30, + FIB_SOURCE_CLI); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30); + FIB_TEST((FIB_NODE_INDEX_INVALID == fei), + "%U gone", + format_fib_prefix, &pfx_10_10_10_20_s_30); + + /* + * inheriting source is modifed - expect the modification to be present + * throughout the sub-tree + */ + adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4, + VNET_LINK_IP4, + &nh_10_10_10_2, + tm->hw[0]->sw_if_index); + fib_test_lb_bucket_t adj_o_10_10_10_2 = { + .type = FT_LB_ADJ, + .adj = { + .adj = ai_10_10_10_2, + }, + }; + + fib_table_entry_update_one_path(0, + &pfx_10_10_10_0_s_24, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_2, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_0_s_24); + + /* + * add the source that replaces inherited state. + * inheriting source is not the best, so it doesn't push state. + */ + fib_table_entry_update_one_path(0, + &pfx_10_10_10_0_s_24, + FIB_SOURCE_PLUGIN_HI, + FIB_ENTRY_FLAG_NONE, + DPO_PROTO_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_0_s_24); + + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_10_10_10_16_s_28); + + /* + * withdraw the higher priority source and expect the inherited to return + * throughout the sub-tree + */ + fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI); + + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_0_s_24); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_16_s_28); + + /* + * source a covered entry in the sub-tree with the same inherting source + * - expect that it now owns the sub-tree and thus over-rides its cover + */ + fib_table_entry_update_one_path(0, + &pfx_10_10_10_16_s_28, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_16_s_28); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_21_s_32); + + /* these two unaffected by the sub-tree change */ + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_0_s_24); + + /* + * removes the more specific, expect the /24 to now re-owns the sub-tree + */ + fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API); + + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_10_0_s_24); + /* + * modify the /24. expect the new forwarding to be pushed down + */ + fib_table_entry_update_one_path(0, + &pfx_10_10_10_0_s_24, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_0_s_24); + + /* + * add an entry less specific to /24. it should not own the /24's tree + */ + const fib_prefix_t pfx_10_10_0_0_s_16 = { + .fp_len = 16, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_addr = nh_10_10_0_0, + }; + fib_table_entry_update_one_path(0, + &pfx_10_10_0_0_s_16, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP4, + &nh_10_10_10_2, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_16_s_28); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_21_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_22_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_255_s_32); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_1), + "%U via 10.10.10.1", + format_fib_prefix, &pfx_10_10_10_0_s_24); + fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP4, + 1, + &adj_o_10_10_10_2), + "%U via 10.10.10.2", + format_fib_prefix, &pfx_10_10_0_0_s_16); + + /* + * cleanup + */ + fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API); + fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API); + adj_unlock(ai_10_10_10_1); + adj_unlock(ai_10_10_10_2); + + /* + * test the v6 tree walk. + * a /64 that covers everytinhg. a /96 that covers one /128 + * a second /128 covered only by the /64. + */ + const fib_prefix_t pfx_2001_s_64 = { + .fp_len = 64, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x2001000000000000), + [1] = clib_host_to_net_u64(0x0000000000000000), + }, + }, + }, + }; + const fib_prefix_t pfx_2001_1_s_96 = { + .fp_len = 96, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x2001000000000000), + [1] = clib_host_to_net_u64(0x1000000000000000), + }, + }, + }, + }; + const fib_prefix_t pfx_2001_1_1_s_128 = { + .fp_len = 128, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x2001000000000000), + [1] = clib_host_to_net_u64(0x1000000000000001), + }, + }, + }, + }; + const fib_prefix_t pfx_2001_0_1_s_128 = { + .fp_len = 128, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_addr = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x2001000000000000), + [1] = clib_host_to_net_u64(0x0000000000000001), + }, + }, + }, + }; + const ip46_address_t nh_3000_1 = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x3000000000000000), + [1] = clib_host_to_net_u64(0x0000000000000001), + }, + }, + }; + const ip46_address_t nh_3000_2 = { + .ip6 = { + .as_u64 = { + [0] = clib_host_to_net_u64(0x3000000000000000), + [1] = clib_host_to_net_u64(0x0000000000000002), + }, + }, + }; + adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6, + VNET_LINK_IP6, + &nh_3000_1, + tm->hw[0]->sw_if_index); + adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6, + VNET_LINK_IP6, + &nh_3000_2, + tm->hw[0]->sw_if_index); + fib_test_lb_bucket_t adj_o_3000_1 = { + .type = FT_LB_ADJ, + .adj = { + .adj = ai_3000_1, + }, + }; + fib_test_lb_bucket_t adj_o_3000_2 = { + .type = FT_LB_ADJ, + .adj = { + .adj = ai_3000_2, + }, + }; + + fib_table_entry_special_add(0, + &pfx_2001_0_1_s_128, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + fib_table_entry_special_add(0, + &pfx_2001_1_1_s_128, + FIB_SOURCE_CLI, + FIB_ENTRY_FLAG_DROP); + + /* + * /96 has inherited forwarding pushed down to its covered /128 + */ + fib_table_entry_update_one_path(0, + &pfx_2001_1_s_96, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP6, + &nh_3000_1, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_1), + "%U via 3000::1", + format_fib_prefix, &pfx_2001_1_s_96); + fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_1), + "%U via 3000::1", + format_fib_prefix, &pfx_2001_1_1_s_128); + fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128); + FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)), + "%U resolves via drop", + format_fib_prefix, &pfx_2001_0_1_s_128); + + /* + * /64 has inherited forwarding pushed down to all, but the /96 + * and its sub-tree remain unaffected. + */ + fib_table_entry_update_one_path(0, + &pfx_2001_s_64, + FIB_SOURCE_API, + FIB_ENTRY_FLAG_COVERED_INHERIT, + DPO_PROTO_IP6, + &nh_3000_2, + tm->hw[0]->sw_if_index, + ~0, + 1, + NULL, + FIB_ROUTE_PATH_FLAG_NONE); + + fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_2), + "%U via 3000::2", + format_fib_prefix, &pfx_2001_s_64); + fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_2), + "%U via 3000::1", + format_fib_prefix, &pfx_2001_0_1_s_128); + + fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_1), + "%U via 3000::1", + format_fib_prefix, &pfx_2001_1_s_96); + fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128); + FIB_TEST(fib_test_validate_entry(fei, + FIB_FORW_CHAIN_TYPE_UNICAST_IP6, + 1, + &adj_o_3000_1), + "%U via 3000::1", + format_fib_prefix, &pfx_2001_1_1_s_128); + + /* + * Cleanup + */ + fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI); + fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API); + fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API); + adj_unlock(ai_3000_1); + adj_unlock(ai_3000_2); + + /* + * test no-one left behind + */ + FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone"); + FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed"); + return (0); +} + +static clib_error_t * +fib_test (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd_arg) +{ + int res; + + res = 0; + fib_test_mk_intf(4); + + if (unformat (input, "debug")) + { + fib_test_do_debug = 1; + } + + if (unformat (input, "ip")) + { + res += fib_test_v4(); + res += fib_test_v6(); + } + else if (unformat (input, "label")) + { + res += fib_test_label(); + } + else if (unformat (input, "ae")) + { + res += fib_test_ae(); + } else if (unformat (input, "pref")) { res += fib_test_pref(); @@ -8701,6 +9721,10 @@ fib_test (vlib_main_t * vm, { res += fib_test_bfd(); } + else if (unformat (input, "inherit")) + { + res += fib_test_inherit(); + } else { res += fib_test_v4(); @@ -8709,6 +9733,7 @@ fib_test (vlib_main_t * vm, res += fib_test_bfd(); res += fib_test_pref(); res += fib_test_label(); + res += fib_test_inherit(); res += lfib_test(); /*