pg: add support to delete pg interface 38/41638/4
authorMohsin Kazmi <[email protected]>
Thu, 3 Oct 2024 23:18:17 +0000 (23:18 +0000)
committerBeno�t Ganne <[email protected]>
Mon, 7 Oct 2024 08:39:23 +0000 (08:39 +0000)
Type: improvement

Signed-off-by: Mohsin Kazmi <[email protected]>
Change-Id: I3102fded415c644673fb79a0fdb7a7448ce20f26

src/vnet/pg/cli.c
src/vnet/pg/pg.api
src/vnet/pg/pg.h
src/vnet/pg/pg_api.c
src/vnet/pg/stream.c
test/test_pg.py
test/vpp_pg_interface.py

index 3f2de26..6cd9cbd 100644 (file)
@@ -672,7 +672,7 @@ create_pg_if_cmd_fn (vlib_main_t * vm,
 
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     {
-      if (unformat (line_input, "interface pg%u", &if_id))
+      if (unformat (line_input, "pg%u", &if_id))
        ;
       else if (unformat (line_input, "coalesce-enabled"))
        coalesce_enabled = 1;
@@ -709,13 +709,60 @@ done:
 }
 
 VLIB_CLI_COMMAND (create_pg_if_cmd, static) = {
-  .path = "create packet-generator",
+  .path = "create packet-generator interface",
   .short_help = "create packet-generator interface <interface name>"
                " [gso-enabled gso-size <size> [coalesce-enabled]]"
                " [mode <ethernet | ip4 | ip6>]",
   .function = create_pg_if_cmd_fn,
 };
 
+static clib_error_t *
+delete_pg_if_cmd_fn (vlib_main_t *vm, unformat_input_t *input,
+                    vlib_cli_command_t *cmd)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  unformat_input_t _line_input, *line_input = &_line_input;
+  u32 sw_if_index = ~0;
+  int rv = 0;
+
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return clib_error_return (0, "Missing <interface>");
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "sw_if_index %d", &sw_if_index))
+       ;
+      else if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm,
+                        &sw_if_index))
+       ;
+      else
+       {
+         return clib_error_create ("unknown input `%U'",
+                                   format_unformat_error, input);
+       }
+    }
+  unformat_free (line_input);
+
+  if (sw_if_index == ~0)
+    return clib_error_return (0,
+                             "please specify interface name or sw_if_index");
+
+  rv = pg_interface_delete (sw_if_index);
+  if (rv == VNET_API_ERROR_INVALID_SW_IF_INDEX)
+    return clib_error_return (0, "not a pg interface");
+  else if (rv != 0)
+    return clib_error_return (0, "error on deleting pg interface");
+
+  return 0;
+}
+
+VLIB_CLI_COMMAND (delete_pg_if_cmd, static) = {
+  .path = "delete packet-generator interface",
+  .short_help = "delete packet-generator interface {<interface name> | "
+               "sw_if_index <sw_idx>}",
+  .function = delete_pg_if_cmd_fn,
+};
+
 /* Dummy init function so that we can be linked in. */
 static clib_error_t *
 pg_cli_init (vlib_main_t * vm)
index 4f531fb..7c6fdcc 100644 (file)
@@ -18,7 +18,7 @@
     This file defines packet-generator interface APIs.
 */
 
-option version = "2.0.0";
+option version = "2.1.0";
 
 import "vnet/interface_types.api";
 
@@ -75,6 +75,18 @@ define pg_create_interface_v2_reply
   vl_api_interface_index_t sw_if_index;
 };
 
