X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Funittest%2Fmfib_test.c;h=764e1837653407a8c6088420724c6a0f6b0964fc;hb=refs%2Fchanges%2F55%2F25955%2F5;hp=fda02580bee0f23c642a032208f1610a8ef7b80e;hpb=494a09a3959f3782a7c7f1fa42b7d16a99c98630;p=vpp.git diff --git a/src/plugins/unittest/mfib_test.c b/src/plugins/unittest/mfib_test.c index fda02580bee..764e1837653 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,20 +220,20 @@ 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", - format_mfib_prefix, &pfx, + format_mfib_prefix, pfx, format_mfib_entry_flags, mfe->mfe_flags, format_mfib_entry_flags, eflags); @@ -244,7 +241,7 @@ mfib_test_entry (fib_node_index_t fei, { MFIB_TEST_REP((DPO_DROP == mfe->mfe_rep.dpoi_type), "%U links to %U", - format_mfib_prefix, &pfx, + format_mfib_prefix, pfx, format_dpo_id, &mfe->mfe_rep, 0); } else @@ -253,13 +250,14 @@ 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); MFIB_TEST_REP((DPO_REPLICATE == tmp.dpoi_type), "%U links to %U", - format_mfib_prefix, &pfx, + format_mfib_prefix, pfx, format_dpo_type, tmp.dpoi_type); va_start(ap, n_buckets); @@ -278,23 +276,23 @@ 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", - format_mfib_prefix, &pfx, sw_if_index); + format_mfib_prefix, pfx, sw_if_index); MFIB_TEST_REP((flags == mfi->mfi_flags), "%U interface %d has flags %U expect %U", - format_mfib_prefix, &pfx, sw_if_index, + format_mfib_prefix, pfx, sw_if_index, format_mfib_itf_flags, flags, format_mfib_itf_flags, mfi->mfi_flags); @@ -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); } @@ -410,15 +408,15 @@ mfib_test_i (fib_protocol_t PROTO, .frp_addr = zero_addr, .frp_sw_if_index = tm->hw[0]->sw_if_index, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT, }; mfib_table_entry_path_update(fib_index, pfx_no_forward, MFIB_SOURCE_API, - &path_via_if0, - MFIB_ITF_FLAG_ACCEPT); + &path_via_if0); mfei_no_f = mfib_table_lookup_exact_match(fib_index, pfx_no_forward); MFIB_TEST(!mfib_test_entry(mfei_no_f, @@ -426,41 +424,42 @@ mfib_test_i (fib_protocol_t PROTO, 0), "%U no replcaitions", format_mfib_prefix, pfx_no_forward); - MFIB_TEST_NS(!mfib_test_entry_itf(mfei_no_f, tm->hw[0]->sw_if_index, - MFIB_ITF_FLAG_ACCEPT)); + MFIB_TEST(!mfib_test_entry_itf(mfei_no_f, tm->hw[0]->sw_if_index, + MFIB_ITF_FLAG_ACCEPT), + "%U interface not accepting", + format_mfib_prefix, pfx_no_forward); fib_route_path_t path_via_if1 = { .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, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; fib_route_path_t path_via_if2 = { .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, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; fib_route_path_t path_via_if3 = { .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, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = (MFIB_ITF_FLAG_FORWARD | + MFIB_ITF_FLAG_NEGATE_SIGNAL), }; - fib_route_path_t path_for_us = { - .frp_proto = fib_proto_to_dpo(PROTO), - .frp_addr = zero_addr, - .frp_sw_if_index = 0xffffffff, - .frp_fib_index = ~0, - .frp_weight = 0, - .frp_flags = FIB_ROUTE_PATH_LOCAL, - }; + fib_route_path_t *two_paths = NULL; + vec_add1(two_paths, path_via_if2); + vec_add1(two_paths, path_via_if3); /* * An (S,G) with 1 accepting and 3 forwarding paths @@ -468,24 +467,15 @@ mfib_test_i (fib_protocol_t PROTO, mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_via_if0, - MFIB_ITF_FLAG_ACCEPT); - mfib_table_entry_path_update(fib_index, - pfx_s_g, - MFIB_SOURCE_API, - &path_via_if1, - MFIB_ITF_FLAG_FORWARD); - mfib_table_entry_path_update(fib_index, - pfx_s_g, - MFIB_SOURCE_API, - &path_via_if2, - MFIB_ITF_FLAG_FORWARD); + &path_via_if0); mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_via_if3, - (MFIB_ITF_FLAG_FORWARD | - MFIB_ITF_FLAG_NEGATE_SIGNAL)); + &path_via_if1); + mfib_table_entry_paths_update(fib_index, + pfx_s_g, + MFIB_SOURCE_API, + two_paths); mfei_s_g = mfib_table_lookup_exact_match(fib_index, pfx_s_g); @@ -517,13 +507,11 @@ mfib_test_i (fib_protocol_t PROTO, mfei_g_1 = mfib_table_entry_path_update(fib_index, pfx_star_g_1, MFIB_SOURCE_API, - &path_via_if0, - MFIB_ITF_FLAG_ACCEPT); + &path_via_if0); mfib_table_entry_path_update(fib_index, pfx_star_g_1, MFIB_SOURCE_API, - &path_via_if1, - MFIB_ITF_FLAG_FORWARD); + &path_via_if1); /* * test we find the *,G and S,G via LPM and exact matches @@ -543,7 +531,8 @@ mfib_test_i (fib_protocol_t PROTO, mfei = mfib_table_lookup(fib_index, pfx_star_g_1); MFIB_TEST(mfei == mfei_g_1, - "%U found via LP match", + "[e:%d a:%d] %U found via LP match", + mfei, mfei_g_1, format_mfib_prefix, pfx_star_g_1); MFIB_TEST(!mfib_test_entry(mfei, @@ -584,16 +573,15 @@ mfib_test_i (fib_protocol_t PROTO, * A (*,G/m), which the same root G as the (*,G). * different paths. test our LPM. */ + path_via_if2.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT; mfei_g_m = mfib_table_entry_path_update(fib_index, pfx_star_g_slash_m, MFIB_SOURCE_API, - &path_via_if2, - MFIB_ITF_FLAG_ACCEPT); + &path_via_if2); mfib_table_entry_path_update(fib_index, pfx_star_g_slash_m, MFIB_SOURCE_API, - &path_via_if3, - MFIB_ITF_FLAG_FORWARD); + &path_via_if3); /* * test we find the (*,G/m), (*,G) and (S,G) via LPM and exact matches @@ -657,11 +645,20 @@ mfib_test_i (fib_protocol_t PROTO, /* * Add a for-us path */ + fib_route_path_t path_for_us = { + .frp_proto = fib_proto_to_dpo(PROTO), + .frp_addr = zero_addr, + .frp_sw_if_index = 0xffffffff, + .frp_fib_index = ~0, + .frp_weight = 1, + .frp_flags = FIB_ROUTE_PATH_LOCAL, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, + }; + mfei = mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_for_us, - MFIB_ITF_FLAG_FORWARD); + &path_for_us); MFIB_TEST(!mfib_test_entry(mfei, MFIB_ENTRY_FLAG_NONE, @@ -694,11 +691,11 @@ mfib_test_i (fib_protocol_t PROTO, * update an existing forwarding path to be only accepting * - expect it to be removed from the replication set. */ + path_via_if3.frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT; mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_via_if3, - MFIB_ITF_FLAG_ACCEPT); + &path_via_if3); MFIB_TEST(!mfib_test_entry(mfei, MFIB_ENTRY_FLAG_NONE, @@ -719,13 +716,13 @@ mfib_test_i (fib_protocol_t PROTO, * Make the path forwarding again * - expect it to be added back to the replication set */ + path_via_if3.frp_mitf_flags = (MFIB_ITF_FLAG_FORWARD | + MFIB_ITF_FLAG_ACCEPT | + MFIB_ITF_FLAG_NEGATE_SIGNAL); mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_via_if3, - (MFIB_ITF_FLAG_FORWARD | - MFIB_ITF_FLAG_ACCEPT | - MFIB_ITF_FLAG_NEGATE_SIGNAL)); + &path_via_if3); mfei = mfib_table_lookup_exact_match(fib_index, pfx_s_g); @@ -807,32 +804,37 @@ mfib_test_i (fib_protocol_t PROTO, MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index)); /* - * remove the accpeting only interface + * remove */ - mfib_table_entry_path_remove(fib_index, - pfx_s_g, - MFIB_SOURCE_API, - &path_via_if0); - - MFIB_TEST(!mfib_test_entry(mfei, - MFIB_ENTRY_FLAG_SIGNAL, - 1, - DPO_ADJACENCY_MCAST, ai_2), - "%U replicate OK", - format_mfib_prefix, pfx_s_g); - MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index, - MFIB_ITF_FLAG_FORWARD)); - MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[0]->sw_if_index)); - MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[1]->sw_if_index)); - MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index)); + /* mfib_table_entry_path_remove(fib_index, */ + /* pfx_s_g, */ + /* MFIB_SOURCE_API, */ + /* &path_via_if0); */ + + /* MFIB_TEST(!mfib_test_entry(mfei, */ + /* MFIB_ENTRY_FLAG_SIGNAL, */ + /* 1, */ + /* DPO_ADJACENCY_MCAST, ai_2), */ + /* "%U replicate OK", */ + /* format_mfib_prefix, pfx_s_g); */ + /* MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index, */ + /* MFIB_ITF_FLAG_FORWARD)); */ + /* MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[0]->sw_if_index)); */ + /* MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[1]->sw_if_index)); */ + /* MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index)); */ /* - * remove the last path, the entry still has flags so it remains + * remove the last path and the accpeting only interface, + * the entry still has flags so it remains */ - mfib_table_entry_path_remove(fib_index, - pfx_s_g, - MFIB_SOURCE_API, - &path_via_if2); + vec_reset_length(two_paths); + vec_add1(two_paths, path_via_if0); + vec_add1(two_paths, path_via_if2); + + mfib_table_entry_paths_remove(fib_index, + pfx_s_g, + MFIB_SOURCE_API, + two_paths); MFIB_TEST(!mfib_test_entry(mfei, MFIB_ENTRY_FLAG_SIGNAL, @@ -859,12 +861,12 @@ mfib_test_i (fib_protocol_t PROTO, /* * An entry with a NS interface */ + path_via_if0.frp_mitf_flags = (MFIB_ITF_FLAG_ACCEPT | + MFIB_ITF_FLAG_NEGATE_SIGNAL); mfei_g_2 = mfib_table_entry_path_update(fib_index, pfx_star_g_2, MFIB_SOURCE_API, - &path_via_if0, - (MFIB_ITF_FLAG_ACCEPT | - MFIB_ITF_FLAG_NEGATE_SIGNAL)); + &path_via_if0); MFIB_TEST(!mfib_test_entry(mfei_g_2, MFIB_ENTRY_FLAG_NONE, 0), @@ -887,12 +889,12 @@ mfib_test_i (fib_protocol_t PROTO, /* * An entry with a NS interface */ + path_via_if0.frp_mitf_flags = (MFIB_ITF_FLAG_ACCEPT | + MFIB_ITF_FLAG_NEGATE_SIGNAL); mfei_g_3 = mfib_table_entry_path_update(fib_index, pfx_star_g_3, MFIB_SOURCE_API, - &path_via_if0, - (MFIB_ITF_FLAG_ACCEPT | - MFIB_ITF_NEGATE_SIGNAL)); + &path_via_if0); MFIB_TEST(!mfib_test_entry(mfei_g_3, MFIB_ENTRY_FLAG_NONE, 0), @@ -929,7 +931,7 @@ mfib_test_i (fib_protocol_t PROTO, /* * Find the (*,G/m) */ - MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2( + MFIB_TEST((mfei_g_m == ip6_mfib_table_fwd_lookup( ip6_mfib_get(fib_index), &src, &pfx_star_g_slash_m->fp_grp_addr.ip6)), @@ -940,7 +942,7 @@ mfib_test_i (fib_protocol_t PROTO, ip6_address_t tmp = pfx_star_g_slash_m->fp_grp_addr.ip6; tmp.as_u8[15] = 0xff; - MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2( + MFIB_TEST((mfei_g_m == ip6_mfib_table_fwd_lookup( ip6_mfib_get(fib_index), &pfx_s_g->fp_src_addr.ip6, &tmp)), @@ -951,9 +953,9 @@ mfib_test_i (fib_protocol_t PROTO, /* * Find the (S,G). */ - mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index), - &pfx_s_g->fp_src_addr.ip6, - &pfx_s_g->fp_grp_addr.ip6); + mfei = ip6_mfib_table_fwd_lookup(ip6_mfib_get(fib_index), + &pfx_s_g->fp_src_addr.ip6, + &pfx_s_g->fp_grp_addr.ip6); MFIB_TEST((mfei_s_g == mfei), "%U found via DP LPM: %d", format_mfib_prefix, pfx_s_g, mfei); @@ -961,21 +963,21 @@ mfib_test_i (fib_protocol_t PROTO, /* * Find the 3 (*,G) s */ - mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index), - &src, - &pfx_star_g_1->fp_grp_addr.ip6); + mfei = ip6_mfib_table_fwd_lookup(ip6_mfib_get(fib_index), + &src, + &pfx_star_g_1->fp_grp_addr.ip6); MFIB_TEST((mfei_g_1 == mfei), "%U found via DP LPM: %d", format_mfib_prefix, pfx_star_g_1, mfei); - mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index), - &src, - &pfx_star_g_2->fp_grp_addr.ip6); + mfei = ip6_mfib_table_fwd_lookup(ip6_mfib_get(fib_index), + &src, + &pfx_star_g_2->fp_grp_addr.ip6); MFIB_TEST((mfei_g_2 == mfei), "%U found via DP LPM: %d", format_mfib_prefix, pfx_star_g_2, mfei); - mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index), - &src, - &pfx_star_g_3->fp_grp_addr.ip6); + mfei = ip6_mfib_table_fwd_lookup(ip6_mfib_get(fib_index), + &src, + &pfx_star_g_3->fp_grp_addr.ip6); MFIB_TEST((mfei_g_3 == mfei), "%U found via DP LPM: %d", format_mfib_prefix, pfx_star_g_3, mfei); @@ -1057,28 +1059,28 @@ mfib_test_i (fib_protocol_t PROTO, .frp_addr = *addr_nbr1, .frp_sw_if_index = tm->hw[0]->sw_if_index, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; fib_route_path_t path_via_nbr2 = { .frp_proto = fib_proto_to_dpo(PROTO), .frp_addr = *addr_nbr2, .frp_sw_if_index = tm->hw[0]->sw_if_index, .frp_fib_index = ~0, - .frp_weight = 0, + .frp_weight = 1, .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; mfei_g_1 = mfib_table_entry_path_update(fib_index, pfx_star_g_1, MFIB_SOURCE_API, - &path_via_nbr1, - (MFIB_ITF_FLAG_FORWARD)); + &path_via_nbr1); mfei_g_1 = mfib_table_entry_path_update(fib_index, pfx_star_g_1, MFIB_SOURCE_API, - &path_via_nbr2, - (MFIB_ITF_FLAG_FORWARD)); + &path_via_nbr2); MFIB_TEST(!mfib_test_entry(mfei_g_1, MFIB_ENTRY_FLAG_NONE, 2, @@ -1142,11 +1144,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), @@ -1230,6 +1233,7 @@ mfib_test_i (fib_protocol_t PROTO, .frp_fib_index = 0, .frp_weight = 1, .frp_flags = FIB_ROUTE_PATH_FLAG_NONE, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, }; dpo_id_t mldp_dpo = DPO_INVALID; @@ -1240,8 +1244,7 @@ mfib_test_i (fib_protocol_t PROTO, mfei = mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_via_mldp, - MFIB_ITF_FLAG_FORWARD); + &path_via_mldp); MFIB_TEST(!mfib_test_entry(mfei, MFIB_ENTRY_FLAG_NONE, @@ -1256,8 +1259,7 @@ mfib_test_i (fib_protocol_t PROTO, mfei = mfib_table_entry_path_update(fib_index, pfx_s_g, MFIB_SOURCE_API, - &path_for_us, - MFIB_ITF_FLAG_FORWARD); + &path_for_us); MFIB_TEST(!mfib_test_entry(mfei, MFIB_ENTRY_FLAG_NONE, 2, @@ -1277,6 +1279,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 ? 3 : 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 == @@ -1316,6 +1323,7 @@ mfib_test_i (fib_protocol_t PROTO, MFIB_TEST(n_itfs == pool_elts(mfib_itf_pool), " No more Interfaces %d!=%d", n_itfs, pool_elts(mfib_itf_pool)); + vec_free(two_paths); return (res); } @@ -1493,6 +1501,433 @@ 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 = 1, + .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT, + }; + 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 = 1, + .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, + }; + 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 = 1, + .frp_flags = 0, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, + }; + 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 = 1, + .frp_flags = FIB_ROUTE_PATH_LOCAL, + .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD, + }; + + /* + * 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); + + 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); + + /* + * 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); + + /* + * 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); + + /* + * 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 + */ + mfei_host1 = mfib_table_entry_path_update(fib_index, + pfx_host1, + MFIB_SOURCE_API, + &path_via_if2); + 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 + */ + mfei_host1 = mfib_table_entry_path_update(fib_index, + pfx_host1, + MFIB_SOURCE_API, + &path_via_if2); + 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); + + 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, @@ -1501,23 +1936,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 clib_error_return(0, "MFIB V4 Unit Test Failed"); + } + + res += mfib_test_v6(); + + if (res) { - return (NULL); + return clib_error_return(0, "MFIB V6 Unit Test Failed"); } + + return (NULL); } VLIB_CLI_COMMAND (test_fib_command, static) = {