summaryrefslogtreecommitdiffstats
path: root/src/vnet/mfib/mfib_entry.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/mfib/mfib_entry.c')
-rw-r--r--src/vnet/mfib/mfib_entry.c224
1 files changed, 118 insertions, 106 deletions
diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c
index 18562219ce2..f169dc0886e 100644
--- a/src/vnet/mfib/mfib_entry.c
+++ b/src/vnet/mfib/mfib_entry.c
@@ -673,21 +673,12 @@ 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));
- /*
- * path-lists require a vector of paths
- */
- rpaths = NULL;
- vec_add1(rpaths, rpath[0]);
-
if (FIB_NODE_INDEX_INVALID == msrc->mfes_pl)
{
/* A non-shared path-list */
@@ -696,33 +687,16 @@ 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_flags));
- /*
- * 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
@@ -819,7 +793,12 @@ 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)));
+ 0 == fib_path_list_get_n_paths(msrc->mfes_pl)) &&
+ (0 == hash_elts(msrc->mfes_itfs)));
+
+ /* return ((MFIB_ENTRY_FLAG_NONE == msrc->mfes_flags) && */
+ /* (0 == fib_path_list_get_n_paths(msrc->mfes_pl)) && */
+ /* (0 == hash_elts(msrc->mfes_itfs))); */
}
@@ -931,18 +910,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);
@@ -953,61 +940,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);
+ path_indices = mfib_entry_src_paths_add(msrc, rpaths);
- /*
- * find the path extension for that path
- */
- path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index);
-
- 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;
+
+ /*
+ * find the path extension for that path
+ */
+ path_ext = mfib_entry_path_ext_find(msrc->mfes_exts, path_index);
- if (old != itf_flags)
+ 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)
{
- /*
- * 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_add(msrc,
+ rpath->frp_sw_if_index,
+ mfib_itf_create(path_index,
+ rpath->frp_mitf_flags));
+ }
+ else
+ {
+ 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);
}
@@ -1021,12 +1020,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);
@@ -1042,23 +1043,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,
@@ -1068,19 +1075,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);
@@ -1321,12 +1329,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_route_path_encode_t *api_rpath;
+ 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);
@@ -1337,20 +1347,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(api_rpath, *api_rpaths)
+ vec_foreach(rpath, ctx.rpaths)
{
mfib_itf_t *mfib_itf;
mfib_itf = mfib_entry_itf_find(bsrc->mfes_itfs,
- api_rpath->rpath.frp_sw_if_index);
+ rpath->frp_sw_if_index);
if (mfib_itf)
{
- api_rpath->rpath.frp_mitf_flags = mfib_itf->mfi_flags;
+ rpath->frp_mitf_flags = mfib_itf->mfi_flags;
}
}
+
+ return (ctx.rpaths);
}
const mfib_prefix_t *