Add option to delete af_packet (host) interfaces

Change-Id: Iab76951758ae9b9a99d679a223941a4b8c683078
Signed-off-by: Alpesh S. Patel <apatel9191@hotmail.com>
Signed-off-by: Damjan Marion <damarion@cisco.com>
This commit is contained in:
Peter Lei
2016-04-08 08:16:31 -07:00
committed by Gerrit Code Review
parent d530445067
commit dba76f29e6
3 changed files with 90 additions and 0 deletions

View File

@ -157,6 +157,7 @@ create_packet_v2_sock(u8 * name, tpacket_req_t * rx_req, tpacket_req_t * tx_req,
return 0;
error:
close(*fd);
*fd = -1;
return ret;
}
@ -210,6 +211,8 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set)
apif->tx_req = tx_req;
apif->host_if_name = host_if_name;
apif->per_interface_next_index = ~0;
apif->next_tx_frame = 0;
apif->next_rx_frame = 0;
{
unix_file_t template = {0};
@ -265,6 +268,58 @@ error:
return ret;
}
int
af_packet_delete_if(vlib_main_t *vm, u8 *host_if_name)
{
vnet_main_t *vnm = vnet_get_main();
af_packet_main_t *apm = &af_packet_main;
af_packet_if_t *apif;
uword *p;
uword if_index;
u32 ring_sz;
p = mhash_get(&apm->if_index_by_host_if_name, host_if_name);
if (p == NULL) {
clib_warning("Host interface %s does not exist", host_if_name);
return VNET_API_ERROR_SYSCALL_ERROR_1;
}
apif = pool_elt_at_index(apm->interfaces, p[0]);
if_index = apif - apm->interfaces;
/* bring down the interface */
vnet_hw_interface_set_flags(vnm, apif->hw_if_index, 0);
/* clean up */
if (apif->unix_file_index != ~0) {
unix_file_del(&unix_main, unix_main.file_pool + apif->unix_file_index);
apif->unix_file_index = ~0;
}
ring_sz = apif->rx_req->tp_block_size * apif->rx_req->tp_block_nr +
apif->tx_req->tp_block_size * apif->tx_req->tp_block_nr;
if (munmap(apif->rx_ring, ring_sz))
clib_warning("Host interface %s could not free rx/tx ring", host_if_name);
apif->rx_ring = NULL;
apif->tx_ring = NULL;
close(apif->fd);
apif->fd = -1;
vec_free(apif->rx_req);
apif->rx_req = NULL;
vec_free(apif->tx_req);
apif->tx_req = NULL;
vec_free(apif->host_if_name);
apif->host_if_name = NULL;
mhash_unset(&apm->if_index_by_host_if_name, host_if_name, &if_index);
ethernet_delete_interface(vnm, apif->hw_if_index);
pool_put(apm->interfaces, apif);
return 0;
}
static clib_error_t *
af_packet_init (vlib_main_t * vm)
{

View File

@ -55,3 +55,4 @@ extern vnet_device_class_t af_packet_device_class;
extern vlib_node_registration_t af_packet_input_node;
int af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set);
int af_packet_delete_if(vlib_main_t * vm, u8 * host_if_name);

View File

@ -80,6 +80,40 @@ VLIB_CLI_COMMAND (af_packet_create_command, static) = {
.function = af_packet_create_command_fn,
};
static clib_error_t *
af_packet_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, * line_input = &_line_input;
u8 * host_if_name = NULL;
/* Get a line of input. */
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, "name %s", &host_if_name))
;
else
return clib_error_return (0, "unknown input `%U'", format_unformat_error, input);
}
unformat_free (line_input);
if (host_if_name == NULL)
return clib_error_return (0, "missing host interface name");
af_packet_delete_if(vm, host_if_name);
return 0;
}
VLIB_CLI_COMMAND (af_packet_delete_command, static) = {
.path = "delete host-interface",
.short_help = "delete host-interface name <interface name>",
.function = af_packet_delete_command_fn,
};
clib_error_t *
af_packet_cli_init (vlib_main_t * vm)
{