diff options
Diffstat (limited to 'src/vnet/fib/fib_entry_src.c')
-rw-r--r-- | src/vnet/fib/fib_entry_src.c | 289 |
1 files changed, 105 insertions, 184 deletions
diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c index ab72565d903..8c5082846a8 100644 --- a/src/vnet/fib/fib_entry_src.c +++ b/src/vnet/fib/fib_entry_src.c @@ -146,7 +146,7 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry, fib_entry_src_vft[source].fesv_deinit(esrc); } - vec_free(esrc->fes_path_exts); + fib_path_ext_list_flush(&esrc->fes_path_exts); vec_del1(fib_entry->fe_srcs, index); } @@ -188,7 +188,7 @@ fib_entry_src_action_cover_update (fib_entry_t *fib_entry, typedef struct fib_entry_src_collect_forwarding_ctx_t_ { - load_balance_path_t * next_hops; + load_balance_path_t *next_hops; const fib_entry_t *fib_entry; const fib_entry_src_t *esrc; fib_forward_chain_type_t fct; @@ -264,95 +264,46 @@ fib_entry_chain_type_fixup (const fib_entry_t *entry, return (dfct); } -static int -fib_entry_src_collect_forwarding (fib_node_index_t pl_index, - fib_node_index_t path_index, - void *arg) +static void +fib_entry_src_get_path_forwarding (fib_node_index_t path_index, + fib_entry_src_collect_forwarding_ctx_t *ctx) { - fib_entry_src_collect_forwarding_ctx_t *ctx; - fib_path_ext_t *path_ext; - int have_path_ext; - - ctx = arg; - - /* - * if the path is not resolved, don't include it. - */ - if (!fib_path_is_resolved(path_index)) - { - return (!0); - } - - if (fib_path_is_recursive_constrained(path_index)) - { - ctx->n_recursive_constrained += 1; - } + load_balance_path_t *nh; /* - * get the matching path-extension for the path being visited. + * no extension => no out-going label for this path. that's OK + * in the case of an IP or EOS chain, but not for non-EOS */ - have_path_ext = 0; - vec_foreach(path_ext, ctx->esrc->fes_path_exts) - { - if (path_ext->fpe_path_index == path_index) - { - have_path_ext = 1; - break; - } - } - - if (have_path_ext && - fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0])) + switch (ctx->fct) { + case FIB_FORW_CHAIN_TYPE_UNICAST_IP4: + case FIB_FORW_CHAIN_TYPE_UNICAST_IP6: + case FIB_FORW_CHAIN_TYPE_MCAST_IP4: + case FIB_FORW_CHAIN_TYPE_MCAST_IP6: /* - * found a matching extension. stack it to obtain the forwarding - * info for this path. + * EOS traffic with no label to stack, we need the IP Adj */ - ctx->next_hops = - fib_path_ext_stack(path_ext, - ctx->fct, - fib_entry_chain_type_fixup(ctx->fib_entry, - ctx->fct), - ctx->next_hops); - } - else - { - load_balance_path_t *nh; + vec_add2(ctx->next_hops, nh, 1); - /* - * no extension => no out-going label for this path. that's OK - * in the case of an IP or EOS chain, but not for non-EOS - */ - switch (ctx->fct) + nh->path_index = path_index; + nh->path_weight = fib_path_get_weight(path_index); + fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo); + + break; + case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: + if (fib_path_is_exclusive(path_index) || + fib_path_is_deag(path_index)) { - case FIB_FORW_CHAIN_TYPE_UNICAST_IP4: - case FIB_FORW_CHAIN_TYPE_UNICAST_IP6: - case FIB_FORW_CHAIN_TYPE_MCAST_IP4: - case FIB_FORW_CHAIN_TYPE_MCAST_IP6: - /* - * EOS traffic with no label to stack, we need the IP Adj - */ vec_add2(ctx->next_hops, nh, 1); nh->path_index = path_index; nh->path_weight = fib_path_get_weight(path_index); - fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo); - - break; - case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: - if (fib_path_is_exclusive(path_index) || - fib_path_is_deag(path_index)) - { - vec_add2(ctx->next_hops, nh, 1); - - nh->path_index = path_index; - nh->path_weight = fib_path_get_weight(path_index); - fib_path_contribute_forwarding(path_index, - FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, - &nh->path_dpo); - } - break; - case FIB_FORW_CHAIN_TYPE_MPLS_EOS: + fib_path_contribute_forwarding(path_index, + FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, + &nh->path_dpo); + } + break; + case FIB_FORW_CHAIN_TYPE_MPLS_EOS: { /* * no label. we need a chain based on the payload. fixup. @@ -371,14 +322,85 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, break; } - case FIB_FORW_CHAIN_TYPE_ETHERNET: - case FIB_FORW_CHAIN_TYPE_NSH: - ASSERT(0); - break; + case FIB_FORW_CHAIN_TYPE_ETHERNET: + case FIB_FORW_CHAIN_TYPE_NSH: + ASSERT(0); + break; + } +} + +static fib_path_list_walk_rc_t +fib_entry_src_collect_forwarding (fib_node_index_t pl_index, + fib_node_index_t path_index, + void *arg) +{ + fib_entry_src_collect_forwarding_ctx_t *ctx; + fib_path_ext_t *path_ext; + + ctx = arg; + + /* + * if the path is not resolved, don't include it. + */ + if (!fib_path_is_resolved(path_index)) + { + return (FIB_PATH_LIST_WALK_CONTINUE); + } + + if (fib_path_is_recursive_constrained(path_index)) + { + ctx->n_recursive_constrained += 1; + } + + /* + * get the matching path-extension for the path being visited. + */ + path_ext = fib_path_ext_list_find_by_path_index(&ctx->esrc->fes_path_exts, + path_index); + + if (NULL != path_ext) + { + switch (path_ext->fpe_type) + { + case FIB_PATH_EXT_MPLS: + if (fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0])) + { + /* + * found a matching extension. stack it to obtain the forwarding + * info for this path. + */ + ctx->next_hops = + fib_path_ext_stack(path_ext, + ctx->fct, + fib_entry_chain_type_fixup(ctx->fib_entry, + ctx->fct), + ctx->next_hops); + } + else + { + fib_entry_src_get_path_forwarding(path_index, ctx); + } + break; + case FIB_PATH_EXT_ADJ: + if (FIB_PATH_EXT_ADJ_FLAG_REFINES_COVER & path_ext->fpe_adj_flags) + { + fib_entry_src_get_path_forwarding(path_index, ctx); + } + /* + * else + * the path does not refine the cover, meaning that + * the adjacency doesdoes not match the sub-net on the link. + * So this path does not contribute forwarding. + */ + break; } } + else + { + fib_entry_src_get_path_forwarding(path_index, ctx); + } - return (!0); + return (FIB_PATH_LIST_WALK_CONTINUE); } void @@ -1036,58 +1058,6 @@ fib_entry_flags_update (const fib_entry_t *fib_entry, } /* - * fib_entry_src_path_ext_add - * - * append a path extension to the entry's list - */ -static void -fib_entry_src_path_ext_append (fib_entry_src_t *esrc, - const fib_route_path_t *rpath) -{ - if (NULL != rpath->frp_label_stack) - { - fib_path_ext_t *path_ext; - - vec_add2(esrc->fes_path_exts, path_ext, 1); - - fib_path_ext_init(path_ext, esrc->fes_pl, rpath); - } -} - -/* - * fib_entry_src_path_ext_insert - * - * insert, sorted, a path extension to the entry's list. - * It's not strictly necessary in sort the path extensions, since each - * extension has the path index to which it resolves. However, by being - * sorted the load-balance produced has a deterministic order, not an order - * based on the sequence of extension additions. this is a considerable benefit. - */ -static void -fib_entry_src_path_ext_insert (fib_entry_src_t *esrc, - const fib_route_path_t *rpath) -{ - if (0 == vec_len(esrc->fes_path_exts)) - return (fib_entry_src_path_ext_append(esrc, rpath)); - - if (NULL != rpath->frp_label_stack) - { - fib_path_ext_t path_ext; - int i = 0; - - fib_path_ext_init(&path_ext, esrc->fes_pl, rpath); - - while (i < vec_len(esrc->fes_path_exts) && - (fib_path_ext_cmp(&esrc->fes_path_exts[i], rpath) < 0)) - { - i++; - } - - vec_insert_elts(esrc->fes_path_exts, &path_ext, 1, i); - } -} - -/* * fib_entry_src_action_add * * Adding a source can result in a new fib_entry being created, which @@ -1103,7 +1073,6 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry, { fib_node_index_t old_path_list, fib_entry_index; fib_path_list_flags_t pl_flags; - fib_path_ext_t *path_ext; fib_entry_src_t *esrc; /* @@ -1140,18 +1109,6 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry, fib_entry_src_vft[source].fesv_path_add(esrc, fib_entry, pl_flags, rpath); fib_entry = fib_entry_get(fib_entry_index); - /* - * re-resolve all the path-extensions with the new path-list - */ - vec_foreach(path_ext, esrc->fes_path_exts) - { - fib_path_ext_resolve(path_ext, esrc->fes_pl); - } - /* - * if the path has a label we need to add a path extension - */ - fib_entry_src_path_ext_insert(esrc, rpath); - fib_path_list_lock(esrc->fes_pl); fib_path_list_unlock(old_path_list); @@ -1176,7 +1133,6 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry, fib_node_index_t old_path_list, fib_entry_index; fib_path_list_flags_t pl_flags; const fib_route_path_t *rpath; - fib_path_ext_t *path_ext; fib_entry_src_t *esrc; esrc = fib_entry_src_find(fib_entry, source, NULL); @@ -1218,17 +1174,6 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry, pl_flags, rpaths); - vec_foreach(path_ext, esrc->fes_path_exts) - { - vec_free(path_ext->fpe_label_stack); - } - vec_free(esrc->fes_path_exts); - - vec_foreach(rpath, rpaths) - { - fib_entry_src_path_ext_append(esrc, rpath); - } - fib_entry = fib_entry_get(fib_entry_index); fib_path_list_lock(esrc->fes_pl); @@ -1244,7 +1189,6 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry, { fib_path_list_flags_t pl_flags; fib_node_index_t old_path_list; - fib_path_ext_t *path_ext; fib_entry_src_t *esrc; esrc = fib_entry_src_find(fib_entry, source, NULL); @@ -1266,29 +1210,6 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry, fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc); fib_entry_src_vft[source].fesv_path_remove(esrc, pl_flags, rpath); - /* - * find the matching path extension and remove it - */ - vec_foreach(path_ext, esrc->fes_path_exts) - { - if (!fib_path_ext_cmp(path_ext, rpath)) - { - /* - * delete the element moving the remaining elements down 1 position. - * this preserves the sorted order. - */ - vec_free(path_ext->fpe_label_stack); - vec_delete(esrc->fes_path_exts, 1, (path_ext - esrc->fes_path_exts)); - break; - } - } - /* - * re-resolve all the path-extensions with the new path-list - */ - vec_foreach(path_ext, esrc->fes_path_exts) - { - fib_path_ext_resolve(path_ext, esrc->fes_pl); - } /* * lock the new path-list, unlock the old if it had one |