tests: reduce sleep interval in ikev2 sa rekey test 54/41954/8
authorIvan Ivanets <iivanets@cisco.com>
Mon, 2 Dec 2024 21:10:10 +0000 (21:10 +0000)
committerBenoit Ganne <bganne@cisco.com>
Wed, 8 Jan 2025 08:11:49 +0000 (08:11 +0000)
Type: test

The sleep interval for this test is set to 0.1 seconds instead of
the default 2 seconds. This change is necessary because the test
verifies the expiration of old IPsec SAs
(self.fail("old IPsec SA not expired")) within a strict timeframe.
A longer sleep interval, such as 2 seconds, would significantly
delay the loop iterations, reducing the granularity of checks for
SA expiration and increasing the risk of false failures.

By setting the sleep interval to 0.1 seconds:
- The test can perform frequent checks for the status of IPsec SAs
- It reduces the likelihood of the test prematurely failing

Change-Id: I92ac3de0f33838620b51083d240043e62f37c490
Signed-off-by: Ivan Ivanets <iivanets@cisco.com>
src/plugins/ikev2/ikev2.api
src/plugins/ikev2/ikev2.c
src/plugins/ikev2/ikev2.h
src/plugins/ikev2/ikev2_api.c
src/plugins/ikev2/ikev2_cli.c
src/plugins/ikev2/ikev2_priv.h
src/plugins/ikev2/ikev2_test.c
test/test_ikev2.py

index e2ff8fb..e01d733 100644 (file)
@@ -42,6 +42,38 @@ define ikev2_plugin_get_version_reply
   u32 minor;
 };
 
+/** \brief IKEv2: Set sleep interval for ikev2_manager_process node
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param timeout - sleep timeout duration in seconds
+*/
+autoreply define ikev2_plugin_set_sleep_interval
+{
+  u32 client_index;
+  u32 context;
+
+  f64 timeout;
+};
+
+/** \brief IKEv2: Get the current sleep interval for the ikev2_manager_process
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply with request
+*/
+define ikev2_get_sleep_interval {
+    u32 client_index;
+    u32 context;
+};
+
+/** \brief IKEv2: Reply with the current sleep interval
+    @param context - sender context, to match reply with request
+    @param sleep_interval - current sleep interval in seconds
+*/
+define ikev2_get_sleep_interval_reply {
+    u32 context;
+    i32 retval;
+    f64 sleep_interval;
+};
+
 /** \brief Dump all profiles
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
index f66469a..0e6751c 100644 (file)
@@ -33,6 +33,7 @@
 
 #define IKEV2_LIVENESS_RETRIES 3
 #define IKEV2_LIVENESS_PERIOD_CHECK 30
+#define IKEV2_SLEEP_INTERVAL       2.0
 
 ikev2_main_t ikev2_main;
 
@@ -5139,6 +5140,8 @@ ikev2_init (vlib_main_t * vm)
   km->vnet_main = vnet_get_main ();
   km->vlib_main = vm;
 
+  km->sleep_interval = IKEV2_SLEEP_INTERVAL;
+
   km->liveness_period = IKEV2_LIVENESS_PERIOD_CHECK;
   km->liveness_max_retries = IKEV2_LIVENESS_RETRIES;
 
@@ -5302,6 +5305,25 @@ ikev2_set_liveness_params (u32 period, u32 max_retries)
   return 0;
 }
 
+clib_error_t *
+ikev2_set_sleep_interval (f64 interval)
+{
+  ikev2_main_t *km = &ikev2_main;
+
+  if (interval == 0.0)
+    return clib_error_return (0, "invalid arg");
+
+  km->sleep_interval = interval;
+  return 0;
+}
+
+f64
+ikev2_get_sleep_interval ()
+{
+  ikev2_main_t *km = &ikev2_main;
+  return km->sleep_interval;
+}
+
 clib_error_t *
 ikev2_profile_natt_disable (u8 * name)
 {
@@ -5539,7 +5561,7 @@ ikev2_mngr_process_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
 
   while (1)
     {
-      vlib_process_wait_for_event_or_clock (vm, 2);
+      vlib_process_wait_for_event_or_clock (vm, km->sleep_interval);
       vlib_process_get_events (vm, NULL);
 
       /* process ike child sas */
