#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
*/
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)
{
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
{
if (app_ns->sock_name)
vec_free (app_ns->sock_name);
+ app_namespace_del_global_table (app_ns);
+
app_namespace_free (app_ns);
}
{
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));
self.logger.debug(self.vapi.cli("show ip fib"))
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0,
+ namespace_id=self.server_appns,
+ secret=self.server_appns_secret,
+ sw_if_index=self.loop0.sw_if_index,
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0,
+ namespace_id=self.client_appns,
+ secret=self.client_appns_secret,
+ sw_if_index=self.loop1.sw_if_index,
+ )
# Delete inter-table routes
self.ip_t01.remove_vpp_config()
self.ip_t10.remove_vpp_config()
i.set_table_ip4(0)
i.admin_down()
+ # Unconfigure namespaces - remove our locks to the vrf tables
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
super(TestSession, self).tearDown()
self.vapi.session_enable_disable(is_enable=1)
)
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
)
def tearDown(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
self.logger.debug(self.vapi.cli("show ip fib"))
def thru_host_stack_tear_down(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip4()
i.set_table_ip4(0)
self.logger.debug(self.vapi.cli("show ip6 fib"))
def thru_host_stack_ipv6_tear_down(self):
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
+ )
for i in self.lo_interfaces:
i.unconfig_ip6()
i.set_table_ip6(0)
iperf3, self.server_iperf3_args, iperf3, self.client_iperf3_args
)
+
+class LDPThruHostStackIperfMss(VCLTestCase):
+ """LDP Thru Host Stack Iperf with MSS"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(LDPThruHostStackIperfMss, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(LDPThruHostStackIperfMss, cls).tearDownClass()
+
+ def setUp(self):
+ super(LDPThruHostStackIperfMss, self).setUp()
+
+ self.thru_host_stack_setup()
+ self.client_iperf3_timeout = 20
+ self.client_iperf3_args = ["-4", "-t 2", "-c", self.loop0.local_ip4]
+ self.server_iperf3_args = ["-4", "-s"]
+
+ def tearDown(self):
+ self.thru_host_stack_tear_down()
+ super(LDPThruHostStackIperfMss, self).tearDown()
+
+ def show_commands_at_teardown(self):
+ self.logger.debug(self.vapi.cli("show session verbose 2"))
+ self.logger.debug(self.vapi.cli("show app mq"))
+
@unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
def test_ldp_thru_host_stack_iperf3_mss(self):
"""run LDP thru host stack iperf3 test with mss option"""
i.unconfig_ip4()
i.set_table_ip4(0)
i.admin_down()
+ # Unconfigure namespaces - remove our locks to the vrf tables
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
self.vapi.session_enable_disable(is_enable=0)
super(TestUDP, self).tearDown()