diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/pg/cli.c | 51 | ||||
-rw-r--r-- | src/vnet/pg/pg.api | 14 | ||||
-rw-r--r-- | src/vnet/pg/pg.h | 2 | ||||
-rw-r--r-- | src/vnet/pg/pg_api.c | 18 | ||||
-rw-r--r-- | src/vnet/pg/stream.c | 44 |
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) |