diff options
author | Steven Luong <sluong@cisco.com> | 2024-07-08 11:21:23 -0700 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2024-07-15 20:57:35 +0000 |
commit | 67bae20b05cb46e5f6d19afeaf1f7a52a5309d59 (patch) | |
tree | 2c05544136add3eeb35e29228a6ca30bc8d064e4 /src | |
parent | ca2f2e1ec9131c01b340381f2cbbac2bc5951566 (diff) |
session: application namespace may reference a deleted vrf table
lock the vrf table when adding an application namespace and
unlock the vrf table when deleting an application namespace.
Free the session table when no more application namespace
uses it anymore to avoid memory leaks.
Type: fix
Change-Id: I10422c9a3b549bd4403962c925e29dd61a058eb0
Signed-off-by: Steven Luong <sluong@cisco.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/session/application_namespace.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/src/vnet/session/application_namespace.c b/src/vnet/session/application_namespace.c index f547dcfc031..2520188d88c 100644 --- a/src/vnet/session/application_namespace.c +++ b/src/vnet/session/application_namespace.c @@ -22,6 +22,12 @@ #include <vppinfra/format_table.h> #include <vlib/unix/unix.h> +/* + * fib source when locking the fib table + */ +static fib_source_t app_namespace_fib_src = FIB_SOURCE_INVALID; +static u32 *fib_index_to_lock_count[FIB_PROTOCOL_IP6 + 1]; + /** * Hash table of application namespaces by app ns ids */ @@ -81,6 +87,50 @@ app_namespace_alloc (const u8 *ns_id) return app_ns; } +static void +app_namespace_fib_table_lock (u32 fib_index, u32 protocol) +{ + fib_table_lock (fib_index, protocol, app_namespace_fib_src); + vec_validate (fib_index_to_lock_count[protocol], fib_index); + fib_index_to_lock_count[protocol][fib_index]++; + ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0); +} + +static void +app_namespace_fib_table_unlock (u32 fib_index, u32 protocol) +{ + fib_table_unlock (fib_index, protocol, app_namespace_fib_src); + ASSERT (fib_index_to_lock_count[protocol][fib_index] > 0); + fib_index_to_lock_count[protocol][fib_index]--; +} + +static void +app_namespace_del_global_table (app_namespace_t *app_ns) +{ + session_table_t *st; + u32 table_index; + + app_namespace_fib_table_unlock (app_ns->ip4_fib_index, FIB_PROTOCOL_IP4); + if (fib_index_to_lock_count[FIB_PROTOCOL_IP4][app_ns->ip4_fib_index] == 0) + { + table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, + app_ns->ip4_fib_index); + st = session_table_get (table_index); + if (st) + session_table_free (st, FIB_PROTOCOL_IP4); + } + + app_namespace_fib_table_unlock (app_ns->ip6_fib_index, FIB_PROTOCOL_IP6); + if (fib_index_to_lock_count[FIB_PROTOCOL_IP6][app_ns->ip6_fib_index] == 0) + { + table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, + app_ns->ip6_fib_index); + st = session_table_get (table_index); + if (st) + session_table_free (st, FIB_PROTOCOL_IP6); + } +} + session_error_t vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a) { @@ -136,12 +186,14 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a) app_ns->ns_secret = a->secret; app_ns->sw_if_index = a->sw_if_index; - app_ns->ip4_fib_index = - fib_table_find (FIB_PROTOCOL_IP4, a->ip4_fib_id); - app_ns->ip6_fib_index = - fib_table_find (FIB_PROTOCOL_IP6, a->ip6_fib_id); - session_lookup_set_tables_appns (app_ns); + app_ns->ip4_fib_index = fib_table_find (FIB_PROTOCOL_IP4, a->ip4_fib_id); + app_namespace_fib_table_lock (app_ns->ip4_fib_index, FIB_PROTOCOL_IP4); + + app_ns->ip6_fib_index = fib_table_find (FIB_PROTOCOL_IP6, a->ip6_fib_id); + app_namespace_fib_table_lock (app_ns->ip6_fib_index, FIB_PROTOCOL_IP6); + + session_lookup_set_tables_appns (app_ns); } else { @@ -164,6 +216,8 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a) if (app_ns->sock_name) vec_free (app_ns->sock_name); + app_namespace_del_global_table (app_ns); + app_namespace_free (app_ns); } @@ -236,6 +290,15 @@ app_namespaces_init (void) { u8 *ns_id = format (0, "default"); + /* We are not contributing any route to the fib. But we allocate a fib source + * so that when we lock the fib table, we can view that we have a lock on the + * particular fib table in case we wonder why the fib table is not free after + * "ip table del" + */ + if (app_namespace_fib_src == FIB_SOURCE_INVALID) + app_namespace_fib_src = fib_source_allocate ( + "application namespace", FIB_SOURCE_PRIORITY_LOW, FIB_SOURCE_BH_SIMPLE); + if (!app_namespace_lookup_table) app_namespace_lookup_table = hash_create_vec (0, sizeof (u8), sizeof (uword)); |