X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fbier%2Fbier_fmask.c;h=73f719460aa1aaab09539982509cc5e79b496bb9;hb=586479a;hp=32bece0c665583d1944b014df3f7f3be2aec4963;hpb=0f8a96c084dbce006cb03a6a27b2e504fb45b11e;p=vpp.git diff --git a/src/vnet/bier/bier_fmask.c b/src/vnet/bier/bier_fmask.c index 32bece0c665..73f719460aa 100644 --- a/src/vnet/bier/bier_fmask.c +++ b/src/vnet/bier/bier_fmask.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,11 @@ static const char *const bier_fmask_attr_names[] = BIER_FMASK_ATTR_NAMES; */ bier_fmask_t *bier_fmask_pool; +/** + * Stats for each BIER fmask object + */ +vlib_combined_counter_main_t bier_fmask_counters; + static inline index_t bier_fmask_get_index (const bier_fmask_t *bfm) { @@ -74,26 +80,27 @@ static void bier_fmask_stack (bier_fmask_t *bfm) { dpo_id_t via_dpo = DPO_INVALID; + fib_forward_chain_type_t fct; - if (bfm->bfm_flags & BIER_FMASK_FLAG_DISP) + if (bfm->bfm_flags & BIER_FMASK_FLAG_MPLS) { - bier_disp_table_contribute_forwarding(bfm->bfm_disp, - &via_dpo); + fct = FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS; } else { - fib_entry_contribute_forwarding(bfm->bfm_fei, - FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, - &via_dpo); + fct = FIB_FORW_CHAIN_TYPE_BIER; } + fib_path_list_contribute_forwarding(bfm->bfm_pl, fct, + FIB_PATH_LIST_FWD_FLAG_COLLAPSE, + &via_dpo); + /* - * If the via fib entry provides no forwarding (i.e. a drop) - * then niether does this fmask. That way children consider this fmask + * If the via PL entry provides no forwarding (i.e. a drop) + * then neither does this fmask. That way children consider this fmask * unresolved and other ECMP options are used instead. */ - if (dpo_is_drop(&via_dpo) || - load_balance_is_drop(&via_dpo)) + if (dpo_is_drop(&via_dpo)) { bfm->bfm_flags &= ~BIER_FMASK_FLAG_FORWARDING; } @@ -130,65 +137,6 @@ bier_fmask_contribute_forwarding (index_t bfmi, } } -static void -bier_fmask_resolve (bier_fmask_t *bfm) -{ - if (bfm->bfm_flags & BIER_FMASK_FLAG_DISP) - { - bier_disp_table_lock(bfm->bfm_disp); - } - else - { - /* - * source a recursive route through which we resolve. - */ - fib_prefix_t pfx = { - .fp_addr = bfm->bfm_id.bfmi_nh, - .fp_proto = (ip46_address_is_ip4(&(bfm->bfm_id.bfmi_nh)) ? - FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6), - .fp_len = (ip46_address_is_ip4(&(bfm->bfm_id.bfmi_nh)) ? 32 : 128), - }; - - bfm->bfm_fei = fib_table_entry_special_add(0, // default table - &pfx, - FIB_SOURCE_RR, - FIB_ENTRY_FLAG_NONE); - - bfm->bfm_sibling = fib_entry_child_add(bfm->bfm_fei, - FIB_NODE_TYPE_BIER_FMASK, - bier_fmask_get_index(bfm)); - } - - bier_fmask_stack(bfm); -} - -static void -bier_fmask_unresolve (bier_fmask_t *bfm) -{ - if (bfm->bfm_flags & BIER_FMASK_FLAG_DISP) - { - bier_disp_table_unlock(bfm->bfm_disp); - } - else - { - /* - * un-source the recursive route through which we resolve. - */ - fib_prefix_t pfx = { - .fp_addr = bfm->bfm_id.bfmi_nh, - .fp_proto = (ip46_address_is_ip4(&(bfm->bfm_id.bfmi_nh)) ? - FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6), - .fp_len = (ip46_address_is_ip4(&(bfm->bfm_id.bfmi_nh)) ? 32 : 128), - }; - - fib_entry_child_remove(bfm->bfm_fei, bfm->bfm_sibling); - fib_table_entry_special_remove(0, &pfx, FIB_SOURCE_RR); - } - dpo_reset(&bfm->bfm_dpo); -} - u32 bier_fmask_child_add (fib_node_index_t bfmi, fib_node_type_t child_type, @@ -204,6 +152,11 @@ void bier_fmask_child_remove (fib_node_index_t bfmi, u32 sibling_index) { + if (INDEX_INVALID == bfmi) + { + return; + } + fib_node_child_remove(FIB_NODE_TYPE_BIER_FMASK, bfmi, sibling_index); @@ -212,38 +165,69 @@ bier_fmask_child_remove (fib_node_index_t bfmi, static void bier_fmask_init (bier_fmask_t *bfm, const bier_fmask_id_t *fmid, - index_t bti, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { const bier_table_id_t *btid; mpls_label_t olabel; - bfm->bfm_id = *fmid; - bfm->bfm_fib_index = bti; + ASSERT(1 == vec_len(rpaths)); + memset(bfm, 0, sizeof(*bfm)); + + bfm->bfm_id = clib_mem_alloc(sizeof(*bfm->bfm_id)); + + fib_node_init(&bfm->bfm_node, FIB_NODE_TYPE_BIER_FMASK); + *bfm->bfm_id = *fmid; dpo_reset(&bfm->bfm_dpo); + btid = bier_table_get_id(bfm->bfm_id->bfmi_bti); + bier_fmask_bits_init(&bfm->bfm_bits, btid->bti_hdr_len); - if (ip46_address_is_zero(&(bfm->bfm_id.bfmi_nh))) + if (ip46_address_is_zero(&(bfm->bfm_id->bfmi_nh))) { bfm->bfm_flags |= BIER_FMASK_FLAG_DISP; } if (!(bfm->bfm_flags & BIER_FMASK_FLAG_DISP)) { - olabel = rpath->frp_label_stack[0]; - vnet_mpls_uc_set_label(&bfm->bfm_label, olabel); - vnet_mpls_uc_set_exp(&bfm->bfm_label, 0); - vnet_mpls_uc_set_s(&bfm->bfm_label, 1); - vnet_mpls_uc_set_ttl(&bfm->bfm_label, 0xff); + if (NULL != rpaths->frp_label_stack) + { + olabel = rpaths->frp_label_stack[0].fml_value; + vnet_mpls_uc_set_label(&bfm->bfm_label, olabel); + vnet_mpls_uc_set_exp(&bfm->bfm_label, 0); + vnet_mpls_uc_set_s(&bfm->bfm_label, 1); + vnet_mpls_uc_set_ttl(&bfm->bfm_label, 64); + bfm->bfm_flags |= BIER_FMASK_FLAG_MPLS; + } + else + { + bier_bift_id_t id; + + /* + * not an MPLS label + */ + bfm->bfm_flags &= ~BIER_FMASK_FLAG_MPLS; + + /* + * use a label as encoded for BIFT value + */ + id = bier_bift_id_encode(btid->bti_set, + btid->bti_sub_domain, + btid->bti_hdr_len); + vnet_mpls_uc_set_label(&bfm->bfm_label, id); + vnet_mpls_uc_set_s(&bfm->bfm_label, 1); + vnet_mpls_uc_set_exp(&bfm->bfm_label, 0); + vnet_mpls_uc_set_ttl(&bfm->bfm_label, 64); + } bfm->bfm_label = clib_host_to_net_u32(bfm->bfm_label); } - else - { - bfm->bfm_disp = rpath->frp_bier_fib_index; - } - btid = bier_table_get_id(bfm->bfm_fib_index); - bier_fmask_bits_init(&bfm->bfm_bits, btid->bti_hdr_len); - bier_fmask_resolve(bfm); + bfm->bfm_pl = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | + FIB_PATH_LIST_FLAG_NO_URPF), + rpaths); + bfm->bfm_sibling = fib_path_list_child_add(bfm->bfm_pl, + FIB_NODE_TYPE_BIER_FMASK, + bier_fmask_get_index(bfm)); + + bier_fmask_stack(bfm); } static void @@ -252,8 +236,11 @@ bier_fmask_destroy (bier_fmask_t *bfm) clib_mem_free(bfm->bfm_bits.bfmb_refs); clib_mem_free(bfm->bfm_bits.bfmb_input_reset_string.bbs_buckets); - bier_fmask_db_remove(bfm->bfm_fib_index, &(bfm->bfm_id)); - bier_fmask_unresolve(bfm); + bier_fmask_db_remove(bfm->bfm_id); + fib_path_list_child_remove(bfm->bfm_pl, + bfm->bfm_sibling); + dpo_reset(&bfm->bfm_dpo); + clib_mem_free(bfm->bfm_id); pool_put(bier_fmask_pool, bfm); } @@ -289,21 +276,22 @@ bier_fmask_lock (index_t bfmi) index_t bier_fmask_create_and_lock (const bier_fmask_id_t *fmid, - index_t bti, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { bier_fmask_t *bfm; + index_t bfmi; pool_get_aligned(bier_fmask_pool, bfm, CLIB_CACHE_LINE_BYTES); + bfmi = bier_fmask_get_index(bfm); - memset(bfm, 0, sizeof(*bfm)); + vlib_validate_combined_counter (&(bier_fmask_counters), bfmi); + vlib_zero_combined_counter (&(bier_fmask_counters), bfmi); - fib_node_init(&bfm->bfm_node, FIB_NODE_TYPE_BIER_FMASK); - bier_fmask_init(bfm, fmid, bti, rpath); + bier_fmask_init(bfm, fmid, rpaths); - bier_fmask_lock(bier_fmask_get_index(bfm)); + bier_fmask_lock(bfmi); - return (bier_fmask_get_index(bfm)); + return (bfmi); } void @@ -353,6 +341,7 @@ format_bier_fmask (u8 *s, va_list *ap) u32 indent = va_arg(*ap, u32); bier_fmask_attributes_t attr; bier_fmask_t *bfm; + vlib_counter_t to; if (pool_is_free_index(bier_fmask_pool, bfmi)) { @@ -362,7 +351,7 @@ format_bier_fmask (u8 *s, va_list *ap) bfm = bier_fmask_get(bfmi); s = format(s, "fmask: nh:%U bs:%U locks:%d ", - format_ip46_address, &bfm->bfm_id.bfmi_nh, IP46_TYPE_ANY, + format_ip46_address, &bfm->bfm_id->bfmi_nh, IP46_TYPE_ANY, format_bier_bit_string, &bfm->bfm_bits.bfmb_input_reset_string, bfm->bfm_node.fn_locks); s = format(s, "flags:"); @@ -371,13 +360,67 @@ format_bier_fmask (u8 *s, va_list *ap) s = format (s, "%s,", bier_fmask_attr_names[attr]); } } - s = format(s, "\n%U%U", + vlib_get_combined_counter (&(bier_fmask_counters), bfmi, &to); + s = format (s, " to:[%Ld:%Ld]]", to.packets, to.bytes); + s = format(s, "\n"); + s = fib_path_list_format(bfm->bfm_pl, s); + + if (bfm->bfm_flags & BIER_FMASK_FLAG_MPLS) + { + s = format(s, " output-label:%U", + format_mpls_unicast_label, + vnet_mpls_uc_get_label(clib_net_to_host_u32(bfm->bfm_label))); + } + else + { + s = format(s, " output-bfit:[%U]", + format_bier_bift_id, + vnet_mpls_uc_get_label(clib_net_to_host_u32(bfm->bfm_label))); + } + s = format(s, "\n %U%U", format_white_space, indent, format_dpo_id, &bfm->bfm_dpo, indent+2); return (s); } +void +bier_fmask_get_stats (index_t bfmi, u64 * packets, u64 * bytes) +{ + vlib_counter_t to; + + vlib_get_combined_counter (&(bier_fmask_counters), bfmi, &to); + + *packets = to.packets; + *bytes = to.bytes; +} + +void +bier_fmask_encode (index_t bfmi, + bier_table_id_t *btid, + fib_route_path_encode_t *rpath) +{ + bier_fmask_t *bfm; + + bfm = bier_fmask_get(bfmi); + *btid = *bier_table_get_id(bfm->bfm_id->bfmi_bti); + + memset(rpath, 0, sizeof(*rpath)); + + rpath->rpath.frp_sw_if_index = ~0; + + switch (bfm->bfm_id->bfmi_nh_type) + { + case BIER_NH_UDP: + rpath->rpath.frp_flags = FIB_ROUTE_PATH_UDP_ENCAP; + rpath->rpath.frp_udp_encap_id = bfm->bfm_id->bfmi_id; + break; + case BIER_NH_IP: + memcpy(&rpath->rpath.frp_addr, &bfm->bfm_id->bfmi_nh, + sizeof(rpath->rpath.frp_addr)); + break; + } +} static fib_node_t * bier_fmask_get_node (fib_node_index_t index) @@ -509,7 +552,8 @@ bier_fmask_show (vlib_main_t * vm, { pool_foreach(bfm, bier_fmask_pool, ({ - vlib_cli_output (vm, "%U", + vlib_cli_output (vm, "[@%d] %U", + bier_fmask_get_index(bfm), format_bier_fmask, bier_fmask_get_index(bfm), 0); })); }