aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/pg
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/pg')
-rw-r--r--src/vnet/pg/cli.c51
-rw-r--r--src/vnet/pg/pg.api14
-rw-r--r--src/vnet/pg/pg.h2
-rw-r--r--src/vnet/pg/pg_api.c18
-rw-r--r--src/vnet/pg/stream.c44
5 files changed, 126 insertions, 3 deletions
diff --git a/src/vnet/pg/cli.c b/src/vnet/pg/cli.c
index 3f2de2604b2..6cd9cbd3be5 100644
--- a/src/vnet/pg/cli.c
+++ b/src/vnet/pg/cli.c
@@ -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)
diff --git a/src/vnet/pg/pg.api b/src/vnet/pg/pg.api
index 4f531fb1f5e..7c6fdcc97cf 100644
--- a/src/vnet/pg/pg.api
+++ b/src/vnet/pg/pg.api
@@ -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
diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h
index bede747428c..0e4b2868b6c 100644
--- a/src/vnet/pg/pg.h
+++ b/src/vnet/pg/pg.h
@@ -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)
{
diff --git a/src/vnet/pg/pg_api.c b/src/vnet/pg/pg_api.c
index e5d0a08a527..f7fc569a8c0 100644
--- a/src/vnet/pg/pg_api.c
+++ b/src/vnet/pg/pg_api.c
@@ -63,6 +63,24 @@ vl_api_pg_create_interface_v2_t_handler (vl_api_pg_create_interface_v2_t *mp)
}
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)
{
diff --git a/src/vnet/pg/stream.c b/src/vnet/pg/stream.c
index cf3d37d5e9e..6376e9b7ce3 100644
--- a/src/vnet/pg/stream.c
+++ b/src/vnet/pg/stream.c
@@ -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)