X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_entry.c;h=3bef28e3ad0a90aa1635e04bb967afb1883fed0e;hb=6ede570259a91cd0c34b9faf9fec7e4ec8275200;hp=19e843309700b8055fd03b073790d8901c5fba24;hpb=2303cb181b51f63c909cd506125c1f832432865a;p=vpp.git diff --git a/src/vnet/fib/fib_entry.c b/src/vnet/fib/fib_entry.c index 19e84330970..3bef28e3ad0 100644 --- a/src/vnet/fib/fib_entry.c +++ b/src/vnet/fib/fib_entry.c @@ -28,11 +28,12 @@ #include #include #include +#include +#include /* * Array of strings/names for the FIB sources */ -static const char *fib_source_names[] = FIB_SOURCES; static const char *fib_attribute_names[] = FIB_ENTRY_ATTRIBUTES; static const char *fib_src_attribute_names[] = FIB_ENTRY_SRC_ATTRIBUTES; @@ -41,6 +42,11 @@ static const char *fib_src_attribute_names[] = FIB_ENTRY_SRC_ATTRIBUTES; */ static fib_entry_t *fib_entry_pool; +/** + * the logger + */ +vlib_log_class_t fib_entry_logger; + fib_entry_t * fib_entry_get (fib_node_index_t index) { @@ -91,21 +97,39 @@ fib_entry_get_default_chain_type (const fib_entry_t *fib_entry) } u8 * -format_fib_source (u8 * s, va_list * args) +format_fib_entry_flags (u8 *s, va_list *args) { - fib_source_t source = va_arg (*args, int); + fib_entry_attribute_t attr; + fib_entry_flag_t flag = va_arg(*args, int); - s = format (s, "src:%s", fib_source_names[source]); + FOR_EACH_FIB_ATTRIBUTE(attr) { + if ((1<fe_prefix); -// if (level >= FIB_ENTRY_FORMAT_DETAIL) -// { + if (level >= FIB_ENTRY_FORMAT_DETAIL) + { s = format (s, " fib:%d", fib_entry->fe_fib_index); s = format (s, " index:%d", fib_entry_get_index(fib_entry)); s = format (s, " locks:%d", fib_entry->fe_node.fn_locks); @@ -129,20 +153,12 @@ format_fib_entry (u8 * s, va_list * args) s = format (s, "\n %U", format_fib_source, source); s = format (s, " refs:%d", src->fes_ref_count); if (FIB_ENTRY_FLAG_NONE != src->fes_entry_flags) { - s = format(s, " entry-flags:"); - FOR_EACH_FIB_ATTRIBUTE(attr) { - if ((1<fes_entry_flags) { - s = format (s, "%s,", fib_attribute_names[attr]); - } - } + s = format(s, " entry-flags:%U", + format_fib_entry_flags, src->fes_entry_flags); } if (FIB_ENTRY_SRC_FLAG_NONE != src->fes_flags) { - s = format(s, " src-flags:"); - FOR_EACH_FIB_SRC_ATTRIBUTE(sattr) { - if ((1<fes_flags) { - s = format (s, "%s,", fib_src_attribute_names[sattr]); - } - } + s = format(s, " src-flags:%U", + format_fib_entry_src_flags, src->fes_flags); } s = fib_entry_src_format(fib_entry, source, s); s = format (s, "\n"); @@ -154,11 +170,11 @@ format_fib_entry (u8 * s, va_list * args) })); s = format (s, "\n forwarding: "); -// } -// else -// { -// s = format (s, "\n"); -// } + } + else + { + s = format (s, "\n"); + } fct = fib_entry_get_default_chain_type(fib_entry); @@ -178,14 +194,13 @@ format_fib_entry (u8 * s, va_list * args) if (level >= FIB_ENTRY_FORMAT_DETAIL2) { - fib_entry_delegate_type_t fdt; - fib_entry_delegate_t *fed; + index_t *fedi; s = format (s, " Delegates:\n"); - FOR_EACH_DELEGATE(fib_entry, fdt, fed, + vec_foreach(fedi, fib_entry->fe_delegates) { - s = format(s, " %U\n", format_fib_entry_deletegate, fed); - }); + s = format(s, " %U\n", format_fib_entry_delegate, *fedi); + } } } @@ -259,7 +274,7 @@ fib_entry_src_get_source (const fib_entry_src_t *esrc) { return (esrc->fes_src); } - return (FIB_SOURCE_MAX); + return (FIB_SOURCE_INVALID); } static fib_entry_flag_t @@ -316,6 +331,9 @@ fib_entry_back_walk_notify (fib_node_t *node, */ ctx->fnbw_flags &= ~FIB_NODE_BW_FLAG_FORCE_SYNC; + FIB_ENTRY_DBG(fib_entry, "bw:%U", + format_fib_node_bw_reason, ctx->fnbw_reason); + /* * propagate the backwalk further if we haven't already reached the * maximum depth. @@ -436,14 +454,17 @@ fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index, } else { - fed = fib_entry_delegate_get(fib_entry, - fib_entry_chain_type_to_delegate_type(fct)); + fed = fib_entry_delegate_find(fib_entry, + fib_entry_chain_type_to_delegate_type(fct)); if (NULL == fed) { - fed = fib_entry_delegate_find_or_add( - fib_entry, - fib_entry_chain_type_to_delegate_type(fct)); + /* + * use a temporary DPO lest the delegate realloc in the recursive + * calculation. + */ + dpo_id_t tmp = DPO_INVALID; + /* * on-demand create eos/non-eos. * There is no on-demand delete because: @@ -454,7 +475,14 @@ fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index, fib_entry_src_mk_lb(fib_entry, fib_entry_get_best_src_i(fib_entry), fct, - &fed->fd_dpo); + &tmp); + + fed = fib_entry_delegate_find_or_add( + fib_entry, + fib_entry_chain_type_to_delegate_type(fct)); + + dpo_copy(&fed->fd_dpo, &tmp); + dpo_reset(&tmp); } dpo_copy(dpo, &fed->fd_dpo); @@ -573,7 +601,7 @@ fib_entry_alloc (u32 fib_index, fib_prefix_t *fep; pool_get(fib_entry_pool, fib_entry); - memset(fib_entry, 0, sizeof(*fib_entry)); + clib_memset(fib_entry, 0, sizeof(*fib_entry)); fib_node_init(&fib_entry->fe_node, FIB_NODE_TYPE_ENTRY); @@ -601,8 +629,6 @@ fib_entry_alloc (u32 fib_index, *fib_entry_index = fib_entry_get_index(fib_entry); - FIB_ENTRY_DBG(fib_entry, "alloc"); - return (fib_entry); } @@ -675,14 +701,16 @@ fib_entry_post_flag_update_actions (fib_entry_t *fib_entry, return (fib_entry); } -static void +static fib_entry_t* fib_entry_post_install_actions (fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags) { fib_entry = fib_entry_post_flag_update_actions(fib_entry, old_flags); - fib_entry_src_action_installed(fib_entry, source); + fib_entry = fib_entry_src_action_installed(fib_entry, source); + + return (fib_entry); } fib_node_index_t @@ -717,7 +745,10 @@ fib_entry_create (u32 fib_index, fib_entry = fib_entry_get(fib_entry_index); fib_entry_src_action_activate(fib_entry, source); - fib_entry_post_install_actions(fib_entry, source, FIB_ENTRY_FLAG_NONE); + fib_entry = fib_entry_post_install_actions(fib_entry, source, + FIB_ENTRY_FLAG_NONE); + + FIB_ENTRY_DBG(fib_entry, "create"); return (fib_entry_index); } @@ -733,7 +764,7 @@ fib_entry_create_special (u32 fib_index, fib_entry_t *fib_entry; /* - * create and initiliase the new enty + * create and initialize the new enty */ fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index); @@ -743,7 +774,10 @@ fib_entry_create_special (u32 fib_index, fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo); fib_entry_src_action_activate(fib_entry, source); - fib_entry_post_install_actions(fib_entry, source, FIB_ENTRY_FLAG_NONE); + fib_entry = fib_entry_post_install_actions(fib_entry, source, + FIB_ENTRY_FLAG_NONE); + + FIB_ENTRY_DBG(fib_entry, "create-special"); return (fib_entry_index); } @@ -791,16 +825,17 @@ fib_entry_source_change_w_flags (fib_entry_t *fib_entry, fib_entry_flag_t old_flags, fib_source_t new_source) { - if (new_source < old_source) + switch (fib_source_cmp(new_source, old_source)) { + case FIB_SOURCE_CMP_BETTER: /* * we have a new winning source. */ fib_entry_src_action_deactivate(fib_entry, old_source); fib_entry_src_action_activate(fib_entry, new_source); - } - else if (new_source > old_source) - { + break; + + case FIB_SOURCE_CMP_WORSE: /* * the new source loses. Re-activate the winning sources * in case it is an interposer and hence relied on the losing @@ -808,15 +843,15 @@ fib_entry_source_change_w_flags (fib_entry_t *fib_entry, */ fib_entry_src_action_reactivate(fib_entry, old_source); return; - } - else - { + + case FIB_SOURCE_CMP_EQUAL: /* * the new source is one this entry already has. * But the path-list was updated, which will contribute new forwarding, * so install it. */ fib_entry_src_action_reactivate(fib_entry, new_source); + break; } fib_entry_post_update_actions(fib_entry, new_source, old_flags); @@ -850,6 +885,7 @@ fib_entry_special_add (fib_node_index_t fib_entry_index, fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo); fib_entry_source_change(fib_entry, best_source, source); + FIB_ENTRY_DBG(fib_entry, "special-add:%U", format_fib_source, source); } void @@ -866,6 +902,8 @@ fib_entry_special_update (fib_node_index_t fib_entry_index, fib_entry = fib_entry_src_action_update(fib_entry, source, flags, dpo); fib_entry_source_change(fib_entry, best_source, source); + + FIB_ENTRY_DBG(fib_entry, "special-updated:%U", format_fib_source, source); } @@ -873,23 +911,23 @@ void fib_entry_path_add (fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { fib_source_t best_source; fib_entry_t *fib_entry; fib_entry_src_t *bsrc; - ASSERT(1 == vec_len(rpath)); - fib_entry = fib_entry_get(fib_entry_index); ASSERT(NULL != fib_entry); bsrc = fib_entry_get_best_src_i(fib_entry); best_source = fib_entry_src_get_source(bsrc); - fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpath); + fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpaths); fib_entry_source_change(fib_entry, best_source, source); + + FIB_ENTRY_DBG(fib_entry, "path add:%U", format_fib_source, source); } static fib_entry_src_flag_t @@ -936,7 +974,7 @@ fib_entry_source_removed (fib_entry_t *fib_entry, bsrc = fib_entry_get_best_src_i(fib_entry); best_source = fib_entry_src_get_source(bsrc); - if (FIB_SOURCE_MAX == best_source) + if (FIB_SOURCE_INVALID == best_source) { /* * no more sources left. this entry is toast. @@ -968,7 +1006,7 @@ fib_entry_source_removed (fib_entry_t *fib_entry, fib_entry_src_flag_t fib_entry_path_remove (fib_node_index_t fib_entry_index, fib_source_t source, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { fib_entry_src_flag_t sflag; fib_source_t best_source; @@ -976,8 +1014,6 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index, fib_entry_t *fib_entry; fib_entry_src_t *bsrc; - ASSERT(1 == vec_len(rpath)); - fib_entry = fib_entry_get(fib_entry_index); ASSERT(NULL != fib_entry); @@ -985,23 +1021,25 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index, best_source = fib_entry_src_get_source(bsrc); bflags = fib_entry_src_get_flags(bsrc); - sflag = fib_entry_src_action_path_remove(fib_entry, source, rpath); + sflag = fib_entry_src_action_path_remove(fib_entry, source, rpaths); + + FIB_ENTRY_DBG(fib_entry, "path remove:%U", format_fib_source, source); /* * if the path list for the source passed is invalid, * then we need to create a new one. else we are updating * an existing. */ - if (source < best_source) + switch (fib_source_cmp(source, best_source)) { + case FIB_SOURCE_CMP_BETTER: /* * Que! removing a path from a source that is better than the * one this entry is using. */ ASSERT(0); - } - else if (source > best_source ) - { + break; + case FIB_SOURCE_CMP_WORSE: /* * the source is not the best. no need to update forwarding */ @@ -1019,10 +1057,9 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index, * that remain are non-inherited */ return (fib_entry_src_burn_only_inherited(fib_entry)); - } - } - else - { + } + break; + case FIB_SOURCE_CMP_EQUAL: /* * removing a path from the path-list we were using. */ @@ -1041,6 +1078,7 @@ fib_entry_path_remove (fib_node_index_t fib_entry_index, */ fib_entry_src_action_reactivate(fib_entry, source); } + break; } fib_entry_post_update_actions(fib_entry, source, bflags); @@ -1074,6 +1112,8 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, best_source = fib_entry_src_get_source(bsrc); bflags = fib_entry_src_get_flags(bsrc); + FIB_ENTRY_DBG(fib_entry, "special remove:%U", format_fib_source, source); + sflag = fib_entry_src_action_remove_or_update_inherit(fib_entry, source); /* @@ -1081,16 +1121,17 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, * then we need to create a new one. else we are updating * an existing. */ - if (source < best_source ) + switch (fib_source_cmp(source, best_source)) { + case FIB_SOURCE_CMP_BETTER: /* * Que! removing a path from a source that is better than the * one this entry is using. This can only mean it is a source * this prefix does not have. */ return (FIB_ENTRY_SRC_FLAG_ADDED); - } - else if (source > best_source ) { + + case FIB_SOURCE_CMP_WORSE: /* * the source is not the best. no need to update forwarding */ @@ -1124,9 +1165,9 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, return (FIB_ENTRY_SRC_FLAG_ADDED); } - } - else - { + break; + + case FIB_SOURCE_CMP_EQUAL: if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag)) { /* @@ -1141,6 +1182,7 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, */ fib_entry_src_action_reactivate(fib_entry, source); } + break; } fib_entry_post_update_actions(fib_entry, source, bflags); @@ -1154,7 +1196,7 @@ fib_entry_special_remove (fib_node_index_t fib_entry_index, /** * fib_entry_inherit * - * If the source on the cover is inherting then push this source + * If the source on the cover is inheriting then push this source * down to the covered. */ void @@ -1206,6 +1248,7 @@ fib_entry_update (fib_node_index_t fib_entry_index, paths); fib_entry_source_change_w_flags(fib_entry, best_source, bflags, source); + FIB_ENTRY_DBG(fib_entry, "update"); } @@ -1235,7 +1278,7 @@ fib_entry_cover_changed (fib_node_index_t fib_entry_index) fib_attached_export_cover_change(fib_entry); /* - * propagate the notificuation to each of the added sources + * propagate the notification to each of the added sources */ index = 0; FOR_EACH_SRC_ADDED(fib_entry, esrc, source, @@ -1261,7 +1304,9 @@ fib_entry_cover_changed (fib_node_index_t fib_entry_index) fib_entry_src_action_reactivate(fib_entry, fib_entry_src_get_source( fib_entry_get_best_src_i(fib_entry))); - fib_entry_post_install_actions(fib_entry, best_source, bflags); + fib_entry = fib_entry_post_install_actions(fib_entry, + best_source, + bflags); } else { @@ -1279,6 +1324,7 @@ fib_entry_cover_changed (fib_node_index_t fib_entry_index) fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx); } + FIB_ENTRY_DBG(fib_entry, "cover-changed"); } /* @@ -1308,7 +1354,7 @@ fib_entry_cover_updated (fib_node_index_t fib_entry_index) fib_attached_export_cover_update(fib_entry); /* - * propagate the notificuation to each of the added sources + * propagate the notification to each of the added sources */ index = 0; FOR_EACH_SRC_ADDED(fib_entry, esrc, source, @@ -1334,7 +1380,9 @@ fib_entry_cover_updated (fib_node_index_t fib_entry_index) fib_entry_src_action_reactivate(fib_entry, fib_entry_src_get_source( fib_entry_get_best_src_i(fib_entry))); - fib_entry_post_install_actions(fib_entry, best_source, bflags); + fib_entry = fib_entry_post_install_actions(fib_entry, + best_source, + bflags); } else { @@ -1352,6 +1400,7 @@ fib_entry_cover_updated (fib_node_index_t fib_entry_index) fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx); } + FIB_ENTRY_DBG(fib_entry, "cover-updated"); } int @@ -1428,7 +1477,16 @@ fib_entry_get_best_source (fib_node_index_t entry_index) } /** - * Return !0 is the entry is reoslved, i.e. will return a valid forwarding + * Return !0 is the entry represents a host prefix + */ +int +fib_entry_is_host (fib_node_index_t fib_entry_index) +{ + return (fib_prefix_is_host(fib_entry_get_prefix(fib_entry_index))); +} + +/** + * Return !0 is the entry is resolved, i.e. will return a valid forwarding * chain */ int @@ -1439,7 +1497,7 @@ fib_entry_is_resolved (fib_node_index_t fib_entry_index) fib_entry = fib_entry_get(fib_entry_index); - fed = fib_entry_delegate_get(fib_entry, FIB_ENTRY_DELEGATE_BFD); + fed = fib_entry_delegate_find(fib_entry, FIB_ENTRY_DELEGATE_BFD); if (NULL == fed) { @@ -1486,14 +1544,24 @@ fib_entry_set_flow_hash_config (fib_node_index_t fib_entry_index, } } +u32 +fib_entry_get_stats_index (fib_node_index_t fib_entry_index) +{ + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + + return (fib_entry->fe_lb.dpoi_index); +} + static int fib_ip4_address_compare (const ip4_address_t * a1, const ip4_address_t * a2) { /* - * IP addresses are unsiged ints. the return value here needs to be signed + * IP addresses are unsigned ints. the return value here needs to be signed * a simple subtraction won't cut it. - * If the addresses are the same, the sort order is undefiend, so phoey. + * If the addresses are the same, the sort order is undefined, so phoey. */ return ((clib_net_to_host_u32(a1->data_u32) > clib_net_to_host_u32(a2->data_u32) ) ? @@ -1583,30 +1651,50 @@ fib_entry_unlock (fib_node_index_t fib_entry_index) void fib_entry_module_init (void) { - fib_node_register_type (FIB_NODE_TYPE_ENTRY, &fib_entry_vft); + fib_node_register_type(FIB_NODE_TYPE_ENTRY, &fib_entry_vft); + fib_entry_logger = vlib_log_register_class("fib", "entry"); + + fib_entry_track_module_init(); } -void -fib_entry_encode (fib_node_index_t fib_entry_index, - fib_route_path_encode_t **api_rpaths) +fib_route_path_t * +fib_entry_encode (fib_node_index_t fib_entry_index) { + fib_path_ext_list_t *ext_list; + fib_path_encode_ctx_t ctx = { + .rpaths = NULL, + }; fib_entry_t *fib_entry; + fib_entry_src_t *bsrc; + ext_list = NULL; fib_entry = fib_entry_get(fib_entry_index); + bsrc = fib_entry_get_best_src_i(fib_entry); + + if (bsrc) + { + ext_list = &bsrc->fes_path_exts; + } + if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent) { - fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths); + fib_path_list_walk_w_ext(fib_entry->fe_parent, + ext_list, + fib_path_encode, + &ctx); } + + return (ctx.rpaths); } -void -fib_entry_get_prefix (fib_node_index_t fib_entry_index, - fib_prefix_t *pfx) +const fib_prefix_t * +fib_entry_get_prefix (fib_node_index_t fib_entry_index) { fib_entry_t *fib_entry; fib_entry = fib_entry_get(fib_entry_index); - *pfx = fib_entry->fe_prefix; + + return (&fib_entry->fe_prefix); } u32 @@ -1625,6 +1713,29 @@ fib_entry_pool_size (void) return (pool_elts(fib_entry_pool)); } +#ifdef CLIB_DEBUG +void +fib_table_assert_empty (const fib_table_t *fib_table) +{ + fib_node_index_t *fei, *feis = NULL; + fib_entry_t *fib_entry; + + pool_foreach (fib_entry, fib_entry_pool, + ({ + if (fib_entry->fe_fib_index == fib_table->ft_index) + vec_add1 (feis, fib_entry_get_index(fib_entry)); + })); + + if (vec_len(feis)) + { + vec_foreach (fei, feis) + clib_error ("%U", format_fib_entry, *fei, FIB_ENTRY_FORMAT_DETAIL); + } + + ASSERT(0); +} +#endif + static clib_error_t * show_fib_entry_command (vlib_main_t * vm, unformat_input_t * input,