index 9ed0ecc..af4f3a0 100644 (file)
@@ -444,6 +444,10 @@ uword unformat_ikev2_transform_esn_type (unformat_input_t * input,
 
 clib_error_t *ikev2_set_liveness_params (u32 period, u32 max_retries);
 
+clib_error_t *ikev2_set_sleep_interval (f64 interval);
+
+f64 ikev2_get_sleep_interval ();
+
 #endif /* __included_ikev2_h__ */
 
 
index e09bde3..19af061 100644 (file)
@@ -780,6 +780,38 @@ static void
   REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_LIVENESS_REPLY);
 }
 
+static void
+vl_api_ikev2_plugin_set_sleep_interval_t_handler (
+  vl_api_ikev2_plugin_set_sleep_interval_t *mp)
+{
+  vl_api_ikev2_plugin_set_sleep_interval_reply_t *rmp;
+  int rv = 0;
+  clib_error_t *error;
+  error = ikev2_set_sleep_interval (clib_net_to_host_f64 (mp->timeout));
+
+  if (error)
+    {
+      ikev2_log_error ("%U", format_clib_error, error);
+      clib_error_free (error);
+      rv = VNET_API_ERROR_UNSPECIFIED;
+    }
+  REPLY_MACRO (VL_API_IKEV2_PLUGIN_SET_SLEEP_INTERVAL_REPLY);
+}
+
+static void
+vl_api_ikev2_get_sleep_interval_t_handler (
+  vl_api_ikev2_get_sleep_interval_t *mp)
+{
+  vl_api_ikev2_get_sleep_interval_reply_t *rmp;
+  int rv = 0;
+
+  f64 sleep_interval = ikev2_get_sleep_interval ();
+
+  REPLY_MACRO2 (VL_API_IKEV2_GET_SLEEP_INTERVAL_REPLY, ({
+                 rmp->sleep_interval = clib_host_to_net_f64 (sleep_interval);
+               }));
+}
+
 static void
 vl_api_ikev2_profile_add_del_t_handler (vl_api_ikev2_profile_add_del_t * mp)
 {
index 975774c..c87fe73 100644 (file)
@@ -715,6 +715,60 @@ VLIB_CLI_COMMAND (set_ikev2_liveness_command, static) = {
   .function = set_ikev2_liveness_period_fn,
 };
 
+static clib_error_t *
+set_ikev2_sleep_interval_fn (vlib_main_t *vm, unformat_input_t *input,
+                            vlib_cli_command_t *cmd)
+{
+  unformat_input_t _line_input, *line_input = &_line_input;
+  clib_error_t *r = 0;
+  f64 interval = 0.0;
+
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "%lf", &interval))
+       {
+         r = ikev2_set_sleep_interval (interval);
+         goto done;
+       }
+      else
+       break;
+    }
+
+  r = clib_error_return (0, "parse error: '%U'", format_unformat_error,
+                        line_input);
+
+done:
+  unformat_free (line_input);
+  return r;
+}
+
+VLIB_CLI_COMMAND (set_ikev2_sleep_interval, static) = {
+  .path = "ikev2 set sleep interval",
+  .short_help = "ikev2 set sleep interval <timeout>",
+  .function = set_ikev2_sleep_interval_fn,
+};
+
+static clib_error_t *
+show_ikev2_sleep_interval_command_fn (vlib_main_t *vm, unformat_input_t *input,
+                                     vlib_cli_command_t *cmd)
+{
+  f64 sleep_interval = ikev2_get_sleep_interval ();
+
+  vlib_cli_output (vm, "IKEv2 Manager sleep interval: %.2f seconds",
+                  sleep_interval);
+
+  return 0;
+}
+
+VLIB_CLI_COMMAND (show_ikev2_sleep_interval_command, static) = {
+  .path = "show ikev2 sleep interval",
+  .short_help = "show ikev2 sleep interval",
+  .function = show_ikev2_sleep_interval_command_fn,
+};
+
 static clib_error_t *
 set_ikev2_local_key_command_fn (vlib_main_t * vm,
                                unformat_input_t * input,
index 9631318..2751657 100644 (file)
@@ -550,6 +550,9 @@ typedef struct
   /* logging level */
   ikev2_log_level_t log_level;
 
+  /* sleep interval for ikev2_manager_process node, in seconds */
+  f64 sleep_interval;
+
   /* how often a liveness check will be performed */
   u32 liveness_period;
 
index 93683a5..ff775d4 100644 (file)
@@ -893,6 +893,72 @@ static void vl_api_ikev2_plugin_get_version_reply_t_handler
   vam->result_ready = 1;
 }
 
