diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/unittest/mfib_test.c | 489 |
1 files changed, 467 insertions, 22 deletions
diff --git a/src/plugins/unittest/mfib_test.c b/src/plugins/unittest/mfib_test.c index bbe6709f4d7..0707a6f57c8 100644 --- a/src/plugins/unittest/mfib_test.c +++ b/src/plugins/unittest/mfib_test.c @@ -34,9 +34,6 @@ fformat(stderr, "FAIL:%d: " _comment "\n", \ __LINE__, ##_args); \ res = 1; \ - } else { \ - fformat(stderr, "PASS:%d: " _comment "\n", \ - __LINE__, ##_args); \ } \ res; \ }) @@ -223,16 +220,16 @@ mfib_test_entry (fib_node_index_t fei, int n_buckets, ...) { + const mfib_prefix_t *pfx; const mfib_entry_t *mfe; const replicate_t *rep; - mfib_prefix_t pfx; va_list ap; int res; res = 0; mfe = mfib_entry_get(fei); - mfib_entry_get_prefix(fei, &pfx); + pfx = mfib_entry_get_prefix(fei); MFIB_TEST_REP((eflags == mfe->mfe_flags), "%U has %U expect %U", @@ -253,7 +250,8 @@ mfib_test_entry (fib_node_index_t fei, mfib_entry_contribute_forwarding( fei, - fib_forw_chain_type_from_fib_proto(pfx.fp_proto), + mfib_forw_chain_type_from_fib_proto(pfx->fp_proto), + MFIB_ENTRY_FWD_FLAG_NONE, &tmp); rep = replicate_get(tmp.dpoi_index); @@ -278,15 +276,15 @@ mfib_test_entry_itf (fib_node_index_t fei, u32 sw_if_index, mfib_itf_flags_t flags) { + const mfib_prefix_t *pfx; const mfib_entry_t *mfe; const mfib_itf_t *mfi; - mfib_prefix_t pfx; int res; res = 0; mfe = mfib_entry_get(fei); mfi = mfib_entry_get_itf(mfe, sw_if_index); - mfib_entry_get_prefix(fei, &pfx); + pfx = mfib_entry_get_prefix(fei); MFIB_TEST_REP((NULL != mfi), "%U has interface %d", @@ -305,19 +303,19 @@ static int mfib_test_entry_no_itf (fib_node_index_t fei, u32 sw_if_index) { + const mfib_prefix_t *pfx; const mfib_entry_t *mfe; const mfib_itf_t *mfi; - mfib_prefix_t pfx; int res; res = 0; mfe = mfib_entry_get(fei); mfi = mfib_entry_get_itf(mfe, sw_if_index); - mfib_entry_get_prefix(fei, &pfx); + pfx = mfib_entry_get_prefix(fei); MFIB_TEST_REP((NULL == mfi), "%U has no interface %d", - format_mfib_prefix, &pfx, sw_if_index); + format_mfib_prefix, pfx, sw_if_index); return (res); } @@ -1143,11 +1141,12 @@ mfib_test_i (fib_protocol_t 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_entry_update(mfei, + MFIB_SOURCE_SRv6, + (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF | + MFIB_ENTRY_FLAG_EXCLUSIVE), + MFIB_RPF_ID_NONE, + repi2); MFIB_TEST(!mfib_test_entry(mfei, (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF | MFIB_ENTRY_FLAG_EXCLUSIVE), @@ -1278,6 +1277,11 @@ mfib_test_i (fib_protocol_t PROTO, /* * Unlock the table - it's the last lock so should be gone thereafter */ + MFIB_TEST(((PROTO == FIB_PROTOCOL_IP4 ? 1 : 5) == + mfib_table_get_n_routes(fib_index, PROTO)), + "1 = %d route left in the FIB", + mfib_table_get_n_routes(fib_index, PROTO)); + mfib_table_unlock(fib_index, PROTO, MFIB_SOURCE_API); MFIB_TEST((FIB_NODE_INDEX_INVALID == @@ -1494,6 +1498,435 @@ mfib_test_v6 (void) &nbr2)); } +static int +mfib_test_rr_i (fib_protocol_t FPROTO, + dpo_proto_t DPROTO, + vnet_link_t LINKT, + const mfib_prefix_t *pfx_cover, + const mfib_prefix_t *pfx_host1, + const mfib_prefix_t *pfx_host2) +{ + fib_node_index_t mfei_cover, mfei_host1, mfei_host2, ai_1, ai_2; + u32 fib_index, n_entries, n_itfs, n_reps, n_pls; + test_main_t *tm; + int res; + + res = 0; + 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; + + fib_index = 0; + ai_1 = adj_mcast_add_or_lock(FPROTO, + LINKT, + tm->hw[1]->sw_if_index); + ai_2 = adj_mcast_add_or_lock(FPROTO, + LINKT, + tm->hw[2]->sw_if_index); + + fib_route_path_t path_via_if0 = { + .frp_proto = DPROTO, + .frp_addr = zero_addr, + .frp_sw_if_index = tm->hw[0]->sw_if_index, + .frp_fib_index = ~0, + .frp_weight = 0, + .frp_flags = 0, + }; + fib_route_path_t path_via_if1 = { + .frp_proto = DPROTO, + .frp_addr = zero_addr, + .frp_sw_if_index = tm->hw[1]->sw_if_index, + .frp_fib_index = ~0, + .frp_weight = 0, + .frp_flags = 0, + }; + fib_route_path_t path_via_if2 = { + .frp_proto = DPROTO, + .frp_addr = zero_addr, + .frp_sw_if_index = tm->hw[2]->sw_if_index, + .frp_fib_index = ~0, + .frp_weight = 0, + .frp_flags = 0, + }; + fib_route_path_t path_for_us = { + .frp_proto = DPROTO, + .frp_addr = zero_addr, + .frp_sw_if_index = 0xffffffff, + .frp_fib_index = ~0, + .frp_weight = 0, + .frp_flags = FIB_ROUTE_PATH_LOCAL, + }; + + /* + * with only the default in place, recusre thru the /32 + */ + mfei_host1 = mfib_table_entry_special_add(fib_index, pfx_host1, + MFIB_SOURCE_RR, + MFIB_ENTRY_FLAG_NONE, + INDEX_INVALID); + /* + * expect its forwarding to match the cover's + */ + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_DROP, + 0), + "%U no replications OK", + format_mfib_prefix, pfx_host1); + + /* + * Insert the less specific /28 + */ + mfib_table_entry_path_update(fib_index, + pfx_cover, + MFIB_SOURCE_API, + &path_via_if1, + MFIB_ITF_FLAG_FORWARD); + + mfei_cover = mfib_table_lookup_exact_match(fib_index, pfx_cover); + + MFIB_TEST(!mfib_test_entry(mfei_cover, + MFIB_ENTRY_FLAG_NONE, + 1, + DPO_ADJACENCY_MCAST, ai_1), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + + /* + * expect the /32 forwarding to match the new cover's + */ + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 1, + DPO_ADJACENCY_MCAST, ai_1), + "%U replicate OK", + format_mfib_prefix, pfx_host1); + + /* + * add another path to the cover + */ + mfib_table_entry_path_update(fib_index, + pfx_cover, + MFIB_SOURCE_API, + &path_via_if2, + MFIB_ITF_FLAG_FORWARD); + + /* + * expect the /32 and /28 to be via both boths + */ + MFIB_TEST(!mfib_test_entry(mfei_cover, + MFIB_ENTRY_FLAG_NONE, + 2, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 2, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_host1); + + /* + * and the other host whilst all is ready + */ + mfei_host2 = mfib_table_entry_special_add(fib_index, pfx_host2, + MFIB_SOURCE_RR, + MFIB_ENTRY_FLAG_NONE, + INDEX_INVALID); + MFIB_TEST(!mfib_test_entry(mfei_host2, + MFIB_ENTRY_FLAG_NONE, + 2, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_host2); + + /* + * repaet multiple time to simulate multiple recursve children + */ + mfei_host2 = mfib_table_entry_special_add(fib_index, pfx_host2, + MFIB_SOURCE_RR, + MFIB_ENTRY_FLAG_NONE, + INDEX_INVALID); + mfei_host2 = mfib_table_entry_special_add(fib_index, pfx_host2, + MFIB_SOURCE_RR, + MFIB_ENTRY_FLAG_NONE, + INDEX_INVALID); + mfei_host2 = mfib_table_entry_special_add(fib_index, pfx_host2, + MFIB_SOURCE_RR, + MFIB_ENTRY_FLAG_NONE, + INDEX_INVALID); + + /* + * add an accepting path to the cover + */ + mfib_table_entry_path_update(fib_index, + pfx_cover, + MFIB_SOURCE_API, + &path_via_if0, + MFIB_ITF_FLAG_ACCEPT); + + /* + * expect the /32 and /28 to be via both boths + */ + MFIB_TEST(!mfib_test_entry(mfei_cover, + MFIB_ENTRY_FLAG_NONE, + 2, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 2, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_host1, tm->hw[0]->sw_if_index, + MFIB_ITF_FLAG_ACCEPT)); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_cover, tm->hw[0]->sw_if_index, + MFIB_ITF_FLAG_ACCEPT)); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_host1, tm->hw[1]->sw_if_index, + MFIB_ITF_FLAG_FORWARD)); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_cover, tm->hw[1]->sw_if_index, + MFIB_ITF_FLAG_FORWARD)); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_host1, tm->hw[2]->sw_if_index, + MFIB_ITF_FLAG_FORWARD)); + MFIB_TEST_NS(!mfib_test_entry_itf(mfei_cover, tm->hw[2]->sw_if_index, + MFIB_ITF_FLAG_FORWARD)); + + /* + * add a for-us path to the cover + */ + mfib_table_entry_path_update(fib_index, + pfx_cover, + MFIB_SOURCE_API, + &path_for_us, + MFIB_ITF_FLAG_FORWARD); + + /* + * expect the /32 and /28 to be via all three paths + */ + MFIB_TEST(!mfib_test_entry(mfei_cover, + MFIB_ENTRY_FLAG_NONE, + 3, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2, + DPO_RECEIVE, 0), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 3, + DPO_ADJACENCY_MCAST, ai_1, + DPO_ADJACENCY_MCAST, ai_2, + DPO_RECEIVE, 0), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + + /* + * get the forwarding chain from the RR prefix + */ + replicate_t *rep; + dpo_id_t dpo = DPO_INVALID; + + mfib_entry_contribute_forwarding( + mfei_host1, + mfib_forw_chain_type_from_dpo_proto(DPROTO), + MFIB_ENTRY_FWD_FLAG_NONE, + &dpo); + + rep = replicate_get(dpo.dpoi_index); + MFIB_TEST((3 == rep->rep_n_buckets), + "%U replicate 3 buckets", + format_mfib_prefix, pfx_host1); + + /* + * get the forwarding chain from the RR prefix without local paths + */ + mfib_entry_contribute_forwarding( + mfei_host1, + mfib_forw_chain_type_from_dpo_proto(DPROTO), + MFIB_ENTRY_FWD_FLAG_NO_LOCAL, + &dpo); + + rep = replicate_get(dpo.dpoi_index); + MFIB_TEST((2 == rep->rep_n_buckets), + "%U no-local replicate 2 buckets", + format_mfib_prefix, pfx_host1); + + dpo_reset(&dpo); + + /* + * delete the cover, expect the /32 to be via the default + */ + mfib_table_entry_delete(fib_index, pfx_cover, MFIB_SOURCE_API); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_DROP, + 0), + "%U no replications OK", + format_mfib_prefix, pfx_host1); + + /* + * source the /32 with its own path + */ + mfib_table_entry_path_update(fib_index, + pfx_host1, + MFIB_SOURCE_API, + &path_via_if2, + MFIB_ITF_FLAG_FORWARD); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_host1); + + /* + * remove host2 - as many times as it was added + */ + mfib_table_entry_delete(fib_index, pfx_host2, + MFIB_SOURCE_RR); + mfib_table_entry_delete(fib_index, pfx_host2, + MFIB_SOURCE_RR); + mfib_table_entry_delete(fib_index, pfx_host2, + MFIB_SOURCE_RR); + mfib_table_entry_delete(fib_index, pfx_host2, + MFIB_SOURCE_RR); + + + /* + * remove the RR source with paths present + */ + mfib_table_entry_delete(fib_index, pfx_host1, + MFIB_SOURCE_RR); + + /* + * add the RR back then remove the path and RR + */ + mfib_table_entry_path_update(fib_index, + pfx_host1, + MFIB_SOURCE_API, + &path_via_if2, + MFIB_ITF_FLAG_FORWARD); + MFIB_TEST(!mfib_test_entry(mfei_host1, + MFIB_ENTRY_FLAG_NONE, + 1, + DPO_ADJACENCY_MCAST, ai_2), + "%U replicate OK", + format_mfib_prefix, pfx_cover); + + mfib_table_entry_delete(fib_index, pfx_host1, + MFIB_SOURCE_API); + mfib_table_entry_delete(fib_index, pfx_host1, + MFIB_SOURCE_RR); + + /* + * test we've leaked no resources + */ + adj_unlock(ai_1); + adj_unlock(ai_2); + 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), + " No more entries %d!=%d", + n_entries, pool_elts(mfib_entry_pool)); + MFIB_TEST(n_itfs == pool_elts(mfib_itf_pool), + " No more Interfaces %d!=%d", + n_itfs, pool_elts(mfib_itf_pool)); + return (res); +} + +static int +mfib_test_rr_v4 (void) +{ + /* + * 2 length of prefix to play with + */ + const mfib_prefix_t pfx_host1 = { + .fp_len = 32, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_grp_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0xe0001011), + }, + }; + const mfib_prefix_t pfx_host2 = { + .fp_len = 64, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_grp_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0xe0001011), + }, + .fp_src_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0x10101010), + }, + }; + const mfib_prefix_t pfx_cover = { + .fp_len = 28, + .fp_proto = FIB_PROTOCOL_IP4, + .fp_grp_addr = { + .ip4.as_u32 = clib_host_to_net_u32(0xe0001010), + }, + }; + + return (mfib_test_rr_i(FIB_PROTOCOL_IP4, + DPO_PROTO_IP4, + VNET_LINK_IP4, + &pfx_cover, + &pfx_host1, + &pfx_host2)); +} + +static int +mfib_test_rr_v6 (void) +{ + /* + * 2 length of prefix to play with + */ + const mfib_prefix_t pfx_host1 = { + .fp_len = 128, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_grp_addr = { + .ip6.as_u64[0] = clib_host_to_net_u64(0xff03000000000000), + .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001), + }, + }; + const mfib_prefix_t pfx_host2 = { + .fp_len = 256, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_grp_addr = { + .ip6.as_u64[0] = clib_host_to_net_u64(0xff03000000000000), + .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001), + }, + .fp_src_addr = { + .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000), + .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001), + }, + }; + const mfib_prefix_t pfx_cover = { + .fp_len = 64, + .fp_proto = FIB_PROTOCOL_IP6, + .fp_grp_addr = { + .ip6.as_u64[0] = clib_host_to_net_u64(0xff03000000000000), + .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000000), + }, + }; + + return (mfib_test_rr_i(FIB_PROTOCOL_IP6, + DPO_PROTO_IP6, + VNET_LINK_IP6, + &pfx_cover, + &pfx_host1, + &pfx_host2)); +} + static clib_error_t * mfib_test (vlib_main_t * vm, unformat_input_t * input, @@ -1502,23 +1935,35 @@ mfib_test (vlib_main_t * vm, int res = 0; res += mfib_test_mk_intf(4); - res += mfib_test_v4(); + res += mfib_test_rr_v4(); if (res) { - return clib_error_return(0, "MFIB Unit Test Failed"); + return clib_error_return(0, "MFIB RR V4 Unit Test Failed"); } - res += mfib_test_v6(); + res += mfib_test_rr_v6(); if (res) { - return clib_error_return(0, "MFIB Unit Test Failed"); + return clib_error_return(0, "MFIB RR V6 Unit Test Failed"); } - else + + res += mfib_test_v4(); + + if (res) { - return (NULL); + return clib_error_return(0, "MFIB V4 Unit Test Failed"); } + + res += mfib_test_v6(); + + if (res) + { + return clib_error_return(0, "MFIB V6 Unit Test Failed"); + } + + return (NULL); } VLIB_CLI_COMMAND (test_fib_command, static) = { |