X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_entry.c;h=d7ff1c8c981c0e7f9c5a6a6a7885de0caae47bf3;hb=57b5860f013953ce161d05302e05370db9cd6ee2;hp=3aa3632c596b6f675e71ba5fdfc50ec3ed36c779;hpb=c0790cfef0bd1c56f4c75dc4f959584148386258;p=vpp.git diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c index 3aa3632c596..d7ff1c8c981 100644 --- a/src/vnet/fib/fib_entry.c +++ b/src/vnet/fib/fib_entry.c @@ -75,13 +75,7 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry) return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6); case FIB_PROTOCOL_MPLS: if (MPLS_EOS == fib_entry->fe_prefix.fp_eos) - /* - * If the entry being asked is a eos-MPLS label entry, - * then use the payload-protocol field, that we stashed there - * for just this purpose - */ - return (fib_forw_chain_type_from_dpo_proto( - fib_entry->fe_prefix.fp_payload_proto)); + return (FIB_FORW_CHAIN_TYPE_MPLS_EOS); else return (FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS); } @@ -94,12 +88,10 @@ format_fib_entry (u8 * s, va_list * args) { fib_forward_chain_type_t fct; fib_entry_attribute_t attr; - fib_path_ext_t *path_ext; fib_entry_t *fib_entry; fib_entry_src_t *src; fib_node_index_t fei; fib_source_t source; - u32 n_covered; int level; fei = va_arg (*args, fib_node_index_t); @@ -133,24 +125,9 @@ format_fib_entry (u8 * s, va_list * args) { s = fib_path_list_format(src->fes_pl, s); } - if (NULL != src->fes_path_exts) - { - s = format(s, " Extensions:"); - vec_foreach(path_ext, src->fes_path_exts) - { - s = format(s, "\n %U", format_fib_path_ext, path_ext); - } - } + s = format(s, "%U", format_fib_path_ext_list, &src->fes_path_exts); })); - n_covered = fib_entry_cover_get_size(fib_entry); - if (n_covered > 0) { - s = format(s, "\n tracking %d covered: ", n_covered); - s = fib_entry_cover_list_format(fib_entry, s); - } - s = fib_ae_import_format(fib_entry, s); - s = fib_ae_export_format(fib_entry, s); - s = format (s, "\n forwarding: "); } else @@ -179,20 +156,17 @@ format_fib_entry (u8 * s, va_list * args) fib_entry_delegate_type_t fdt; fib_entry_delegate_t *fed; - FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, + s = format (s, " Delegates:\n"); + FOR_EACH_DELEGATE(fib_entry, fdt, fed, { - s = format(s, " %U-chain\n %U", - format_fib_forw_chain_type, - fib_entry_delegate_type_to_chain_type(fdt), - format_dpo_id, &fed->fd_dpo, 2); - s = format(s, "\n"); + s = format(s, " %U\n", format_fib_entry_deletegate, fed); }); } } if (level >= FIB_ENTRY_FORMAT_DETAIL2) { - s = format(s, "\nchildren:"); + s = format(s, " Children:"); s = fib_node_children_format(fib_entry->fe_node.fn_children, s); } @@ -346,7 +320,7 @@ fib_entry_show_memory (void) n_srcs += vec_len(entry->fe_srcs); vec_foreach(esrc, entry->fe_srcs) { - n_exts += vec_len(esrc->fes_path_exts); + n_exts += fib_path_ext_list_length(&esrc->fes_path_exts); } })); @@ -382,6 +356,35 @@ fib_entry_contribute_urpf (fib_node_index_t entry_index, return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf)); } +/* + * If the client is request a chain for multicast forwarding then swap + * the chain type to one that can provide such transport. + */ +static fib_forward_chain_type_t +fib_entry_chain_type_mcast_to_ucast (fib_forward_chain_type_t fct) +{ + switch (fct) + { + case FIB_FORW_CHAIN_TYPE_MCAST_IP4: + case FIB_FORW_CHAIN_TYPE_MCAST_IP6: + /* + * we can only transport IP multicast packets if there is an + * LSP. + */ + fct = FIB_FORW_CHAIN_TYPE_MPLS_EOS; + break; + case FIB_FORW_CHAIN_TYPE_MPLS_EOS: + case FIB_FORW_CHAIN_TYPE_UNICAST_IP4: + case FIB_FORW_CHAIN_TYPE_UNICAST_IP6: + case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: + case FIB_FORW_CHAIN_TYPE_ETHERNET: + case FIB_FORW_CHAIN_TYPE_NSH: + break; + } + + return (fct); +} + /* * fib_entry_contribute_forwarding * @@ -397,6 +400,11 @@ fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index, fib_entry = fib_entry_get(fib_entry_index); + /* + * mfib children ask for mcast chains. fix these to the appropriate ucast types. + */ + fct = fib_entry_chain_type_mcast_to_ucast(fct); + if (fct == fib_entry_get_default_chain_type(fib_entry)) { dpo_copy(dpo, &fib_entry->fe_lb); @@ -426,6 +434,11 @@ fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index, dpo_copy(dpo, &fed->fd_dpo); } + /* + * don't allow the special index indicating replicate.vs.load-balance + * to escape to the clients + */ + dpo->dpoi_index &= ~MPLS_IS_REPLICATE; } const dpo_id_t * @@ -449,11 +462,15 @@ fib_entry_get_adj (fib_node_index_t fib_entry_index) const dpo_id_t *dpo; dpo = fib_entry_contribute_ip_forwarding(fib_entry_index); - dpo = load_balance_get_bucket(dpo->dpoi_index, 0); - if (dpo_is_adj(dpo)) + if (dpo_id_is_valid(dpo)) { - return (dpo->dpoi_index); + dpo = load_balance_get_bucket(dpo->dpoi_index, 0); + + if (dpo_is_adj(dpo)) + { + return (dpo->dpoi_index); + } } return (ADJ_INDEX_INVALID); } @@ -551,11 +568,18 @@ fib_entry_alloc (u32 fib_index, return (fib_entry); } -static void +static fib_entry_t* fib_entry_post_flag_update_actions (fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags) { + fib_node_index_t fei; + + /* + * save the index so we can recover from pool reallocs + */ + fei = fib_entry_get_index(fib_entry); + /* * handle changes to attached export for import entries */ @@ -591,6 +615,11 @@ fib_entry_post_flag_update_actions (fib_entry_t *fib_entry, * no change. nothing to do. */ + /* + * reload the entry address post possible pool realloc + */ + fib_entry = fib_entry_get(fei); + /* * handle changes to attached export for export entries */ @@ -605,6 +634,8 @@ fib_entry_post_flag_update_actions (fib_entry_t *fib_entry, // FIXME } // else FIXME + + return (fib_entry); } static void @@ -612,7 +643,9 @@ fib_entry_post_install_actions (fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags) { - fib_entry_post_flag_update_actions(fib_entry, source, old_flags); + fib_entry = fib_entry_post_flag_update_actions(fib_entry, + source, + old_flags); fib_entry_src_action_installed(fib_entry, source); } @@ -908,8 +941,10 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index, /* * no more sources left. this entry is toast. */ + fib_entry = fib_entry_post_flag_update_actions(fib_entry, + source, + bflags); fib_entry_src_action_uninstall(fib_entry); - fib_entry_post_flag_update_actions(fib_entry, source, bflags); return (FIB_ENTRY_SRC_FLAG_NONE); } @@ -996,8 +1031,10 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, /* * no more sources left. this entry is toast. */ + fib_entry = fib_entry_post_flag_update_actions(fib_entry, + source, + bflags); fib_entry_src_action_uninstall(fib_entry); - fib_entry_post_flag_update_actions(fib_entry, source, bflags); return (FIB_ENTRY_SRC_FLAG_NONE); } @@ -1319,6 +1356,65 @@ fib_entry_get_best_source (fib_node_index_t entry_index) return (fib_entry_src_get_source(bsrc)); } +/** + * Return !0 is the entry is reoslved, i.e. will return a valid forwarding + * chain + */ +int +fib_entry_is_resolved (fib_node_index_t fib_entry_index) +{ + fib_entry_delegate_t *fed; + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + + fed = fib_entry_delegate_get(fib_entry, FIB_ENTRY_DELEGATE_BFD); + + if (NULL == fed) + { + /* + * no BFD tracking - consider it resolved. + */ + return (!0); + } + else + { + /* + * defer to the state of the BFD tracking + */ + return (FIB_BFD_STATE_UP == fed->fd_bfd_state); + } +} + +void +fib_entry_set_flow_hash_config (fib_node_index_t fib_entry_index, + flow_hash_config_t hash_config) +{ + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + + /* + * pass the hash-config on to the load-balance object where it is cached. + * we can ignore LBs in the delegate chains, since they will not be of the + * correct protocol type (i.e. they are not IP) + * There's no way, nor need, to change the hash config for MPLS. + */ + if (dpo_id_is_valid(&fib_entry->fe_lb)) + { + load_balance_t *lb; + + ASSERT(DPO_LOAD_BALANCE == fib_entry->fe_lb.dpoi_type); + + lb = load_balance_get(fib_entry->fe_lb.dpoi_index); + + /* + * atomic update for packets in flight + */ + lb->lb_hash_config = hash_config; + } +} + static int fib_ip4_address_compare (const ip4_address_t * a1, const ip4_address_t * a2) @@ -1426,7 +1522,10 @@ fib_entry_encode (fib_node_index_t fib_entry_index, fib_entry_t *fib_entry; fib_entry = fib_entry_get(fib_entry_index); - fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths); + if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent) + { + fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths); + } } void