#include <vlib/unix/plugin.h>
+// clang-format off
+
/*
* Add debugs for passing tests
*/
return format (s, "test-eth%d", dev_instance);
}
-static uword dummy_interface_tx (vlib_main_t * vm,
+static uword placeholder_interface_tx (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
VNET_DEVICE_CLASS (test_interface_device_class,static) = {
.name = "Test interface",
.format_device_name = format_test_interface_name,
- .tx_function = dummy_interface_tx,
+ .tx_function = placeholder_interface_tx,
.admin_up_down_function = test_interface_admin_up_down,
};
for (i = 0; i < ninterfaces; i++)
{
- hw_address[5] = i;
+ vnet_eth_interface_registration_t eir = {};
+ vnet_main_t *vnm = vnet_get_main();
- error = ethernet_register_interface(vnet_get_main(),
- test_interface_device_class.index,
- i /* instance */,
- hw_address,
- &tm->hw_if_indicies[i],
- /* flag change */ 0);
+ hw_address[5] = i;
- FIB_TEST((NULL == error), "ADD interface %d", i);
+ eir.dev_class_index = test_interface_device_class.index;
+ eir.dev_instance = i;
+ eir.address = hw_address;
+ tm->hw_if_indicies[i] = vnet_eth_register_interface (vnm, &eir);
error = vnet_hw_interface_set_flags(vnet_get_main(),
tm->hw_if_indicies[i],
VNET_HW_INTERFACE_FLAG_LINK_UP);
tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
tm->hw_if_indicies[i]);
- vec_validate (ip4_main.fib_index_by_sw_if_index,
- tm->hw[i]->sw_if_index);
- vec_validate (ip6_main.fib_index_by_sw_if_index,
- tm->hw[i]->sw_if_index);
- ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
- ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
error = vnet_sw_interface_set_flags(vnet_get_main(),
tm->hw[i]->sw_if_index,
exp->label_stack_o_adj.adj);
}
break;
+ case FT_LB_LABEL_CHAIN_O_ADJ:
+ {
+ const mpls_label_dpo_t *mld = NULL;
+ mpls_label_dpo_flags_t mf;
+ mpls_label_t hdr;
+ u32 ii;
+
+ mf = ((exp->label_chain_o_adj.mode ==
+ FIB_MPLS_LSP_MODE_UNIFORM) ?
+ MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
+ MPLS_LABEL_DPO_FLAG_NONE);
+
+ for (ii = 0; ii < exp->label_chain_o_adj.label_chain_size; ii++)
+ {
+ 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);
+ FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
+ exp->label_chain_o_adj.label_chain[ii]),
+ "bucket %d stacks on label %d",
+ bucket,
+ exp->label_chain_o_adj.label_chain[ii]);
+ dpo = &mld->mld_dpo;
+ }
+
+ FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
+ "bucket %d label stacks on %U",
+ bucket,
+ format_dpo_type, mld->mld_dpo.dpoi_type);
+
+ FIB_TEST_LB((exp->label_chain_o_adj.adj == mld->mld_dpo.dpoi_index),
+ "bucket %d label stacks on adj %d",
+ bucket,
+ exp->label_chain_o_adj.adj);
+ }
+ break;
case FT_LB_LABEL_O_ADJ:
{
const mpls_label_dpo_t *mld;
"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);
FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
exp->label_o_adj.label),
- "bucket %d stacks on label %d",
+ "bucket %d stacks on label %d not %d",
bucket,
+ vnet_mpls_uc_get_label(hdr),
exp->label_o_adj.label);
FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
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(fib_index, &pfx->fp_addr.ip6);
break;
case FIB_PROTOCOL_MPLS:
{
return (res);
}
+static int
+fib_test_multipath_v4 (const test_main_t *tm, const u32 fib_index,
+ const fib_prefix_t *pfx, const int n_paths,
+ const int expected_n_buckets)
+{
+ const int path_list_pool_size = fib_path_list_pool_size();
+ const int path_list_db_size = fib_path_list_db_size();
+ const int entry_pool_size = fib_entry_pool_size();
+ fib_route_path_t *r_paths = NULL;
+ const load_balance_t *lb;
+ const dpo_id_t *dpo;
+ u32 fei;
+ int res = 0;
+ int i;
+
+ for (i = 0; i < n_paths; i++)
+ {
+ fib_route_path_t r_path = {
+ .frp_proto = DPO_PROTO_IP4,
+ .frp_addr = {
+ .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + i),
+ },
+ .frp_sw_if_index = tm->hw[0]->sw_if_index,
+ .frp_weight = 1,
+ .frp_fib_index = ~0,
+ .frp_flags = FIB_ROUTE_PATH_ATTACHED,
+ };
+ vec_add1(r_paths, r_path);
+ }
+
+ fib_table_entry_update(fib_index,
+ pfx,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ r_paths);
+
+ fei = fib_table_lookup_exact_match(fib_index, pfx);
+ FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "prefix present");
+ dpo = fib_entry_contribute_ip_forwarding(fei);
+
+ lb = load_balance_get(dpo->dpoi_index);
+ FIB_TEST((lb->lb_n_buckets == expected_n_buckets),
+ "prefix lb over %d paths", lb->lb_n_buckets);
+
+ fib_table_entry_delete(fib_index,
+ pfx,
+ FIB_SOURCE_API);
+ FIB_TEST(FIB_NODE_INDEX_INVALID ==
+ fib_table_lookup_exact_match(fib_index, pfx), "prefix removed");
+ vec_free(r_paths);
+
+ /*
+ * add-remove test. no change.
+ */
+ FIB_TEST((path_list_db_size == fib_path_list_db_size()),
+ "path list DB population:%d", fib_path_list_db_size());
+ FIB_TEST((path_list_pool_size == fib_path_list_pool_size()),
+ "path list pool size is %d", fib_path_list_pool_size());
+ FIB_TEST((entry_pool_size == fib_entry_pool_size()),
+ "entry pool size is %d", fib_entry_pool_size());
+ return res;
+}
+
static int
fib_test_v4 (void)
{
FIB_SOURCE_API);
for (ii = 0; ii < 4; ii++)
- {
- ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
- }
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[ii]->sw_if_index, fib_index);
fib_prefix_t pfx_0_0_0_0_s_0 = {
.fp_len = 0,
* at this stage there are 5 entries in the test FIB (plus 5 in the default),
* all of which are special sourced and so none of which share path-lists.
* There are also 2 entries, and 2 non-shared path-lists, in the v6 default
- * table, and 4 path-lists in the v6 MFIB table
+ * table, and 4 path-lists in the v6 MFIB table and 2 in v4.
*/
#define ENBR (5+5+2)
- u32 PNBR = 5+5+2+4;
+ u32 PNBR = 5+5+2+4+2;
/*
* if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
adj = adj_get(ai);
FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
"attached interface adj is glean");
- FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
- &adj->sub_type.glean.receive_addr)),
- "attached interface adj is receive ok");
local_pfx.fp_len = 32;
fib_table_entry_update_one_path(fib_index, &local_pfx,
FIB_PROTOCOL_IP4,
FIB_SOURCE_INTERFACE)),
"2 Interface Source'd prefixes");
+ FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
+ &adj->sub_type.glean.rx_pfx.fp_addr)),
+ "attached interface adj is receive ok");
/*
* +2 interface routes +2 non-shared path-lists
/*
* A route with multiple paths at once
*/
- fib_route_path_t *r_paths = NULL;
+ FIB_TEST(0 ==
+ fib_test_multipath_v4(tm, fib_index, &pfx_4_4_4_4_s_32, 4, 4),
+ "multipath with 4 nexthops");
- for (ii = 0; ii < 4; 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);
- }
-
- fib_table_entry_update(fib_index,
- &pfx_4_4_4_4_s_32,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_NONE,
- r_paths);
-
- 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);
-
- lb = load_balance_get(dpo->dpoi_index);
- FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
-
- 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 with lots of multiple paths that will overflow max supported
+ * lb buckets because of normalization
+ */
+ FIB_TEST(0 ==
+ fib_test_multipath_v4(tm, fib_index, &pfx_4_4_4_4_s_32,
+ LB_MAX_BUCKETS / 2 + 23, LB_MAX_BUCKETS),
+ "multipath with too many nexthops");
/*
- * add-remove test. no change.
+ * A route with more paths than max supported lb buckets
*/
- FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
- fib_path_list_db_size());
- FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
- fib_path_list_pool_size());
- FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
- fib_entry_pool_size());
+ FIB_TEST(0 ==
+ fib_test_multipath_v4 (tm, fib_index, &pfx_4_4_4_4_s_32,
+ LB_MAX_BUCKETS + 13, LB_MAX_BUCKETS),
+ "multipath with too many nexthops");
/*
* A route deag route
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_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);
/*
* add-remove test. no change.
FIB_SOURCE_INTERFACE)),
"NO INterface Source'd prefixes");
+ for (ii = 0; ii < 4; ii++)
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[ii]->sw_if_index, 0);
+
fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
FIB_SOURCE_API);
for (ii = 0; ii < 4; ii++)
- {
- ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
- }
+ fib_table_bind (FIB_PROTOCOL_IP6, tm->hw[ii]->sw_if_index, fib_index);
fib_prefix_t pfx_0_0 = {
.fp_len = 0,
dpo = fib_entry_contribute_ip_forwarding(dfrt);
FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
- &ip6_main,
1,
&pfx_0_0.fp_addr.ip6)),
"default-route; fwd and non-fwd tables match");
/*
* At this stage there is one v4 FIB with 5 routes and two v6 FIBs
- * each with 2 entries and a v6 mfib with 4 path-lists.
+ * each with 2 entries and a v6 mfib with 4 path-lists and v4 mfib with 2.
* All entries are special so no path-list sharing.
*/
#define ENPS (5+4)
- u32 PNPS = (5+4+4);
+ u32 PNPS = (5+4+4+2);
/*
* if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
*/
adj = adj_get(ai);
FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
"attached interface adj is glean");
- FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
- &adj->sub_type.glean.receive_addr)),
- "attached interface adj is receive ok");
dpo = fib_entry_contribute_ip_forwarding(fei);
FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
- &ip6_main,
1,
&local_pfx.fp_addr.ip6)),
"attached-route; fwd and non-fwd tables match");
dpo = fib_entry_contribute_ip_forwarding(fei);
FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
- &ip6_main,
1,
&local_pfx.fp_addr.ip6)),
"local-route; fwd and non-fwd tables match");
+ FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
+ &adj->sub_type.glean.rx_pfx.fp_addr)),
+ "attached interface adj is receive ok");
/*
* +2 entries. +2 unshared path-lists
/*
* Add the interface back. routes stay unresolved.
*/
- error = ethernet_register_interface(vnet_get_main(),
- test_interface_device_class.index,
- 0 /* instance */,
- hw_address,
- &tm->hw_if_indicies[0],
- /* flag change */ 0);
+ vnet_eth_interface_registration_t eir = {};
+ eir.dev_class_index = test_interface_device_class.index;
+ eir.dev_instance = 0;
+ eir.address = hw_address;
+ tm->hw_if_indicies[0] = vnet_eth_register_interface (vnet_get_main(), &eir);
fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
/*
* now remove the VRF
*/
+
+ for (ii = 0; ii < 4; ii++)
+ fib_table_bind (FIB_PROTOCOL_IP6, tm->hw[ii]->sw_if_index, 0);
+
fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
adj_nbr_db_size());
+ FIB_TEST((0 == adj_glean_db_size()), "ADJ DB size is %d",
+ adj_glean_db_size());
return (res);
}
{
const dpo_id_t *dpo, *dpo_drop;
const u32 fib_index = 0;
- fib_node_index_t fei;
+ fib_node_index_t dfrt, fei;
test_main_t *tm;
- ip4_main_t *im;
int res;
res = 0;
tm = &test_main;
- im = &ip4_main;
FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
adj_nbr_db_size());
},
};
- vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
- im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[0]->sw_if_index, fib_index);
dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
11,
FIB_SOURCE_CLI);
+ /*
+ * Add default route in the import FIB
+ */
+ fib_prefix_t pfx_0_0_0_0_s_0 = {
+ .fp_len = 0,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4 = {
+ {0}
+ },
+ },
+ };
+
+ dfrt = fib_table_lookup(import_fib_index1, &pfx_0_0_0_0_s_0);
+ FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
+
+ fib_table_entry_path_add(import_fib_index1,
+ &pfx_0_0_0_0_s_0,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ DPO_PROTO_IP4,
+ NULL,
+ tm->hw[0]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+ fei = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
+ FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "default route present");
+ FIB_TEST((fei != dfrt), "default route added");
+
+ /*
+ * delete default route and check for the presence in the import table
+ */
+ fib_table_entry_delete(import_fib_index1, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
+ fei = fib_table_lookup(import_fib_index1, &pfx_0_0_0_0_s_0);
+ FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "default route present");
+ FIB_TEST((fei == dfrt), "default route removed");
/*
* Add an attached route in the import FIB
static int
fib_test_pref (void)
{
- test_main_t *tm = &test_main;
- int res;
+ test_main_t *tm;
+ int res, i;
+ tm = &test_main;
res = 0;
+
const fib_prefix_t pfx_1_1_1_1_s_32 = {
.fp_len = 32,
.fp_proto = FIB_PROTOCOL_IP4,
},
};
+ for (i = 0; i <= 2; i++)
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[i]->sw_if_index, 0);
+
/*
* 2 high, 2 medium and 2 low preference non-recursive paths
*/
const u32 fib_index = 0;
int lb_count, ii, res;
test_main_t *tm;
- ip4_main_t *im;
res = 0;
lb_count = pool_elts(load_balance_pool);
tm = &test_main;
- im = &ip4_main;
/*
* add interface routes. We'll assume this works. It's more rigorously
FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
adj_nbr_db_size());
- vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
- im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[0]->sw_if_index, fib_index);
fib_table_entry_update_one_path(fib_index, &local0_pfx,
FIB_SOURCE_INTERFACE,
},
};
- vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
- im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[1]->sw_if_index, fib_index);
fib_table_entry_update_one_path(fib_index, &local1_pfx,
FIB_SOURCE_INTERFACE,
l1600,
FIB_ROUTE_PATH_FLAG_NONE);
- FIB_TEST(!fib_test_validate_entry(fei,
+ FIB_TEST(!fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
&l1600_eos_o_1_1_1_1),
"adj 10.10.11.1");
fib_table_entry_delete_index(fei, FIB_SOURCE_API);
+ /*
+ * A prefix with outgoing labels. We'll RR source a /32 it covers
+ * and test that the RR source picks up the out-going labels
+ */
+ fib_prefix_t pfx_100_s_8 = {
+ .fp_len = 8,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4.as_u32 = clib_host_to_net_u32(0x64000000),
+ },
+ };
+ fib_test_lb_bucket_t l_100_eos_o_10_10_10_1 = {
+ .type = FT_LB_LABEL_O_ADJ,
+ .label_o_adj = {
+ .adj = ai_mpls_10_10_11_1,
+ .label = 1602,
+ .eos = MPLS_EOS,
+ },
+ };
+ fib_mpls_label_t *l1602 = NULL, fml1602 = {
+ .fml_value = 1602,
+ };
+ vec_add1(l1602, fml1602);
+ fei = fib_table_entry_update_one_path(fib_index,
+ &pfx_100_s_8,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ DPO_PROTO_IP4,
+ &nh_10_10_11_1,
+ tm->hw[1]->sw_if_index,
+ ~0, // invalid fib index
+ 1,
+ l1602,
+ FIB_ROUTE_PATH_FLAG_NONE);
+
+ FIB_TEST(!fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &l_100_eos_o_10_10_10_1),
+ "100.0.0.0/8 LB 1 buckets via: lbl 101 "
+ "adj 10.10.11.1");
+
+ fib_prefix_t pfx_100_1_1_1_s_32 = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4.as_u32 = clib_host_to_net_u32(0x64010101),
+ },
+ };
+
+ fei = fib_table_entry_special_add(fib_index,
+ &pfx_100_1_1_1_s_32,
+ FIB_SOURCE_RR,
+ FIB_ENTRY_FLAG_NONE);
+
+ FIB_TEST(!fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &l_100_eos_o_10_10_10_1),
+ "100.1.1.1/32 LB 1 buckets via: "
+ "adj 10.10.11.1");
+
+ fib_table_entry_delete(fib_index,
+ &pfx_100_s_8,
+ FIB_SOURCE_API);
+ fib_table_entry_delete_index(fei, FIB_SOURCE_RR);
+
/*
* cleanup
*/
}
static int fib_test_walk_spawns_walks;
+static fib_node_type_t test_node_type;
static fib_node_back_walk_rc_t
fib_test_child_back_walk_notify (fib_node_t *node,
vec_add1(tc->ctxs, *ctx);
if (1 == fib_test_walk_spawns_walks)
- fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
+ fib_walk_sync(test_node_type, tc->index, ctx);
if (2 == fib_test_walk_spawns_walks)
- fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
+ fib_walk_async(test_node_type, tc->index,
FIB_WALK_PRIORITY_HIGH, ctx);
return (FIB_NODE_BACK_WALK_CONTINUE);
res = 0;
vm = vlib_get_main();
- fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
+ test_node_type = fib_node_register_new_type("fib-test", &fib_test_child_vft);
/*
* init a fake node on which we will add children
*/
fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
- FIB_NODE_TYPE_TEST);
+ test_node_type);
FOR_EACH_TEST_CHILD(tc)
{
- fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
+ fib_node_init(&tc->node, test_node_type);
fib_node_lock(&tc->node);
tc->ctxs = NULL;
tc->index = ii;
- tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
+ tc->sibling = fib_node_child_add(test_node_type,
PARENT_INDEX,
- FIB_NODE_TYPE_TEST, ii);
+ test_node_type, ii);
}
/*
*/
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
"Parent has %d children pre-walk",
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_LOW, &low_ctx);
fib_walk_process_queues(vm, 1);
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &low_ctx);
fib_walk_process_queues(vm, 1);
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &low_ctx);
fib_walk_process_queues(vm, 1);
*/
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
fib_walk_process_queues(vm, 0);
/*
* schedule another walk that will catch-up and merge.
*/
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
fib_walk_process_queues(vm, 1);
*/
high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
fib_walk_process_queues(vm, 0);
fib_walk_process_queues(vm, 0);
- fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
+ fib_walk_sync(test_node_type, PARENT_INDEX, &high_ctx);
FOR_EACH_TEST_CHILD(tc)
{
* make the parent a child of one of its children, thus inducing a routing loop.
*/
fib_test_nodes[PARENT_INDEX].sibling =
- fib_node_child_add(FIB_NODE_TYPE_TEST,
+ fib_node_child_add(test_node_type,
1, // the first child
- FIB_NODE_TYPE_TEST,
+ test_node_type,
PARENT_INDEX);
/*
*/
fib_test_walk_spawns_walks = 1;
- fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
+ fib_walk_sync(test_node_type, PARENT_INDEX, &high_ctx);
FOR_EACH_TEST_CHILD(tc)
{
* execute an async walk of the graph loop, with each child spawns sync walks
*/
high_ctx.fnbw_depth = 0;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
fib_walk_process_queues(vm, 1);
*/
fib_test_walk_spawns_walks = 2;
high_ctx.fnbw_depth = 0;
- fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_walk_async(test_node_type, PARENT_INDEX,
FIB_WALK_PRIORITY_HIGH, &high_ctx);
fib_walk_process_queues(vm, 1);
}
- fib_node_child_remove(FIB_NODE_TYPE_TEST,
+ fib_node_child_remove(test_node_type,
1, // the first child
fib_test_nodes[PARENT_INDEX].sibling);
*/
FOR_EACH_TEST_CHILD(tc)
{
- fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
+ fib_node_child_remove(test_node_type, PARENT_INDEX,
tc->sibling);
fib_node_deinit(&tc->node);
fib_node_unlock(&tc->node);
bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
- adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
-
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);
+ bfd_10_10_10_1.udp.adj_index = ai_10_10_10_1;
+
+ adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
+
/*
* whilst the BFD session is not signalled, the adj is up
*/
mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
mpls_sw_interface_enable_disable(&mpls_main,
tm->hw[0]->sw_if_index,
- 1, 1);
+ 1);
ip46_address_t nh_10_10_10_1 = {
.ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
*/
mpls_sw_interface_enable_disable(&mpls_main,
tm->hw[0]->sw_if_index,
- 0, 1);
+ 0);
mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
fib_test_inherit (void)
{
fib_node_index_t fei;
+ int n_feis, res, i;
test_main_t *tm;
- int n_feis, res;
+ tm = &test_main;
res = 0;
+
+ for (i = 0; i <= 2; i++)
+ {
+ fib_table_bind (FIB_PROTOCOL_IP4, tm->hw[i]->sw_if_index, 0);
+ fib_table_bind (FIB_PROTOCOL_IP6, tm->hw[i]->sw_if_index, 0);
+ }
n_feis = fib_entry_pool_size();
- tm = &test_main;
const ip46_address_t nh_10_10_10_1 = {
.ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
"%U via 10.10.10.2",
format_fib_prefix, &pfx_10_10_10_0_s_24);
+ fib_source_t hi_src = fib_source_allocate("test", 0x50,
+ FIB_SOURCE_BH_SIMPLE);
+
/*
* 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,
+ hi_src,
FIB_ENTRY_FLAG_NONE,
DPO_PROTO_IP4,
&nh_10_10_10_1,
* 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);
+ fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, hi_src);
fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
FIB_TEST(!fib_test_validate_entry(fei,
&adj_o_10_10_10_3),
"%U via 10.10.10.1",
format_fib_prefix, &pfx_11_11_11_11_s_32);
+ dpo_reset(&interposer);
+ fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
+
+ /*
+ * add an interposer to a source with path-extensions
+ */
+ fib_mpls_label_t *l3300 = NULL, fml_3300 = {
+ .fml_value = 3300,
+ };
+ vec_add1(l3300, fml_3300);
+ fib_table_entry_update_one_path(0,
+ &pfx_11_11_11_11_s_32,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ DPO_PROTO_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ ~0,
+ 1,
+ l3300,
+ FIB_ROUTE_PATH_FLAG_NONE);
+
+ mpls_label_dpo_create(l99,
+ MPLS_EOS,
+ DPO_PROTO_IP4,
+ MPLS_LABEL_DPO_FLAG_NONE,
+ punt_dpo_get(DPO_PROTO_MPLS),
+ &interposer);
+
+ adj_index_t ai_mpls_10_10_10_3 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
+ VNET_LINK_MPLS,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index);
+ fib_test_lb_bucket_t l3300_o_10_10_10_3 = {
+ .type = FT_LB_LABEL_O_ADJ,
+ .label_o_adj = {
+ .adj = ai_mpls_10_10_10_3,
+ .label = 3300,
+ .eos = MPLS_EOS,
+ },
+ };
+ fib_test_lb_bucket_t lchain_o_10_10_10_3 = {
+ .type = FT_LB_LABEL_CHAIN_O_ADJ,
+ .label_chain_o_adj = {
+ .adj = ai_mpls_10_10_10_3,
+ .label_chain_size = 2,
+ .label_chain = {
+ 99, 3300
+ },
+ .eos = MPLS_EOS,
+ },
+ };
+
+ fei = fib_table_entry_special_dpo_add(0,
+ &pfx_11_11_11_11_s_32,
+ FIB_SOURCE_SPECIAL,
+ FIB_ENTRY_FLAG_INTERPOSE,
+ &interposer);
+
+ FIB_TEST(!fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &lchain_o_10_10_10_3),
+ "%U via interposer & mpls on adj",
+ format_fib_prefix, &pfx_11_11_11_11_s_32);
+
+ fib_table_entry_special_remove(0,
+ &pfx_11_11_11_11_s_32,
+ FIB_SOURCE_SPECIAL);
+ FIB_TEST(!fib_test_validate_entry(fei,
+ FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
+ 1,
+ &l3300_o_10_10_10_3),
+ "%U via 10.10.10.1",
+ format_fib_prefix, &pfx_11_11_11_11_s_32);
+ adj_unlock(ai_mpls_10_10_10_3);
/*
* remove and re-add the second best API source while the interpose
FIB_TEST(!fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
- &l99_o_10_10_10_3),
+ &lchain_o_10_10_10_3),
"%U via interposer adj",
format_fib_prefix,&pfx_11_11_11_11_s_32);
- FIB_TEST(2 == pool_elts(mpls_label_dpo_pool),
+ FIB_TEST(3 == pool_elts(mpls_label_dpo_pool),
"MPLS label pool: %d",
pool_elts(mpls_label_dpo_pool));
* multiple interpose sources on the same entry. Only the high
* priority source gets to add the interpose.
*/
+ fib_table_entry_update_one_path(0,
+ &pfx_11_11_11_11_s_32,
+ FIB_SOURCE_API,
+ FIB_ENTRY_FLAG_NONE,
+ DPO_PROTO_IP4,
+ &nh_10_10_10_3,
+ tm->hw[0]->sw_if_index,
+ ~0,
+ 1,
+ NULL,
+ FIB_ROUTE_PATH_FLAG_NONE);
+
dpo_id_t interposer2 = DPO_INVALID;
fib_mpls_label_t *l100 = NULL, fml_100 = {
.fml_value = 100,
FIB_SOURCE_CLASSIFY,
FIB_ENTRY_FLAG_INTERPOSE,
&interposer2);
+
+ fib_test_lb_bucket_t lc100_o_10_10_10_3 = {
+ .type = FT_LB_LABEL_CHAIN_O_ADJ,
+ .label_chain_o_adj = {
+ .adj = ai_10_10_10_3,
+ .label_chain_size = 2,
+ .label_chain = {
+ 99, 100
+ },
+ .eos = MPLS_EOS,
+ },
+ };
+
FIB_TEST(!fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
- &l99_o_10_10_10_3),
+ &lc100_o_10_10_10_3),
"%U via interposer label 99",
format_fib_prefix,&pfx_11_11_11_11_s_32);
format_fib_prefix,&pfx_11_11_11_11_s_32);
fib_table_entry_delete(0, &pfx_11_11_11_0_s_24, FIB_SOURCE_API);
+ fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
FIB_TEST(!fib_test_validate_entry(fei,
FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1,
fib_route_path_t *r_paths2 = NULL;
r_paths2 = vec_dup(r_paths);
- _vec_len(r_paths2) = 3;
+ vec_set_len (r_paths2, 3);
pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths2);
fib_path_list_lock(pl_index);
fib_route_path_t *r_paths3 = NULL;
r_paths3 = vec_dup(r_paths);
- _vec_len(r_paths3) = 3;
+ vec_set_len (r_paths3, 3);
r_paths3[0].frp_weight = 3;
}
VLIB_INIT_FUNCTION (fib_test_init);
+
+// clang-format on