acl-plugin: CLI to clear all sessions
It is useful to have the CLI to clear the existing sessions. There was a work-in-progress CLI but it did not work properly. Fix it and split into a separate "clear acl-plugin sessions", and add a unit test into the extended connection-oriented tests. Change-Id: I55889165ebcee139841fdac88747390903a05394 Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
This commit is contained in:
Andrew Yourtchenko
committed by
Ole Trøan
parent
a2b4ac1c13
commit
eb46754ef6
@ -1828,12 +1828,6 @@ acl_set_aclplugin_fn (vlib_main_t * vm,
|
||||
goto done;
|
||||
}
|
||||
if (unformat (input, "session")) {
|
||||
if (unformat (input, "clear")) {
|
||||
acl_main_t *am = &acl_main;
|
||||
vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index,
|
||||
ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX, ~0);
|
||||
goto done;
|
||||
}
|
||||
if (unformat (input, "table")) {
|
||||
/* The commands here are for tuning/testing. No user-serviceable parts inside */
|
||||
if (unformat (input, "max-entries")) {
|
||||
@ -2189,6 +2183,17 @@ acl_show_aclplugin_fn (vlib_main_t * vm,
|
||||
return error;
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
acl_clear_aclplugin_fn (vlib_main_t * vm,
|
||||
unformat_input_t * input,
|
||||
vlib_cli_command_t * cmd)
|
||||
{
|
||||
clib_error_t *error = 0;
|
||||
acl_main_t *am = &acl_main;
|
||||
vlib_process_signal_event (am->vlib_main, am->fa_cleaner_node_index,
|
||||
ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX, ~0);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_CLI_COMMAND (aclplugin_set_command, static) = {
|
||||
@ -2202,6 +2207,12 @@ VLIB_CLI_COMMAND (aclplugin_show_command, static) = {
|
||||
.short_help = "show acl-plugin {sessions|acl|interface|tables}",
|
||||
.function = acl_show_aclplugin_fn,
|
||||
};
|
||||
|
||||
VLIB_CLI_COMMAND (aclplugin_clear_command, static) = {
|
||||
.path = "clear acl-plugin sessions",
|
||||
.short_help = "clear acl-plugin sessions",
|
||||
.function = acl_clear_aclplugin_fn,
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
|
||||
|
@ -1465,6 +1465,7 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
{
|
||||
uword *clear_sw_if_index_bitmap = 0;
|
||||
uword *sw_if_index0;
|
||||
int clear_all = 0;
|
||||
#ifdef FA_NODE_VERBOSE_DEBUG
|
||||
clib_warning("ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX received");
|
||||
#endif
|
||||
@ -1476,7 +1477,17 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
("ACL_FA_NODE_CLEAN: ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX: %d",
|
||||
*sw_if_index0);
|
||||
#endif
|
||||
clear_sw_if_index_bitmap = clib_bitmap_set(clear_sw_if_index_bitmap, *sw_if_index0, 1);
|
||||
if (*sw_if_index0 == ~0)
|
||||
{
|
||||
clear_all = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pool_is_free_index (am->vnet_main->interface_main.sw_interfaces, *sw_if_index0))
|
||||
{
|
||||
clear_sw_if_index_bitmap = clib_bitmap_set(clear_sw_if_index_bitmap, *sw_if_index0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef FA_NODE_VERBOSE_DEBUG
|
||||
clib_warning("ACL_FA_CLEANER_DELETE_BY_SW_IF_INDEX bitmap: %U", format_bitmap_hex, clear_sw_if_index_bitmap);
|
||||
@ -1496,7 +1507,15 @@ acl_fa_session_cleaner_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
|
||||
if (pw0->clear_in_process) {
|
||||
clib_warning("ERROR-BUG! Could not initiate cleaning on worker because another cleanup in progress");
|
||||
} else {
|
||||
pw0->pending_clear_sw_if_index_bitmap = clib_bitmap_dup(clear_sw_if_index_bitmap);
|
||||
if (clear_all)
|
||||
{
|
||||
/* if we need to clear all, then just clear the interfaces that we are servicing */
|
||||
pw0->pending_clear_sw_if_index_bitmap = clib_bitmap_dup(pw0->serviced_sw_if_index_bitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
pw0->pending_clear_sw_if_index_bitmap = clib_bitmap_dup(clear_sw_if_index_bitmap);
|
||||
}
|
||||
pw0->clear_in_process = 1;
|
||||
}
|
||||
}
|
||||
|
@ -279,6 +279,27 @@ class ACLPluginConnTestCase(VppTestCase):
|
||||
# If it didn't - it is a problem
|
||||
self.assert_equal(p2, None, "packet on long-idle conn")
|
||||
|
||||
def run_clear_conn_test(self, af, acl_side):
|
||||
""" Clear the connections via CLI """
|
||||
conn1 = Conn(self, self.pg0, self.pg1, af, UDP, 42001, 4242)
|
||||
conn1.apply_acls(0, acl_side)
|
||||
conn1.send_through(0)
|
||||
# the return packets should pass
|
||||
conn1.send_through(1)
|
||||
# send some packets on conn1, ensure it doesn't go away
|
||||
for i in IterateWithSleep(self, 20, "Keep conn active", 0.3):
|
||||
conn1.send_through(1)
|
||||
# clear all connections
|
||||
self.vapi.ppcli("clear acl-plugin sessions")
|
||||
# now try to send a packet on the reflected side
|
||||
try:
|
||||
p2 = conn1.send_through(1).command()
|
||||
except:
|
||||
# If we asserted while waiting, it's good.
|
||||
# the conn should have timed out.
|
||||
p2 = None
|
||||
self.assert_equal(p2, None, "packet on supposedly deleted conn")
|
||||
|
||||
def test_0000_conn_prepare_test(self):
|
||||
""" Prepare the settings """
|
||||
self.vapi.ppcli("set acl-plugin session timeout udp idle 1")
|
||||
@ -291,6 +312,14 @@ class ACLPluginConnTestCase(VppTestCase):
|
||||
""" IPv4: Basic conn timeout test reflect on egress """
|
||||
self.run_basic_conn_test(AF_INET, 1)
|
||||
|
||||
def test_0005_clear_conn_test(self):
|
||||
""" IPv4: reflect egress, clear conn """
|
||||
self.run_clear_conn_test(AF_INET, 1)
|
||||
|
||||
def test_0006_clear_conn_test(self):
|
||||
""" IPv4: reflect ingress, clear conn """
|
||||
self.run_clear_conn_test(AF_INET, 0)
|
||||
|
||||
def test_0011_active_conn_test(self):
|
||||
""" IPv4: Idle conn behind active conn, reflect on ingress """
|
||||
self.run_active_conn_test(AF_INET, 0)
|
||||
@ -307,6 +336,14 @@ class ACLPluginConnTestCase(VppTestCase):
|
||||
""" IPv6: Basic conn timeout test reflect on egress """
|
||||
self.run_basic_conn_test(AF_INET6, 1)
|
||||
|
||||
def test_1005_clear_conn_test(self):
|
||||
""" IPv6: reflect egress, clear conn """
|
||||
self.run_clear_conn_test(AF_INET6, 1)
|
||||
|
||||
def test_1006_clear_conn_test(self):
|
||||
""" IPv6: reflect ingress, clear conn """
|
||||
self.run_clear_conn_test(AF_INET6, 0)
|
||||
|
||||
def test_1011_active_conn_test(self):
|
||||
""" IPv6: Idle conn behind active conn, reflect on ingress """
|
||||
self.run_active_conn_test(AF_INET6, 0)
|
||||
|
Reference in New Issue
Block a user