+static int
+api_ikev2_plugin_set_sleep_interval (vat_main_t *vam)
+{
+  unformat_input_t *i = vam->input;
+  vl_api_ikev2_plugin_set_sleep_interval_t *mp;
+  f64 timeout = 0.0; /* Default value for timeout */
+  int ret;
+
+  /* Parse input arguments */
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (!unformat (i, "timeout %lf", &timeout))
+       {
+         errmsg ("parse error '%U'", format_unformat_error, i);
+         return -99;
+       }
+    }
+
+  M (IKEV2_PLUGIN_SET_SLEEP_INTERVAL, mp);
+
+  mp->timeout = clib_host_to_net_f64 (timeout);
+
+  S (mp);
+  W (ret);
+
+  return ret;
+}
+
+static int
+api_ikev2_get_sleep_interval (vat_main_t *vam)
+{
+  ikev2_test_main_t *sm = &ikev2_test_main;
+  vl_api_ikev2_get_sleep_interval_t *mp;
+  u32 msg_size = sizeof (*mp);
+  int ret;
+
+  vam->result_ready = 0;
+
+  /* Allocate and initialize the message */
+  mp = vl_msg_api_alloc_as_if_client (msg_size);
+  clib_memset (mp, 0, msg_size);
+  mp->_vl_msg_id = ntohs (VL_API_IKEV2_GET_SLEEP_INTERVAL + sm->msg_id_base);
+  mp->client_index = vam->my_client_index;
+
+  /* Send the message */
+  S (mp);
+
+  /* Wait for a reply */
+  W (ret);
+  return ret;
+}
+
+static void
+vl_api_ikev2_get_sleep_interval_reply_t_handler (
+  vl_api_ikev2_get_sleep_interval_reply_t *mp)
+{
+  vat_main_t *vam = ikev2_test_main.vat_main;
+
+  /* Output the sleep interval */
+  clib_warning ("IKEv2 Manager Sleep Interval: %.2f seconds",
+               clib_net_to_host_f64 (mp->sleep_interval));
+
+  /* Mark the result as ready */
+  vam->result_ready = 1;
+}
+
 static int
 api_ikev2_profile_set_ipsec_udp_port (vat_main_t * vam)
 {
index 4bff829..51f1405 100644 (file)
@@ -22,8 +22,6 @@ from scapy.packet import raw, Raw
 from scapy.utils import long_converter
 from framework import VppTestCase
 from asfframework import (
-    tag_fixme_vpp_workers,
-    tag_fixme_ubuntu2404,
     VppTestRunner,
 )
 from vpp_ikev2 import Profile, IDType, AuthMethod
@@ -2322,7 +2320,6 @@ class TestResponderRekey(TestResponderPsk):
         self.assertEqual(r[0].sa.stats.n_rekey_req, 1)
 
 
-@tag_fixme_ubuntu2404
 class TestResponderRekeyRepeat(TestResponderRekey):
     """test ikev2 responder - rekey repeat"""
 
@@ -2330,6 +2327,22 @@ class TestResponderRekeyRepeat(TestResponderRekey):
 
     def test_responder(self):
         super(TestResponderRekeyRepeat, self).test_responder()
+
+        # The sleep interval for this test is set to 0.1 seconds instead of the default 2 seconds.
+        # This change is necessary because the test verifies the expiration of old IPsec SAs
+        # (self.fail("old IPsec SA not expired")) within a strict timeframe. A longer sleep
+        # interval, such as 2 seconds, would significantly delay the loop iterations, reducing
+        # the granularity of checks for SA expiration and increasing the risk of false failures.
+        #
+        # By setting the sleep interval to 0.1 seconds:
+        # - The test can perform frequent checks for the status of IPsec SAs, ensuring timely
+        #   detection of their expiration.
+        # - It reduces the likelihood of the test prematurely failing due to missing an SA
+        #   expiration event caused by coarse-grained timing checks.
+        #
+        # This adjustment enhances test stability and ensures accurate validation of the
+        # expiration behavior under the conditions specified by the test.
+        self.vapi.ikev2_plugin_set_sleep_interval(timeout=0.1)
         # rekey request is not accepted until old IPsec SA is expired
         capture = self.send_rekey_from_initiator()
         ih = self.get_ike_header(capture[0])
@@ -2357,7 +2370,6 @@ class TestResponderRekeyKEX(TestResponderRekey):
     vpp_worker_count = 2
 
 
-@tag_fixme_ubuntu2404
 class TestResponderRekeyRepeatKEX(TestResponderRekeyRepeat):
     """test ikev2 responder - rekey repeat with key exchange"""