X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_path_list.c;h=e9eaa75a08e4404fa63eab258c765ac82361fd7b;hb=4bc2d7ab3990aa8c819cd8134d029aa0d5e5b0d7;hp=3e4c3333a08aa1c6f7c18e29d4c2e0a1f4c3e066;hpb=8142499cd1cb3b8d0168d0e6cf5309c5b4813cc4;p=vpp.git diff --git a/src/vnet/fib/fib_path_list.c b/src/vnet/fib/fib_path_list.c index 3e4c3333a08..e9eaa75a08e 100644 --- a/src/vnet/fib/fib_path_list.c +++ b/src/vnet/fib/fib_path_list.c @@ -116,9 +116,7 @@ fib_path_list_get_node (fib_node_index_t index) static fib_path_list_t* fib_path_list_from_fib_node (fib_node_t *node) { -#if CLIB_DEBUG > 0 ASSERT(FIB_NODE_TYPE_PATH_LIST == node->fn_type); -#endif return ((fib_path_list_t*)node); } @@ -128,16 +126,21 @@ fib_path_list_get_index (fib_path_list_t *path_list) return (path_list - fib_path_list_pool); } -static u8 * +u8 * format_fib_path_list (u8 * s, va_list * args) { + fib_node_index_t *path_index, path_list_index; fib_path_list_attribute_t attr; - fib_node_index_t *path_index; fib_path_list_t *path_list; + u32 indent; - path_list = va_arg (*args, fib_path_list_t *); - - s = format (s, " index:%u", fib_path_list_get_index(path_list)); + path_list_index = va_arg (*args, fib_node_index_t); + indent = va_arg (*args, u32); + path_list = fib_path_list_get(path_list_index); + + s = format (s, "%Upath-list:[%d]", + format_white_space, indent, + fib_path_list_get_index(path_list)); s = format (s, " locks:%u", path_list->fpl_node.fn_locks); if (FIB_PATH_LIST_FLAG_NONE != path_list->fpl_flags) @@ -155,7 +158,7 @@ format_fib_path_list (u8 * s, va_list * args) vec_foreach (path_index, path_list->fpl_paths) { - s = fib_path_format(*path_index, s); + s = format(s, "%U", format_fib_path, *path_index, indent+2); s = format(s, "\n"); } @@ -166,11 +169,7 @@ u8 * fib_path_list_format (fib_node_index_t path_list_index, u8 * s) { - fib_path_list_t *path_list; - - path_list = fib_path_list_get(path_list_index); - - return (format(s, "%U", format_fib_path_list, path_list)); + return (format(s, "%U", format_fib_path_list, path_list_index, 4)); } static uword @@ -355,20 +354,7 @@ fib_path_list_mk_lb (fib_path_list_t *path_list, load_balance_path_t *nhs; fib_node_index_t *path_index; - nhs = NULL; - - if (!dpo_id_is_valid(dpo)) - { - /* - * first time create - */ - dpo_set(dpo, - DPO_LOAD_BALANCE, - fib_forw_chain_type_to_dpo_proto(fct), - load_balance_create(0, - fib_forw_chain_type_to_dpo_proto(fct), - 0 /* FIXME FLOW HASH */)); - } + nhs = NULL; /* * We gather the DPOs from resolved paths. @@ -384,6 +370,12 @@ fib_path_list_mk_lb (fib_path_list_t *path_list, * Path-list load-balances, which if used, would be shared and hence * never need a load-balance map. */ + dpo_set(dpo, + DPO_LOAD_BALANCE, + fib_forw_chain_type_to_dpo_proto(fct), + load_balance_create(vec_len(nhs), + fib_forw_chain_type_to_dpo_proto(fct), + 0 /* FIXME FLOW HASH */)); load_balance_multipath_update(dpo, nhs, LOAD_BALANCE_FLAG_NONE); FIB_PATH_LIST_DBG(path_list, "mk lb: %d", dpo->dpoi_index); @@ -583,6 +575,11 @@ fib_path_list_get_n_paths (fib_node_index_t path_list_index) { fib_path_list_t *path_list; + if (FIB_NODE_INDEX_INVALID == path_list_index) + { + return (0); + } + path_list = fib_path_list_get(path_list_index); return (vec_len(path_list->fpl_paths)); @@ -611,7 +608,7 @@ fib_path_list_get_resolving_interface (fib_node_index_t path_list_index) return (sw_if_index); } -fib_protocol_t +dpo_proto_t fib_path_list_get_proto (fib_node_index_t path_list_index) { fib_path_list_t *path_list; @@ -680,6 +677,16 @@ fib_path_list_create (fib_path_list_flags_t flags, fib_path_create(path_list_index, &rpaths[i])); } + /* + * we sort the paths since the key for the path-list is + * the description of the paths it contains. The paths need to + * be sorted else this description will differ. + */ + if (vec_len(path_list->fpl_paths) > 1) + { + vec_sort_with_function(path_list->fpl_paths, + fib_path_cmp_for_sort); + } } /* @@ -743,7 +750,7 @@ fib_path_list_flags_2_path_flags (fib_path_list_flags_t plf) } fib_node_index_t -fib_path_list_create_special (fib_protocol_t nh_proto, +fib_path_list_create_special (dpo_proto_t nh_proto, fib_path_list_flags_t flags, const dpo_id_t *dpo) { @@ -1133,6 +1140,7 @@ fib_path_list_copy_and_path_remove (fib_node_index_t orig_path_list_index, void fib_path_list_contribute_forwarding (fib_node_index_t path_list_index, fib_forward_chain_type_t fct, + fib_path_list_fwd_flags_t flags, dpo_id_t *dpo) { fib_path_list_t *path_list; @@ -1140,6 +1148,18 @@ fib_path_list_contribute_forwarding (fib_node_index_t path_list_index, path_list = fib_path_list_get(path_list_index); fib_path_list_mk_lb(path_list, fct, dpo); + + ASSERT(DPO_LOAD_BALANCE == dpo->dpoi_type); + + /* + * If there's only one bucket in the load-balance then we can + * squash it out. + */ + if ((1 == load_balance_n_buckets(dpo->dpoi_index)) && + (FIB_PATH_LIST_FWD_FLAG_COLLAPSE & flags)) + { + dpo_copy(dpo, load_balance_get_bucket(dpo->dpoi_index, 0)); + } } /* @@ -1184,6 +1204,8 @@ fib_path_list_recursive_loop_detect (fib_node_index_t path_list_index, is_looped = fib_path_recursive_loop_detect(*path_index, copy_ptr); list_looped += is_looped; + + vec_free(copy); } FIB_PATH_LIST_DBG(path_list, "loop-detect: eval:%d", eval); @@ -1355,9 +1377,9 @@ show_fib_path_list_command (vlib_main_t * vm, * show all */ vlib_cli_output (vm, "FIB Path Lists"); - pool_foreach(path_list, fib_path_list_pool, + pool_foreach_index (pli, fib_path_list_pool, ({ - vlib_cli_output (vm, "%U", format_fib_path_list, path_list); + vlib_cli_output (vm, "%U", format_fib_path_list, pli, 0); })); } return (NULL);