+/** \brief PacketGenerator delete interface request
+    @param client_index - opaque cookie to identify the sender
+    @param context - sender context, to match reply w/ request
+    @param sw_if_index - interface index
+*/
+autoreply define pg_delete_interface
+{
+  u32 client_index;
+  u32 context;
+  vl_api_interface_index_t sw_if_index;
+};
+
 /** \brief PacketGenerator interface enable/disable packet coalesce
     @param client_index - opaque cookie to identify the sender
     @param context - sender context, to match reply w/ request
index bede747..0e4b286 100644 (file)
@@ -396,6 +396,8 @@ u32 pg_interface_add_or_get (pg_main_t *pg, u32 stream_index, u8 gso_enabled,
                             u32 gso_size, u8 coalesce_enabled,
                             pg_interface_mode_t mode);
 
+int pg_interface_delete (u32 sw_if_index);
+
 always_inline pg_node_t *
 pg_get_node (uword node_index)
 {
index e5d0a08..f7fc569 100644 (file)
@@ -62,6 +62,24 @@ vl_api_pg_create_interface_v2_t_handler (vl_api_pg_create_interface_v2_t *mp)
                ({ rmp->sw_if_index = ntohl (pi->sw_if_index); }));
 }
 
+static void
+vl_api_pg_delete_interface_t_handler (vl_api_pg_delete_interface_t *mp)
+{
+  vl_api_pg_delete_interface_reply_t *rmp;
+  int rv = 0;
+
+  VALIDATE_SW_IF_INDEX (mp);
+
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+
+  pg_main_t *pg = &pg_main;
+
+  rv = pg_interface_delete (sw_if_index);
+
+  BAD_SW_IF_INDEX_LABEL;
+  REPLY_MACRO (VL_API_PG_DELETE_INTERFACE_REPLY);
+}
+
 static void
   vl_api_pg_interface_enable_disable_coalesce_t_handler
   (vl_api_pg_interface_enable_disable_coalesce_t * mp)
index cf3d37d..6376e9b 100644 (file)
@@ -325,6 +325,50 @@ pg_interface_add_or_get (pg_main_t *pg, u32 if_id, u8 gso_enabled,
   return i;
 }
 
+int
+pg_interface_delete (u32 sw_if_index)
+{
+  vnet_main_t *vnm = vnet_get_main ();
+  pg_main_t *pm = &pg_main;
+  pg_interface_t *pi;
+  vnet_hw_interface_t *hw;
+  uword *p;
+
+  hw = vnet_get_sup_hw_interface_api_visible_or_null (vnm, sw_if_index);
+  if (hw == NULL || pg_dev_class.index != hw->dev_class_index)
+    return VNET_API_ERROR_INVALID_SW_IF_INDEX;
+
+  pi = pool_elt_at_index (pm->interfaces, hw->dev_instance);
+
+  vnet_hw_interface_set_flags (vnm, pi->hw_if_index, 0);
+  vnet_sw_interface_set_flags (vnm, pi->sw_if_index, 0);
+
+  if (pi->mode == PG_MODE_ETHERNET)
+    ethernet_delete_interface (vnm, pi->hw_if_index);
+  else
+    vnet_delete_hw_interface (vnm, pi->hw_if_index);
+
+  pi->hw_if_index = ~0;
+
+  if (pi->coalesce_enabled)
+    pg_interface_enable_disable_coalesce (pi, 0, ~0);
+
+  if (vlib_num_workers ())
+    {
+      clib_mem_free ((void *) pi->lockp);
+      pi->lockp = 0;
+    }
+
+  vec_del1 (pm->if_index_by_sw_if_index, sw_if_index);
+  p = hash_get (pm->if_index_by_if_id, pi->id);
+  if (p)
+    hash_unset (pm->if_index_by_if_id, pi->id);
+
+  clib_memset (pi, 0, sizeof (*pi));
+  pool_put (pm->interfaces, pi);
+  return 0;
+}
+
 static void
 do_edit (pg_stream_t * stream,
         pg_edit_group_t * g, pg_edit_t * e, uword want_commit)
index da3b225..14e149b 100644 (file)
@@ -38,6 +38,7 @@ class TestPgTun(VppTestCase):
         for i in self.pg_interfaces:
             i.unconfig_ip4()
             i.admin_down()
+            i.remove_vpp_config()
         super(TestPgTun, self).tearDown()
 
     def test_pg_tun(self):
index 1e02801..cd99818 100644 (file)
@@ -147,6 +147,11 @@ class VppPGInterface(VppInterface):
         )
         self._cap_name = "pcap%u-sw_if_index-%s" % (self.pg_index, self.sw_if_index)
 
+    def remove_vpp_config(self):
+        """delete Pg interface"""
+        self.disable_capture()
+        self.test.vapi.pg_delete_interface(sw_if_index=self.sw_if_index)
+
     def link_pcap_file(self, path, direction, counter):
         if not config.keep_pcaps:
             return