aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/mfib
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/mfib')
-rw-r--r--src/vnet/mfib/ip4_mfib.c12
-rw-r--r--src/vnet/mfib/ip4_mfib.h5
-rw-r--r--src/vnet/mfib/ip6_mfib.c12
-rw-r--r--src/vnet/mfib/ip6_mfib.h5
-rw-r--r--src/vnet/mfib/mfib_entry.c11
-rw-r--r--src/vnet/mfib/mfib_entry.h2
-rw-r--r--src/vnet/mfib/mfib_table.c88
-rw-r--r--src/vnet/mfib/mfib_table.h29
-rw-r--r--src/vnet/mfib/mfib_test.c11
-rw-r--r--src/vnet/mfib/mfib_types.h8
10 files changed, 149 insertions, 34 deletions
diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c
index 1849a3a4201..b2482580678 100644
--- a/src/vnet/mfib/ip4_mfib.c
+++ b/src/vnet/mfib/ip4_mfib.c
@@ -33,7 +33,8 @@ static const mfib_prefix_t ip4_specials[] = {
};
static u32
-ip4_create_mfib_with_table_id (u32 table_id)
+ip4_create_mfib_with_table_id (u32 table_id,
+ mfib_source_t src)
{
mfib_table_t *mfib_table;
@@ -53,7 +54,7 @@ ip4_create_mfib_with_table_id (u32 table_id)
mfib_table->v4.table_id =
table_id;
- mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4);
+ mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP4, src);
/*
* add the special entries into the new FIB
@@ -113,14 +114,15 @@ ip4_mfib_table_destroy (ip4_mfib_t *mfib)
}
u32
-ip4_mfib_table_find_or_create_and_lock (u32 table_id)
+ip4_mfib_table_find_or_create_and_lock (u32 table_id,
+ mfib_source_t src)
{
u32 index;
index = ip4_mfib_index_from_table_id(table_id);
if (~0 == index)
- return ip4_create_mfib_with_table_id(table_id);
- mfib_table_lock(index, FIB_PROTOCOL_IP4);
+ return ip4_create_mfib_with_table_id(table_id, src);
+ mfib_table_lock(index, FIB_PROTOCOL_IP4, src);
return (index);
}
diff --git a/src/vnet/mfib/ip4_mfib.h b/src/vnet/mfib/ip4_mfib.h
index ea682651767..e31fb744b9b 100644
--- a/src/vnet/mfib/ip4_mfib.h
+++ b/src/vnet/mfib/ip4_mfib.h
@@ -72,8 +72,9 @@ ip4_mfib_get (u32 index)
* @returns A pointer to the retrieved or created fib.
*
*/
-extern u32 ip4_mfib_table_find_or_create_and_lock(u32 table_id);
-extern u32 ip4_mfib_table_create_and_lock(void);
+extern u32 ip4_mfib_table_find_or_create_and_lock(u32 table_id,
+ mfib_source_t src);
+extern u32 ip4_mfib_table_create_and_lock(mfib_source_t src);
static inline
u32 ip4_mfib_index_from_table_id (u32 table_id)
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c
index 5e48e9193b5..e4861330654 100644
--- a/src/vnet/mfib/ip6_mfib.c
+++ b/src/vnet/mfib/ip6_mfib.c
@@ -151,7 +151,8 @@ static const ip6_mfib_special_t ip6_mfib_specials[] =
static u32
-ip6_create_mfib_with_table_id (u32 table_id)
+ip6_create_mfib_with_table_id (u32 table_id,
+ mfib_source_t src)
{
mfib_table_t *mfib_table;
mfib_prefix_t pfx = {
@@ -182,7 +183,7 @@ ip6_create_mfib_with_table_id (u32 table_id)
mfib_table->v6.table_id =
table_id;
- mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6);
+ mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6, src);
mfib_table->v6.rhead =
clib_mem_alloc_aligned (sizeof(*mfib_table->v6.rhead),
@@ -297,14 +298,15 @@ ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
}
u32
-ip6_mfib_table_find_or_create_and_lock (u32 table_id)
+ip6_mfib_table_find_or_create_and_lock (u32 table_id,
+ mfib_source_t src)
{
u32 index;
index = ip6_mfib_index_from_table_id(table_id);
if (~0 == index)
- return ip6_create_mfib_with_table_id(table_id);
- mfib_table_lock(index, FIB_PROTOCOL_IP6);
+ return ip6_create_mfib_with_table_id(table_id, src);
+ mfib_table_lock(index, FIB_PROTOCOL_IP6, src);
return (index);
}
diff --git a/src/vnet/mfib/ip6_mfib.h b/src/vnet/mfib/ip6_mfib.h
index adaa7ec24fe..ea81b553cd5 100644
--- a/src/vnet/mfib/ip6_mfib.h
+++ b/src/vnet/mfib/ip6_mfib.h
@@ -79,8 +79,9 @@ ip6_mfib_get (u32 index)
* @returns A pointer to the retrieved or created fib.
*
*/
-extern u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id);
-extern u32 ip6_mfib_table_create_and_lock(void);
+extern u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id,
+ mfib_source_t src);
+extern u32 ip6_mfib_table_create_and_lock(mfib_source_t src);
static inline
diff --git a/src/vnet/mfib/mfib_entry.c b/src/vnet/mfib/mfib_entry.c
index 804e10ab0e2..2302b9a1707 100644
--- a/src/vnet/mfib/mfib_entry.c
+++ b/src/vnet/mfib/mfib_entry.c
@@ -334,6 +334,17 @@ mfib_entry_get_best_src (const mfib_entry_t *mfib_entry)
return (bsrc);
}
+int
+mfib_entry_is_sourced (fib_node_index_t mfib_entry_index,
+ mfib_source_t source)
+{
+ mfib_entry_t *mfib_entry;
+
+ mfib_entry = mfib_entry_get(mfib_entry_index);
+
+ return (NULL != mfib_entry_src_find(mfib_entry, source, NULL));
+}
+
static void
mfib_entry_src_flush (mfib_entry_src_t *msrc)
{
diff --git a/src/vnet/mfib/mfib_entry.h b/src/vnet/mfib/mfib_entry.h
index d4377878a2c..96ee49f799e 100644
--- a/src/vnet/mfib/mfib_entry.h
+++ b/src/vnet/mfib/mfib_entry.h
@@ -130,6 +130,8 @@ extern void mfib_entry_unlock(fib_node_index_t fib_entry_index);
extern void mfib_entry_get_prefix(fib_node_index_t fib_entry_index,
mfib_prefix_t *pfx);
extern u32 mfib_entry_get_fib_index(fib_node_index_t fib_entry_index);
+extern int mfib_entry_is_sourced(fib_node_index_t fib_entry_index,
+ mfib_source_t source);
extern void mfib_entry_contribute_forwarding(
fib_node_index_t mfib_entry_index,
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c
index 7ffe8941e75..e5550adc8f7 100644
--- a/src/vnet/mfib/mfib_table.c
+++ b/src/vnet/mfib/mfib_table.c
@@ -424,7 +424,8 @@ mfib_table_find (fib_protocol_t proto,
u32
mfib_table_find_or_create_and_lock (fib_protocol_t proto,
- u32 table_id)
+ u32 table_id,
+ mfib_source_t src)
{
mfib_table_t *mfib_table;
fib_node_index_t fi;
@@ -432,10 +433,10 @@ mfib_table_find_or_create_and_lock (fib_protocol_t proto,
switch (proto)
{
case FIB_PROTOCOL_IP4:
- fi = ip4_mfib_table_find_or_create_and_lock(table_id);
+ fi = ip4_mfib_table_find_or_create_and_lock(table_id, src);
break;
case FIB_PROTOCOL_IP6:
- fi = ip6_mfib_table_find_or_create_and_lock(table_id);
+ fi = ip6_mfib_table_find_or_create_and_lock(table_id, src);
break;
case FIB_PROTOCOL_MPLS:
default:
@@ -451,6 +452,59 @@ mfib_table_find_or_create_and_lock (fib_protocol_t proto,
return (fi);
}
+/**
+ * @brief Table flush context. Store the indicies of matching FIB entries
+ * that need to be removed.
+ */
+typedef struct mfib_table_flush_ctx_t_
+{
+ /**
+ * The list of entries to flush
+ */
+ fib_node_index_t *mftf_entries;
+
+ /**
+ * The source we are flushing
+ */
+ mfib_source_t mftf_source;
+} mfib_table_flush_ctx_t;
+
+static int
+mfib_table_flush_cb (fib_node_index_t mfib_entry_index,
+ void *arg)
+{
+ mfib_table_flush_ctx_t *ctx = arg;
+
+ if (mfib_entry_is_sourced(mfib_entry_index, ctx->mftf_source))
+ {
+ vec_add1(ctx->mftf_entries, mfib_entry_index);
+ }
+ return (1);
+}
+
+void
+mfib_table_flush (u32 mfib_index,
+ fib_protocol_t proto,
+ mfib_source_t source)
+{
+ fib_node_index_t *mfib_entry_index;
+ mfib_table_flush_ctx_t ctx = {
+ .mftf_entries = NULL,
+ .mftf_source = source,
+ };
+
+ mfib_table_walk(mfib_index, proto,
+ mfib_table_flush_cb,
+ &ctx);
+
+ vec_foreach(mfib_entry_index, ctx.mftf_entries)
+ {
+ mfib_table_entry_delete_index(*mfib_entry_index, source);
+ }
+
+ vec_free(ctx.mftf_entries);
+}
+
static void
mfib_table_destroy (mfib_table_t *mfib_table)
{
@@ -472,27 +526,43 @@ mfib_table_destroy (mfib_table_t *mfib_table)
void
mfib_table_unlock (u32 fib_index,
- fib_protocol_t proto)
+ fib_protocol_t proto,
+ mfib_source_t source)
{
mfib_table_t *mfib_table;
mfib_table = mfib_table_get(fib_index, proto);
- mfib_table->mft_locks--;
+ mfib_table->mft_locks[source]--;
+ mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS]--;
+
+ if (0 == mfib_table->mft_locks[source])
+ {
+ /*
+ * The source no longer needs the table. flush any routes
+ * from it just in case
+ */
+ mfib_table_flush(fib_index, proto, source);
+ }
- if (0 == mfib_table->mft_locks)
+ if (0 == mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS])
{
- mfib_table_destroy(mfib_table);
+ /*
+ * no more locak from any source - kill it
+ */
+ mfib_table_destroy(mfib_table);
}
}
void
mfib_table_lock (u32 fib_index,
- fib_protocol_t proto)
+ fib_protocol_t proto,
+ mfib_source_t source)
{
mfib_table_t *mfib_table;
mfib_table = mfib_table_get(fib_index, proto);
- mfib_table->mft_locks++;
+ mfib_table->mft_locks[source]++;
+ mfib_table->mft_locks[MFIB_TABLE_TOTAL_LOCKS]++;
}
void
diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h
index 83aa04ef797..c6b0b0973a1 100644
--- a/src/vnet/mfib/mfib_table.h
+++ b/src/vnet/mfib/mfib_table.h
@@ -23,6 +23,12 @@
#include <vnet/mfib/mfib_types.h>
/**
+ * Keep a lock per-source and a total
+ */
+#define MFIB_TABLE_N_LOCKS (MFIB_N_SOURCES+1)
+#define MFIB_TABLE_TOTAL_LOCKS MFIB_N_SOURCES
+
+/**
* @brief
* A protocol Independent IP multicast FIB table
*/
@@ -47,7 +53,7 @@ typedef struct mfib_table_t_
/**
* number of locks on the table
*/
- u16 mft_locks;
+ u16 mft_locks[MFIB_TABLE_N_LOCKS];
/**
* Table ID (hash key) for this FIB.
@@ -259,7 +265,8 @@ extern fib_node_index_t mfib_table_entry_special_add(u32 fib_index,
* the source to flush
*/
extern void mfib_table_flush(u32 fib_index,
- fib_protocol_t proto);
+ fib_protocol_t proto,
+ mfib_source_t source);
/**
* @brief
@@ -307,9 +314,13 @@ extern u32 mfib_table_find(fib_protocol_t proto, u32 table_id);
*
* @return fib_index
* The index of the FIB
+ *
+ * @param source
+ * The ID of the client/source.
*/
extern u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto,
- u32 table_id);
+ u32 table_id,
+ mfib_source_t source);
/**
@@ -321,9 +332,13 @@ extern u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto,
*
* @paran proto
* The protocol of the FIB (and thus the entries therein)
+ *
+ * @param source
+ * The ID of the client/source.
*/
extern void mfib_table_unlock(u32 fib_index,
- fib_protocol_t proto);
+ fib_protocol_t proto,
+ mfib_source_t source);
/**
* @brief
@@ -335,9 +350,13 @@ extern void mfib_table_unlock(u32 fib_index,
*
* @paran proto
* The protocol of the FIB (and thus the entries therein)
+ *
+ * @param source
+ * The ID of the client/source.
*/
extern void mfib_table_lock(u32 fib_index,
- fib_protocol_t proto);
+ fib_protocol_t proto,
+ mfib_source_t source);
/**
* @brief
diff --git a/src/vnet/mfib/mfib_test.c b/src/vnet/mfib/mfib_test.c
index 57787eca641..3055844dd59 100644
--- a/src/vnet/mfib/mfib_test.c
+++ b/src/vnet/mfib/mfib_test.c
@@ -22,6 +22,7 @@
#include <vnet/fib/fib_path_list.h>
#include <vnet/fib/fib_test.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/fib/mpls_fib.h>
#include <vnet/dpo/replicate_dpo.h>
#include <vnet/adj/adj_mcast.h>
@@ -366,7 +367,7 @@ mfib_test_i (fib_protocol_t PROTO,
MFIB_TEST(3 == adj_mcast_db_size(), "3 MCAST adjs");
/* Find or create FIB table 11 */
- fib_index = mfib_table_find_or_create_and_lock(PROTO, 11);
+ fib_index = mfib_table_find_or_create_and_lock(PROTO, 11, MFIB_SOURCE_API);
mfib_prefix_t pfx_dft = {
.fp_len = 0,
@@ -1113,9 +1114,10 @@ mfib_test_i (fib_protocol_t PROTO,
/*
* MPLS enable an interface so we get the MPLS table created
*/
+ mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
mpls_sw_interface_enable_disable(&mpls_main,
tm->hw[0]->sw_if_index,
- 1);
+ 1, 0);
lfei = fib_table_entry_update_one_path(0, // default MPLS Table
&pfx_3500,
@@ -1192,7 +1194,7 @@ mfib_test_i (fib_protocol_t PROTO,
/*
* Unlock the table - it's the last lock so should be gone thereafter
*/
- mfib_table_unlock(fib_index, PROTO);
+ mfib_table_unlock(fib_index, PROTO, MFIB_SOURCE_API);
MFIB_TEST((FIB_NODE_INDEX_INVALID ==
mfib_table_find(PROTO, fib_index)),
@@ -1207,7 +1209,8 @@ mfib_test_i (fib_protocol_t PROTO,
*/
mpls_sw_interface_enable_disable(&mpls_main,
tm->hw[0]->sw_if_index,
- 0);
+ 0, 0);
+ mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
/*
* test we've leaked no resources
diff --git a/src/vnet/mfib/mfib_types.h b/src/vnet/mfib/mfib_types.h
index 863fad169a5..50aede044ec 100644
--- a/src/vnet/mfib/mfib_types.h
+++ b/src/vnet/mfib/mfib_types.h
@@ -166,9 +166,10 @@ typedef enum mfib_source_t_
MFIB_SOURCE_VXLAN,
MFIB_SOURCE_DHCP,
MFIB_SOURCE_SRv6,
- MFIB_SOURCE_DEFAULT_ROUTE,
MFIB_SOURCE_GTPU,
MFIB_SOURCE_VXLAN_GPE,
+ MFIB_SOURCE_RR,
+ MFIB_SOURCE_DEFAULT_ROUTE,
} mfib_source_t;
#define MFIB_SOURCE_NAMES { \
@@ -178,11 +179,14 @@ typedef enum mfib_source_t_
[MFIB_SOURCE_DHCP] = "DHCP", \
[MFIB_SOURCE_VXLAN] = "VXLAN", \
[MFIB_SOURCE_SRv6] = "SRv6", \
- [MFIB_SOURCE_DEFAULT_ROUTE] = "Default Route", \
[MFIB_SOURCE_GTPU] = "GTPU", \
[MFIB_SOURCE_VXLAN_GPE] = "VXLAN-GPE", \
+ [MFIB_SOURCE_RR] = "Recursive-resolution", \
+ [MFIB_SOURCE_DEFAULT_ROUTE] = "Default Route", \
}
+#define MFIB_N_SOURCES (MFIB_SOURCE_DEFAULT_ROUTE)
+
/**
* \brief Compare two prefixes for equality
*/