aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/mfib
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2018-05-01 05:17:55 -0700
committerOle Trøan <otroan@employees.org>2019-06-18 13:31:39 +0000
commit097fa66b986f06281f603767d321ab13ab6c88c3 (patch)
treeed052819615d08ee4bd0afbc34de7e64e4598105 /src/vnet/mfib
parent39baa32186fd3e4b20d9f58afbbfe7b8daebed62 (diff)
fib: fib api updates
Enhance the route add/del APIs to take a set of paths rather than just one. Most unicast routing protocols calcualte all the available paths in one run of the algorithm so updating all the paths at once is beneficial for the client. two knobs control the behaviour: is_multipath - if set the the set of paths passed will be added to those that already exist, otherwise the set will replace them. is_add - add or remove the set is_add=0, is_multipath=1 and an empty set, results in deleting the route. It is also considerably faster to add multiple paths at once, than one at a time: vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.11 100000 routes in .572240 secs, 174751.80 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.12 100000 routes in .528383 secs, 189256.54 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.13 100000 routes in .757131 secs, 132077.52 routes/sec vat# ip_add_del_route 1.1.1.1/32 count 100000 multipath via 10.10.10.14 100000 routes in .878317 secs, 113854.12 routes/sec vat# ip_route_add_del 1.1.1.1/32 count 100000 multipath via 10.10.10.11 via 10.10.10.12 via 10.10.10.13 via 10.10.10.14 100000 routes in .900212 secs, 111084.93 routes/sec Change-Id: I416b93f7684745099c1adb0b33edac58c9339c1a Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Paul Vinciguerra <pvinci@vinciconsulting.com>
Diffstat (limited to 'src/vnet/mfib')
-rw-r--r--src/vnet/mfib/ip6_mfib.c14
-rw-r--r--src/vnet/mfib/mfib_api.c119
-rw-r--r--src/vnet/mfib/mfib_api.h38
-rw-r--r--src/vnet/mfib/mfib_entry.c224
-rw-r--r--src/vnet/mfib/mfib_entry.h6
-rw-r--r--src/vnet/mfib/mfib_table.c95
-rw-r--r--src/vnet/mfib/mfib_table.h25
-rw-r--r--src/vnet/mfib/mfib_types.api35
8 files changed, 414 insertions, 142 deletions
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c
index 31a92687e1a..5b15c8d1736 100644
--- a/src/vnet/mfib/ip6_mfib.c
+++ b/src/vnet/mfib/ip6_mfib.c
@@ -141,8 +141,9 @@ ip6_create_mfib_with_table_id (u32 table_id,
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
+ .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
};
pool_get_aligned(ip6_main.mfibs, mfib_table, CLIB_CACHE_LINE_BYTES);
@@ -180,8 +181,7 @@ ip6_create_mfib_with_table_id (u32 table_id,
mfib_table_entry_path_update(mfib_table->mft_index,
&pfx,
MFIB_SOURCE_SPECIAL,
- &path_for_us,
- MFIB_ITF_FLAG_FORWARD);
+ &path_for_us);
}));
return (mfib_table->mft_index);
@@ -200,7 +200,7 @@ ip6_mfib_table_destroy (ip6_mfib_t *mfib)
.frp_addr = zero_addr,
.frp_sw_if_index = 0xffffffff,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
.frp_flags = FIB_ROUTE_PATH_LOCAL,
};
@@ -236,7 +236,8 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
.frp_addr = zero_addr,
.frp_sw_if_index = sw_if_index,
.frp_fib_index = ~0,
- .frp_weight = 0,
+ .frp_weight = 1,
+ .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
};
mfib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP6,
@@ -253,8 +254,7 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
mfib_table_entry_path_update(mfib_index,
&pfx,
MFIB_SOURCE_SPECIAL,
- &path,
- MFIB_ITF_FLAG_ACCEPT);
+ &path);
});
}
else
diff --git a/src/vnet/mfib/mfib_api.c b/src/vnet/mfib/mfib_api.c
new file mode 100644
index 00000000000..bcab83ba0e5
--- /dev/null
+++ b/src/vnet/mfib/mfib_api.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/vnet.h>
+#include <vlibmemory/api.h>
+#include <vnet/mfib/mfib_api.h>
+#include <vnet/mfib/mfib_table.h>
+#include <vnet/fib/fib_api.h>
+#include <vnet/ip/ip_types_api.h>
+
+#include <vnet/vnet_msg_enum.h>
+
+#define vl_typedefs /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_typedefs
+
+#define vl_endianfun /* define message structures */
+#include <vnet/vnet_all_api_h.h>
+#undef vl_endianfun
+
+/* instantiate all the print functions we know about */
+#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
+#define vl_printfun
+#include <vnet/vnet_all_api_h.h>
+#undef vl_printfun
+
+static vl_api_mfib_itf_flags_t
+mfib_api_path_itf_flags_encode (mfib_itf_flags_t flags)
+{
+ vl_api_mfib_itf_flags_t out = MFIB_API_ITF_FLAG_NONE;
+
+ switch (flags)
+ {
+ case MFIB_ITF_FLAG_NONE:
+ out = MFIB_API_ITF_FLAG_NONE;
+ break;
+ case MFIB_ITF_FLAG_NEGATE_SIGNAL:
+ out = MFIB_API_ITF_FLAG_NEGATE_SIGNAL;
+ break;
+ case MFIB_ITF_FLAG_ACCEPT:
+ out = MFIB_API_ITF_FLAG_ACCEPT;
+ break;
+ case MFIB_ITF_FLAG_FORWARD:
+ out = MFIB_API_ITF_FLAG_FORWARD;
+ break;
+ case MFIB_ITF_FLAG_SIGNAL_PRESENT:
+ out = MFIB_API_ITF_FLAG_SIGNAL_PRESENT;
+ break;
+ case MFIB_ITF_FLAG_DONT_PRESERVE:
+ out = MFIB_API_ITF_FLAG_DONT_PRESERVE;
+ break;
+ }
+ return (ntohl(out));
+}
+
+void
+mfib_api_path_encode (const fib_route_path_t *in,
+ vl_api_mfib_path_t *out)
+{
+ out->itf_flags = mfib_api_path_itf_flags_encode(in->frp_mitf_flags);
+
+ fib_api_path_encode(in, &out->path);
+}
+
+static void
+mfib_api_path_itf_flags_decode (vl_api_mfib_itf_flags_t in,
+ mfib_itf_flags_t *out)
+{
+ in = clib_net_to_host_u32(in);
+
+ if (in & MFIB_API_ITF_FLAG_NONE)
+ *out |= MFIB_ITF_FLAG_NONE;
+ if (in & MFIB_API_ITF_FLAG_NEGATE_SIGNAL)
+ *out |= MFIB_ITF_FLAG_NEGATE_SIGNAL;
+ if (in & MFIB_API_ITF_FLAG_ACCEPT)
+ *out |= MFIB_ITF_FLAG_ACCEPT;
+ if (in & MFIB_API_ITF_FLAG_FORWARD)
+ *out |= MFIB_ITF_FLAG_FORWARD;
+ if (in & MFIB_API_ITF_FLAG_SIGNAL_PRESENT)
+ *out |= MFIB_ITF_FLAG_SIGNAL_PRESENT;
+ if (in & MFIB_API_ITF_FLAG_DONT_PRESERVE)
+ *out |= MFIB_ITF_FLAG_DONT_PRESERVE;
+}
+
+int
+mfib_api_path_decode (vl_api_mfib_path_t *in,
+ fib_route_path_t *out)
+{
+ mfib_api_path_itf_flags_decode(in->itf_flags, &out->frp_mitf_flags);
+
+ return (fib_api_path_decode(&in->path, out));
+}
+
+int
+mfib_api_table_id_decode (fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index)
+{
+ *fib_index = mfib_table_find(fproto, table_id);
+
+ if (INDEX_INVALID == *fib_index)
+ {
+ return VNET_API_ERROR_NO_SUCH_FIB;
+ }
+
+ return (0);
+}
diff --git a/src/vnet/mfib/mfib_api.h b/src/vnet/mfib/mfib_api.h
new file mode 100644
index 00000000000..f9c0a74bedb
--- /dev/null
+++ b/src/vnet/mfib/mfib_api.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MFIB_API_H__
+#define __MFIB_API_H__
+
+#include <vnet/mfib/mfib_types.h>
+
+/**
+ * Forward declare the API type, no need to include the generated api headers
+ */
+struct _vl_api_mfib_path;
+
+/**
+ * Encode and decode functions from the API types to internal types
+ */
+extern void mfib_api_path_encode(const fib_route_path_t *in,
+ struct _vl_api_mfib_path *out);
+extern int mfib_api_path_decode(struct _vl_api_mfib_path *in,
+ fib_route_path_t *out);
+
+extern int mfib_api_table_id_decode(fib_protocol_t fproto,
+ u32 table_id,
+ u32 *fib_index);
+
+#endif /* __MFIB_API_H__ */
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 *
diff --git a/src/vnet/mfib/mfib_entry.h b/src/vnet/mfib/mfib_entry.h
index 8ab7cee5ea7..4a1121bc9d5 100644
--- a/src/vnet/mfib/mfib_entry.h
+++ b/src/vnet/mfib/mfib_entry.h
@@ -135,8 +135,7 @@ extern int mfib_entry_special_add(fib_node_index_t fib_entry_index,
extern void mfib_entry_path_update(fib_node_index_t fib_entry_index,
mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t itf_flags);
+ const fib_route_path_t *rpath);
extern int mfib_entry_path_remove(fib_node_index_t fib_entry_index,
@@ -188,8 +187,7 @@ extern void mfib_entry_contribute_forwarding(
mfib_entry_fwd_flags_t flags,
dpo_id_t *dpo);
-extern void mfib_entry_encode(fib_node_index_t fib_entry_index,
- fib_route_path_encode_t **api_rpaths);
+extern fib_route_path_t* mfib_entry_encode(fib_node_index_t fib_entry_index);
extern void mfib_entry_module_init(void);
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c
index 68154b37ff8..504333a2474 100644
--- a/src/vnet/mfib/mfib_table.c
+++ b/src/vnet/mfib/mfib_table.c
@@ -286,12 +286,11 @@ mfib_table_entry_update (u32 fib_index,
return (mfib_entry_index);
}
-fib_node_index_t
-mfib_table_entry_path_update (u32 fib_index,
- const mfib_prefix_t *prefix,
- mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t itf_flags)
+static fib_node_index_t
+mfib_table_entry_paths_update_i (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
{
fib_node_index_t mfib_entry_index;
mfib_table_t *mfib_table;
@@ -308,30 +307,53 @@ mfib_table_entry_path_update (u32 fib_index,
MFIB_ENTRY_FLAG_NONE,
INDEX_INVALID);
- mfib_entry_path_update(mfib_entry_index,
- source,
- rpath,
- itf_flags);
+ mfib_entry_path_update(mfib_entry_index, source, rpaths);
mfib_table_entry_insert(mfib_table, prefix, mfib_entry_index);
}
else
{
- mfib_entry_path_update(mfib_entry_index,
- source,
- rpath,
- itf_flags);
+ mfib_entry_path_update(mfib_entry_index, source, rpaths);
}
return (mfib_entry_index);
}
-void
-mfib_table_entry_path_remove (u32 fib_index,
+
+fib_node_index_t
+mfib_table_entry_path_update (u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
const fib_route_path_t *rpath)
{
fib_node_index_t mfib_entry_index;
+ fib_route_path_t *rpaths = NULL;
+
+ vec_add1(rpaths, *rpath);
+
+ mfib_entry_index = mfib_table_entry_paths_update_i(fib_index, prefix,
+ source, rpaths);
+
+ vec_free(rpaths);
+ return (mfib_entry_index);
+}
+
+fib_node_index_t
+mfib_table_entry_paths_update (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ return (mfib_table_entry_paths_update_i(fib_index, prefix,
+ source, rpaths));
+}
+
+static void
+mfib_table_entry_paths_remove_i (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ fib_node_index_t mfib_entry_index;
mfib_table_t *mfib_table;
mfib_table = mfib_table_get(fib_index, prefix->fp_proto);
@@ -340,7 +362,7 @@ mfib_table_entry_path_remove (u32 fib_index,
if (FIB_NODE_INDEX_INVALID == mfib_entry_index)
{
/*
- * removing an etry that does not exist. i'll allow it.
+ * removing an entry that does not exist. i'll allow it.
*/
}
else
@@ -354,7 +376,7 @@ mfib_table_entry_path_remove (u32 fib_index,
no_more_sources = mfib_entry_path_remove(mfib_entry_index,
source,
- rpath);
+ rpaths);
if (no_more_sources)
{
@@ -367,6 +389,35 @@ mfib_table_entry_path_remove (u32 fib_index,
mfib_entry_unlock(mfib_entry_index);
}
}
+void
+mfib_table_entry_paths_remove (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpaths)
+{
+ mfib_table_entry_paths_remove_i(fib_index,
+ prefix,
+ source,
+ rpaths);
+}
+
+void
+mfib_table_entry_path_remove (u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpath)
+{
+ fib_route_path_t *rpaths = NULL;
+
+ vec_add1(rpaths, *rpath);
+
+ mfib_table_entry_paths_remove_i(fib_index,
+ prefix,
+ source,
+ rpaths);
+
+ vec_free(rpaths);
+}
fib_node_index_t
mfib_table_entry_special_add (u32 fib_index,
@@ -464,12 +515,10 @@ void
mfib_table_entry_delete_index (fib_node_index_t mfib_entry_index,
mfib_source_t source)
{
- const mfib_prefix_t *prefix;
-
- prefix = mfib_entry_get_prefix(mfib_entry_index);
-
mfib_table_entry_delete_i(mfib_entry_get_fib_index(mfib_entry_index),
- mfib_entry_index, prefix, source);
+ mfib_entry_index,
+ mfib_entry_get_prefix(mfib_entry_index),
+ source);
}
u32
diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h
index 6be4f798cd7..47461375a10 100644
--- a/src/vnet/mfib/mfib_table.h
+++ b/src/vnet/mfib/mfib_table.h
@@ -164,8 +164,11 @@ extern fib_node_index_t mfib_table_entry_update(u32 fib_index,
extern fib_node_index_t mfib_table_entry_path_update(u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
- const fib_route_path_t *rpath,
- mfib_itf_flags_t flags);
+ const fib_route_path_t *rpath);
+extern fib_node_index_t mfib_table_entry_paths_update(u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *rpath);
/**
* @brief
@@ -190,6 +193,10 @@ extern void mfib_table_entry_path_remove(u32 fib_index,
const mfib_prefix_t *prefix,
mfib_source_t source,
const fib_route_path_t *paths);
+extern void mfib_table_entry_paths_remove(u32 fib_index,
+ const mfib_prefix_t *prefix,
+ mfib_source_t source,
+ const fib_route_path_t *paths);
@@ -320,6 +327,20 @@ extern u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
*/
extern u32 mfib_table_find(fib_protocol_t proto, u32 table_id);
+/**
+ * @brief
+ * Get the Table-ID of the FIB from protocol and index
+ *
+ * @param fib_index
+ * The FIB index
+ *
+ * @paran proto
+ * The protocol of the FIB (and thus the entries therein)
+ *
+ * @return fib_index
+ * The tableID of the FIB
+ */
+extern u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto);
/**
* @brief
diff --git a/src/vnet/mfib/mfib_types.api b/src/vnet/mfib/mfib_types.api
new file mode 100644
index 00000000000..b2ba4329ea5
--- /dev/null
+++ b/src/vnet/mfib/mfib_types.api
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import "vnet/fib/fib_types.api";
+import "vnet/ip/ip_types.api";
+
+enum mfib_itf_flags
+{
+ MFIB_API_ITF_FLAG_NONE = 0,
+ MFIB_API_ITF_FLAG_NEGATE_SIGNAL = 0x1,
+ MFIB_API_ITF_FLAG_ACCEPT = 0x2,
+ MFIB_API_ITF_FLAG_FORWARD = 0x4,
+ MFIB_API_ITF_FLAG_SIGNAL_PRESENT = 0x8,
+ MFIB_API_ITF_FLAG_DONT_PRESERVE = 0x10,
+};
+
+/** \brief mFIB path
+*/
+typeonly define mfib_path
+{
+ vl_api_mfib_itf_flags_t itf_flags;
+ vl_api_fib_path_t path;
+};