X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fmfib%2Fmfib_entry.c;h=448e6c5e0a8a9bd3d0a2e9b363d446bf3450b175;hb=9db6ada77;hp=ac37665fb723cc38f33631c10c9cbaa2b4c0995e;hpb=775f73c6baaf9bc2283e7ab9752c81984823be99;p=vpp.git diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c index ac37665fb72..448e6c5e0a8 100644 --- a/src/vnet/mfib/mfib_entry.c +++ b/src/vnet/mfib/mfib_entry.c @@ -38,6 +38,7 @@ static mfib_path_ext_t *mfib_path_ext_pool; * String names for each source */ static const char *mfib_source_names[] = MFIB_SOURCE_NAMES; +static const char *mfib_src_attribute_names[] = MFIB_ENTRY_SRC_ATTRIBUTES; /* * Pool for all fib_entries @@ -101,6 +102,26 @@ format_mfib_entry_path_ext (u8 * s, va_list * args) format_mfib_itf_flags, path_ext->mfpe_flags)); } +u8 * +format_mfib_entry_src_flags (u8 *s, va_list *args) +{ + mfib_entry_src_attribute_t sattr; + mfib_entry_src_flags_t flag = va_arg(*args, int); + + if (!flag) + { + return format(s, "none"); + } + + FOR_EACH_MFIB_SRC_ATTRIBUTE(sattr) { + if ((1 << sattr) & flag) { + s = format (s, "%s,", mfib_src_attribute_names[sattr]); + } + } + + return (s); +} + u8 * format_mfib_entry (u8 * s, va_list * args) { @@ -127,14 +148,15 @@ format_mfib_entry (u8 * s, va_list * args) s = format (s, " locks:%d\n", mfib_entry->mfe_node.fn_locks); vec_foreach(msrc, mfib_entry->mfe_srcs) { - s = format (s, " src:%s locks:%d:", + s = format (s, " src:%s flags:%U locks:%d:", mfib_source_names[msrc->mfes_src], + format_mfib_entry_src_flags, msrc->mfes_flags, msrc->mfes_ref_count); if (msrc->mfes_cover != FIB_NODE_INDEX_INVALID) { s = format (s, " cover:%d", msrc->mfes_cover); } - s = format (s, " %U\n", format_mfib_entry_flags, msrc->mfes_flags); + s = format (s, " %U\n", format_mfib_entry_flags, msrc->mfes_route_flags); if (FIB_NODE_INDEX_INVALID != msrc->mfes_pl) { s = fib_path_list_format(msrc->mfes_pl, s); @@ -201,7 +223,7 @@ mfib_entry_src_init (mfib_entry_t *mfib_entry, { mfib_entry_src_t esrc = { .mfes_pl = FIB_NODE_INDEX_INVALID, - .mfes_flags = MFIB_ENTRY_FLAG_NONE, + .mfes_route_flags = MFIB_ENTRY_FLAG_NONE, .mfes_src = source, .mfes_cover = FIB_NODE_INDEX_INVALID, .mfes_sibling = FIB_NODE_INDEX_INVALID, @@ -215,8 +237,8 @@ mfib_entry_src_init (mfib_entry_t *mfib_entry, static mfib_entry_src_t * mfib_entry_src_find (const mfib_entry_t *mfib_entry, - mfib_source_t source, - u32 *index) + mfib_source_t source, + u32 *index) { mfib_entry_src_t *esrc; @@ -269,8 +291,9 @@ mfib_entry_src_update (mfib_entry_t *mfib_entry, msrc = mfib_entry_src_find_or_create(mfib_entry, source); - msrc->mfes_flags = entry_flags; + msrc->mfes_route_flags = entry_flags; msrc->mfes_rpf_id = rpf_id; + msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE; return (msrc); } @@ -286,6 +309,7 @@ mfib_entry_src_update_and_lock (mfib_entry_t *mfib_entry, msrc = mfib_entry_src_update(mfib_entry, source, rpf_id, entry_flags); msrc->mfes_ref_count++; + msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE; return (msrc); } @@ -331,6 +355,44 @@ mfib_entry_is_sourced (fib_node_index_t mfib_entry_index, return (NULL != mfib_entry_src_find(mfib_entry, source, NULL)); } +int +mfib_entry_is_marked (fib_node_index_t mfib_entry_index, + mfib_source_t source) +{ + mfib_entry_t *mfib_entry; + mfib_entry_src_t *esrc; + + mfib_entry = mfib_entry_get(mfib_entry_index); + + esrc = mfib_entry_src_find(mfib_entry, source, NULL); + + if (NULL == esrc) + { + return (0); + } + else + { + return (!!(esrc->mfes_flags & MFIB_ENTRY_SRC_FLAG_STALE)); + } +} + +void +mfib_entry_mark (fib_node_index_t fib_entry_index, + mfib_source_t source) +{ + mfib_entry_t *mfib_entry; + mfib_entry_src_t *esrc; + + mfib_entry = mfib_entry_get(fib_entry_index); + + esrc = mfib_entry_src_find(mfib_entry, source, NULL); + + if (NULL != esrc) + { + esrc->mfes_flags |= MFIB_ENTRY_SRC_FLAG_STALE; + } +} + int mfib_entry_is_host (fib_node_index_t mfib_entry_index) { @@ -578,7 +640,7 @@ mfib_entry_stack (mfib_entry_t *mfib_entry, * updates to recalculate forwarding. */ mfib_entry->mfe_pl = msrc->mfes_pl; - mfib_entry->mfe_flags = msrc->mfes_flags; + mfib_entry->mfe_flags = msrc->mfes_route_flags; mfib_entry->mfe_itfs = msrc->mfes_itfs; mfib_entry->mfe_rpf_id = msrc->mfes_rpf_id; @@ -633,16 +695,25 @@ mfib_entry_stack (mfib_entry_t *mfib_entry, { /* * for exclusive routes the source provided a replicate DPO - * we we stashed inthe special path list with one path + * which we stashed in the special path list with one path, * so we can stack directly on that. */ ASSERT(1 == vec_len(ctx.next_hops)); - dpo_stack(DPO_MFIB_ENTRY, dp, - &mfib_entry->mfe_rep, - &ctx.next_hops[0].path_dpo); - dpo_reset(&ctx.next_hops[0].path_dpo); - vec_free(ctx.next_hops); + if (NULL != ctx.next_hops) + { + dpo_stack(DPO_MFIB_ENTRY, dp, + &mfib_entry->mfe_rep, + &ctx.next_hops[0].path_dpo); + dpo_reset(&ctx.next_hops[0].path_dpo); + vec_free(ctx.next_hops); + } + else + { + dpo_stack(DPO_MFIB_ENTRY, dp, + &mfib_entry->mfe_rep, + drop_dpo_get(dp)); + } } } else @@ -664,20 +735,13 @@ mfib_entry_stack (mfib_entry_t *mfib_entry, &bw_ctx); } -static fib_node_index_t -mfib_entry_src_path_add (mfib_entry_src_t *msrc, - const fib_route_path_t *rpath) +static fib_node_index_t* +mfib_entry_src_paths_add (mfib_entry_src_t *msrc, + const fib_route_path_t *rpaths) { - fib_node_index_t path_index; - fib_route_path_t *rpaths; - - ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags)); + ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_route_flags)); - /* - * path-lists require a vector of paths - */ - rpaths = NULL; - vec_add1(rpaths, rpath[0]); + msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE; if (FIB_NODE_INDEX_INVALID == msrc->mfes_pl) { @@ -687,33 +751,18 @@ mfib_entry_src_path_add (mfib_entry_src_t *msrc, fib_path_list_lock(msrc->mfes_pl); } - path_index = fib_path_list_path_add(msrc->mfes_pl, rpaths); - - vec_free(rpaths); - - return (path_index); + return (fib_path_list_paths_add(msrc->mfes_pl, rpaths)); } -static fib_node_index_t -mfib_entry_src_path_remove (mfib_entry_src_t *msrc, - const fib_route_path_t *rpath) +static fib_node_index_t* +mfib_entry_src_paths_remove (mfib_entry_src_t *msrc, + const fib_route_path_t *rpaths) { - fib_node_index_t path_index; - fib_route_path_t *rpaths; + ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_route_flags)); - ASSERT(!(MFIB_ENTRY_FLAG_EXCLUSIVE & msrc->mfes_flags)); + msrc->mfes_flags &= ~MFIB_ENTRY_SRC_FLAG_STALE; - /* - * path-lists require a vector of paths - */ - rpaths = NULL; - vec_add1(rpaths, rpath[0]); - - path_index = fib_path_list_path_remove(msrc->mfes_pl, rpaths); - - vec_free(rpaths); - - return (path_index); + return (fib_path_list_paths_remove(msrc->mfes_pl, rpaths)); } static void @@ -809,8 +858,13 @@ static int mfib_entry_src_ok_for_delete (const mfib_entry_src_t *msrc) { return ((INDEX_INVALID == msrc->mfes_cover && - MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags && - 0 == fib_path_list_get_n_paths(msrc->mfes_pl))); + MFIB_ENTRY_FLAG_NONE == msrc->mfes_route_flags && + 0 == fib_path_list_get_n_paths(msrc->mfes_pl)) && + (0 == hash_elts(msrc->mfes_itfs))); + + /* return ((MFIB_ENTRY_FLAG_NONE == msrc->mfes_route_flags) && */ + /* (0 == fib_path_list_get_n_paths(msrc->mfes_pl)) && */ + /* (0 == hash_elts(msrc->mfes_itfs))); */ } @@ -922,18 +976,26 @@ mfib_entry_itf_remove (mfib_entry_src_t *msrc, hash_unset(msrc->mfes_itfs, sw_if_index); } +static int +mfib_entry_path_itf_based (const fib_route_path_t *rpath) +{ + return (!(rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP) && + ~0 != rpath->frp_sw_if_index); +} + void mfib_entry_path_update (fib_node_index_t mfib_entry_index, mfib_source_t source, - const fib_route_path_t *rpath, - mfib_itf_flags_t itf_flags) + const fib_route_path_t *rpaths) { - fib_node_index_t path_index; + fib_node_index_t* path_indices, path_index; + const fib_route_path_t *rpath; mfib_source_t current_best; mfib_path_ext_t *path_ext; mfib_entry_t *mfib_entry; mfib_entry_src_t *msrc; mfib_itf_flags_t old; + u32 ii; mfib_entry = mfib_entry_get(mfib_entry_index); ASSERT(NULL != mfib_entry); @@ -944,61 +1006,73 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index, * add the path to the path-list. If it's a duplicate we'll get * back the original path. */ - path_index = mfib_entry_src_path_add(msrc, rpath); - - /* - * find the path extension for that path - */ - path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index); + path_indices = mfib_entry_src_paths_add(msrc, rpaths); - if (NULL == path_ext) + vec_foreach_index(ii, path_indices) { - old = MFIB_ITF_FLAG_NONE; - path_ext = mfib_path_ext_add(msrc, path_index, itf_flags); - } - else - { - old = path_ext->mfpe_flags; - path_ext->mfpe_flags = itf_flags; - } + path_index = path_indices[ii]; + rpath = &rpaths[ii]; - /* - * Has the path changed its contribution to the input interface set. - * Which only paths with interfaces can do... - */ - if (~0 != rpath[0].frp_sw_if_index) - { - mfib_itf_t *mfib_itf; + if (FIB_NODE_INDEX_INVALID == path_index) + continue; - if (old != itf_flags) + /* + * find the path extension for that path + */ + path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index); + + if (NULL == path_ext) { - /* - * change of flag contributions - */ - mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs, - rpath[0].frp_sw_if_index); + old = MFIB_ITF_FLAG_NONE; + path_ext = mfib_path_ext_add(msrc, path_index, + rpath->frp_mitf_flags); + } + else + { + old = path_ext->mfpe_flags; + path_ext->mfpe_flags = rpath->frp_mitf_flags; + } - if (NULL == mfib_itf) - { - mfib_entry_itf_add(msrc, - rpath[0].frp_sw_if_index, - mfib_itf_create(path_index, itf_flags)); - } - else + /* + * Has the path changed its contribution to the input interface set. + * Which only paths with interfaces can do... + */ + if (mfib_entry_path_itf_based(rpath)) + { + mfib_itf_t *mfib_itf; + + if (old != rpath->frp_mitf_flags) { - if (mfib_itf_update(mfib_itf, - path_index, - itf_flags)) + /* + * change of flag contributions + */ + mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs, + rpath->frp_sw_if_index); + + if (NULL == mfib_itf) + { + mfib_entry_itf_add(msrc, + rpath->frp_sw_if_index, + mfib_itf_create(path_index, + rpath->frp_mitf_flags)); + } + else { - /* - * no more interface flags on this path, remove - * from the data-plane set - */ - mfib_entry_itf_remove(msrc, rpath[0].frp_sw_if_index); + if (mfib_itf_update(mfib_itf, + path_index, + rpath->frp_mitf_flags)) + { + /* + * no more interface flags on this path, remove + * from the data-plane set + */ + mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index); + } } } } } + vec_free(path_indices); mfib_entry_recalculate_forwarding(mfib_entry, current_best); } @@ -1012,12 +1086,14 @@ mfib_entry_path_update (fib_node_index_t mfib_entry_index, int mfib_entry_path_remove (fib_node_index_t mfib_entry_index, mfib_source_t source, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { - fib_node_index_t path_index; + fib_node_index_t path_index, *path_indices; + const fib_route_path_t *rpath; mfib_source_t current_best; mfib_entry_t *mfib_entry; mfib_entry_src_t *msrc; + u32 ii; mfib_entry = mfib_entry_get(mfib_entry_index); ASSERT(NULL != mfib_entry); @@ -1033,23 +1109,29 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index, } /* - * remove the path from the path-list. If it's not there we'll get - * back invalid + * remove the paths from the path-list. If it's not there we'll get + * back an empty vector */ - path_index = mfib_entry_src_path_remove(msrc, rpath); + path_indices = mfib_entry_src_paths_remove(msrc, rpaths); - if (FIB_NODE_INDEX_INVALID != path_index) + vec_foreach_index(ii, path_indices) { + path_index = path_indices[ii]; + rpath = &rpaths[ii]; + + if (FIB_NODE_INDEX_INVALID == path_index) + continue; + /* * don't need the extension, nor the interface anymore */ mfib_path_ext_remove(msrc, path_index); - if (~0 != rpath[0].frp_sw_if_index) + if (mfib_entry_path_itf_based(rpath)) { mfib_itf_t *mfib_itf; mfib_itf = mfib_entry_itf_find(msrc->mfes_itfs, - rpath[0].frp_sw_if_index); + rpath->frp_sw_if_index); if (mfib_itf_update(mfib_itf, path_index, @@ -1059,19 +1141,20 @@ mfib_entry_path_remove (fib_node_index_t mfib_entry_index, * no more interface flags on this path, remove * from the data-plane set */ - mfib_entry_itf_remove(msrc, rpath[0].frp_sw_if_index); + mfib_entry_itf_remove(msrc, rpath->frp_sw_if_index); } } - } - if (mfib_entry_src_ok_for_delete(msrc)) - { - /* - * this source has no interfaces and no flags. - * it has nothing left to give - remove it - */ - mfib_entry_src_remove(mfib_entry, source); + if (mfib_entry_src_ok_for_delete(msrc)) + { + /* + * this source has no interfaces and no flags. + * it has nothing left to give - remove it + */ + mfib_entry_src_remove(mfib_entry, source); + } } + vec_free(path_indices); mfib_entry_recalculate_forwarding(mfib_entry, current_best); @@ -1312,11 +1395,14 @@ mfib_entry_module_init (void) mfib_entry_logger = vlib_log_register_class("mfib", "entry"); } -void -mfib_entry_encode (fib_node_index_t mfib_entry_index, - fib_route_path_encode_t **api_rpaths) +fib_route_path_t* +mfib_entry_encode (fib_node_index_t mfib_entry_index) { + fib_path_encode_ctx_t ctx = { + .rpaths = NULL, + }; mfib_entry_t *mfib_entry; + fib_route_path_t *rpath; mfib_entry_src_t *bsrc; mfib_entry = mfib_entry_get(mfib_entry_index); @@ -1327,8 +1413,22 @@ mfib_entry_encode (fib_node_index_t mfib_entry_index, fib_path_list_walk_w_ext(bsrc->mfes_pl, NULL, fib_path_encode, - api_rpaths); + &ctx); } + + vec_foreach(rpath, ctx.rpaths) + { + mfib_itf_t *mfib_itf; + + mfib_itf = mfib_entry_itf_find(bsrc->mfes_itfs, + rpath->frp_sw_if_index); + if (mfib_itf) + { + rpath->frp_mitf_flags = mfib_itf->mfi_flags; + } + } + + return (ctx.rpaths); } const mfib_prefix_t *