aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/tap
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/tap')
-rw-r--r--src/vnet/devices/tap/FEATURE.yaml2
-rw-r--r--src/vnet/devices/tap/cli.c24
-rw-r--r--src/vnet/devices/tap/tap.c242
-rw-r--r--src/vnet/devices/tap/tap.h5
-rw-r--r--src/vnet/devices/tap/tapv2.api80
-rw-r--r--src/vnet/devices/tap/tapv2_api.c97
6 files changed, 287 insertions, 163 deletions
diff --git a/src/vnet/devices/tap/FEATURE.yaml b/src/vnet/devices/tap/FEATURE.yaml
index 35ee4885b02..1a774fb0e74 100644
--- a/src/vnet/devices/tap/FEATURE.yaml
+++ b/src/vnet/devices/tap/FEATURE.yaml
@@ -1,6 +1,6 @@
---
name: Tap Device
-maintainer: damarion@cisco.com sluong@cisco.com sykazmi@cisco.com
+maintainer: damarion@cisco.com sluong@cisco.com mohsin.kazmi14@gmail.com
features:
- Virtio
- Persistence
diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c
index 10f4bb0ee2e..5c676d32d60 100644
--- a/src/vnet/devices/tap/cli.c
+++ b/src/vnet/devices/tap/cli.c
@@ -41,6 +41,7 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
args.tap_flags = 0;
args.rv = -1;
args.num_rx_queues = 1;
+ args.num_tx_queues = 1;
/* Get a line of input. */
if (unformat_user (input, unformat_line_input, line_input))
@@ -76,6 +77,8 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
args.host_ip6_gw_set = 1;
else if (unformat (line_input, "num-rx-queues %d", &tmp))
args.num_rx_queues = tmp;
+ else if (unformat (line_input, "num-tx-queues %d", &tmp))
+ args.num_tx_queues = tmp;
else if (unformat (line_input, "rx-ring-size %d", &tmp))
args.rx_ring_sz = tmp;
else if (unformat (line_input, "tx-ring-size %d", &tmp))
@@ -133,12 +136,12 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_create_command, static) = {
.path = "create tap",
- .short_help = "create tap {id <if-id>} [hw-addr <mac-address>] "
- "[num-rx-queues <n>] [rx-ring-size <size>] [tx-ring-size <size>] "
- "[host-ns <netns>] [host-bridge <bridge-name>] "
+ .short_help =
+ "create tap {id <if-id>} [hw-addr <mac-address>] "
+ "[num-rx-queues <n>] [num-tx-queues <n>] [rx-ring-size <size>] "
+ "[tx-ring-size <size>] [host-ns <netns>] [host-bridge <bridge-name>] "
"[host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6-addr>] "
"[host-ip4-gw <ip4-addr>] [host-ip6-gw <ip6-addr>] "
"[host-mac-addr <host-mac-address>] [host-if-name <name>] "
@@ -146,7 +149,6 @@ VLIB_CLI_COMMAND (tap_create_command, static) = {
"[persist] [attach] [tun] [packed] [in-order]",
.function = tap_create_command_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
tap_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
@@ -187,14 +189,12 @@ tap_delete_command_fn (vlib_main_t * vm, unformat_input_t * input,
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_delete__command, static) =
{
.path = "delete tap",
.short_help = "delete tap {<interface> | sw_if_index <sw_idx>}",
.function = tap_delete_command_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
tap_offload_command_fn (vlib_main_t * vm, unformat_input_t * input,
@@ -257,7 +257,6 @@ tap_offload_command_fn (vlib_main_t * vm, unformat_input_t * input,
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_offload_command, static) =
{
.path = "set tap offload",
@@ -266,7 +265,6 @@ VLIB_CLI_COMMAND (tap_offload_command, static) =
"csum-offload-disable>",
.function = tap_offload_command_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
tap_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
@@ -296,10 +294,8 @@ tap_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (vec_len (hw_if_indices) == 0)
{
- /* *INDENT-OFF* */
pool_foreach (vif, mm->interfaces)
vec_add1 (hw_if_indices, vif->hw_if_index);
- /* *INDENT-ON* */
}
virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_TAP);
@@ -309,13 +305,11 @@ done:
return error;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_show_command, static) = {
.path = "show tap",
.short_help = "show tap {<interface>] [descriptors]",
.function = tap_show_command_fn,
};
-/* *INDENT-ON* */
static clib_error_t *
tun_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
@@ -345,10 +339,8 @@ tun_show_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (vec_len (hw_if_indices) == 0)
{
- /* *INDENT-OFF* */
pool_foreach (vif, mm->interfaces)
vec_add1 (hw_if_indices, vif->hw_if_index);
- /* *INDENT-ON* */
}
virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_TUN);
@@ -358,13 +350,11 @@ done:
return error;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tun_show_command, static) = {
.path = "show tun",
.short_help = "show tun {<interface>] [descriptors]",
.function = tun_show_command_fn,
};
-/* *INDENT-ON* */
clib_error_t *
tap_cli_init (vlib_main_t * vm)
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c
index 33d6e3bc84a..1e2ee87041d 100644
--- a/src/vnet/devices/tap/tap.c
+++ b/src/vnet/devices/tap/tap.c
@@ -58,13 +58,11 @@ tap_main_t tap_main;
goto error; \
}
- /* *INDENT-OFF* */
-VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) =
-{
+VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) = {
.name = "tun-device",
.flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
+ .tx_hash_fn_type = VNET_HASH_FN_TYPE_IP,
};
- /* *INDENT-ON* */
#define TUN_MAX_PACKET_BYTES 65355
#define TUN_MIN_PACKET_BYTES 64
@@ -79,6 +77,14 @@ virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
return 0;
}
+static clib_error_t *
+virtio_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi,
+ u32 frame_size)
+{
+ /* nothing for now */
+ return 0;
+}
+
#define TAP_MAX_INSTANCE 1024
static void
@@ -89,14 +95,14 @@ tap_free (vlib_main_t * vm, virtio_if_t * vif)
clib_error_t *err = 0;
int i;
- /* *INDENT-OFF* */
+ virtio_pre_input_node_disable (vm, vif);
+
vec_foreach_index (i, vif->vhost_fds) if (vif->vhost_fds[i] != -1)
close (vif->vhost_fds[i]);
vec_foreach_index (i, vif->rxq_vrings)
virtio_vring_free_rx (vm, vif, RX_QUEUE (i));
vec_foreach_index (i, vif->txq_vrings)
virtio_vring_free_tx (vm, vif, TX_QUEUE (i));
- /* *INDENT-ON* */
if (vif->tap_fds)
{
@@ -106,6 +112,7 @@ tap_free (vlib_main_t * vm, virtio_if_t * vif)
error:
vec_foreach_index (i, vif->tap_fds) close (vif->tap_fds[i]);
+ vec_free (vif->tap_fds);
vec_free (vif->vhost_fds);
vec_free (vif->rxq_vrings);
vec_free (vif->txq_vrings);
@@ -129,6 +136,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
tap_main_t *tm = &tap_main;
vnet_sw_interface_t *sw;
vnet_hw_interface_t *hw;
+ vnet_hw_if_caps_change_t cc;
int i, num_vhost_queues;
int old_netns_fd = -1;
struct ifreq ifr = {.ifr_flags = IFF_NO_PI | IFF_VNET_HDR };
@@ -190,43 +198,47 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
vif->dev_instance = vif - vim->interfaces;
vif->id = args->id;
- vif->num_txqs = thm->n_vlib_mains;
+ vif->num_txqs = clib_max (args->num_tx_queues, thm->n_vlib_mains);
vif->num_rxqs = clib_max (args->num_rx_queues, 1);
if (args->tap_flags & TAP_FLAG_ATTACH)
{
- if (args->host_if_name != NULL)
- {
- host_if_name = (char *) args->host_if_name;
- clib_memcpy (ifr.ifr_name, host_if_name,
- clib_min (IFNAMSIZ, vec_len (host_if_name)));
- }
- else
+ if (args->host_if_name == NULL)
{
args->rv = VNET_API_ERROR_NO_MATCHING_INTERFACE;
err = clib_error_return (0, "host_if_name is not provided");
goto error;
}
- if (args->host_namespace)
+ }
+
+ /* if namespace is specified, all further netlink messages should be executed
+ * after we change our net namespace */
+ if (args->host_namespace)
+ {
+ old_netns_fd = clib_netns_open (NULL /* self */);
+ if ((nfd = clib_netns_open (args->host_namespace)) == -1)
{
- old_netns_fd = clib_netns_open (NULL /* self */);
- if ((nfd = clib_netns_open (args->host_namespace)) == -1)
- {
- args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
- args->error = clib_error_return_unix (0, "clib_netns_open '%s'",
- args->host_namespace);
- goto error;
- }
- if (clib_setns (nfd) == -1)
- {
- args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
- args->error = clib_error_return_unix (0, "setns '%s'",
- args->host_namespace);
- goto error;
- }
+ args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
+ args->error = clib_error_return_unix (0, "clib_netns_open '%s'",
+ args->host_namespace);
+ goto error;
+ }
+ if (clib_setns (nfd) == -1)
+ {
+ args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
+ args->error =
+ clib_error_return_unix (0, "setns '%s'", args->host_namespace);
+ goto error;
}
}
+ if (args->host_if_name != NULL)
+ {
+ host_if_name = (char *) args->host_if_name;
+ clib_memcpy (ifr.ifr_name, host_if_name,
+ clib_min (IFNAMSIZ, vec_len (host_if_name)));
+ }
+
if ((tfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
{
args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
@@ -258,7 +270,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
else
ifr.ifr_flags |= IFF_MULTI_QUEUE;
- hdrsz = sizeof (virtio_net_hdr_v1_t);
+ hdrsz = sizeof (vnet_virtio_net_hdr_v1_t);
if (args->tap_flags & TAP_FLAG_GSO)
{
offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6;
@@ -320,10 +332,10 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
args->error = clib_error_return_unix (0, "open '/dev/net/tun'");
goto error;
}
+ vec_add1 (vif->tap_fds, qfd);
_IOCTL (qfd, TUNSETIFF, (void *) &ifr);
tap_log_dbg (vif, "TUNSETIFF fd %d name %s flags 0x%x", qfd,
ifr.ifr_ifrn.ifrn_name, ifr.ifr_flags);
- vec_add1 (vif->tap_fds, qfd);
}
for (i = 0; i < vif->num_rxqs; i++)
@@ -399,54 +411,6 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
virtio_set_net_hdr_size (vif);
- if (!(args->tap_flags & TAP_FLAG_ATTACH))
- {
- /* if namespace is specified, all further netlink messages should be executed
- after we change our net namespace */
- if (args->host_namespace)
- {
- old_netns_fd = clib_netns_open (NULL /* self */);
- if ((nfd = clib_netns_open (args->host_namespace)) == -1)
- {
- args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
- args->error = clib_error_return_unix (0, "clib_netns_open '%s'",
- args->host_namespace);
- goto error;
- }
- args->error = vnet_netlink_set_link_netns (vif->ifindex, nfd,
- host_if_name);
- if (args->error)
- {
- args->rv = VNET_API_ERROR_NETLINK_ERROR;
- goto error;
- }
- if (clib_setns (nfd) == -1)
- {
- args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
- args->error = clib_error_return_unix (0, "setns '%s'",
- args->host_namespace);
- goto error;
- }
- if ((vif->ifindex = if_nametoindex (host_if_name)) == 0)
- {
- args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
- args->error = clib_error_return_unix (0, "if_nametoindex '%s'",
- host_if_name);
- goto error;
- }
- }
- else if (host_if_name)
- {
- args->error =
- vnet_netlink_set_link_name (vif->ifindex, host_if_name);
- if (args->error)
- {
- args->rv = VNET_API_ERROR_NETLINK_ERROR;
- goto error;
- }
- }
- }
-
if (vif->type == VIRTIO_IF_TYPE_TAP)
{
if (ethernet_mac_address_is_zero (args->host_mac_addr.bytes))
@@ -611,7 +575,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
vhost_vring_addr_t addr = { 0 };
vhost_vring_state_t state = { 0 };
vhost_vring_file_t file = { 0 };
- virtio_vring_t *vring;
+ vnet_virtio_vring_t *vring;
u16 qp = i >> 1;
int fd = vif->vhost_fds[qp];
@@ -629,7 +593,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
}
addr.index = state.index = file.index = vring->queue_id & 1;
- state.num = vring->size;
+ state.num = vring->queue_size;
virtio_log_debug (vif, "VHOST_SET_VRING_NUM fd %d index %u num %u", fd,
state.index, state.num);
_IOCTL (fd, VHOST_SET_VRING_NUM, &state);
@@ -668,10 +632,12 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
ethernet_mac_address_generate (args->mac_addr.bytes);
clib_memcpy (vif->mac_addr, args->mac_addr.bytes, 6);
- vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
+ if (args->host_bridge)
+ vif->host_bridge = format (0, "%s%c", args->host_bridge, 0);
}
vif->host_if_name = format (0, "%s%c", host_if_name, 0);
- vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
+ if (args->host_namespace)
+ vif->net_ns = format (0, "%s%c", args->host_namespace, 0);
vif->host_mtu_size = args->host_mtu_size;
vif->tap_flags = args->tap_flags;
clib_memcpy (vif->host_mac_addr, args->host_mac_addr.bytes, 6);
@@ -684,17 +650,14 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
if (vif->type != VIRTIO_IF_TYPE_TUN)
{
- args->error =
- ethernet_register_interface (vnm, virtio_device_class.index,
- vif->dev_instance, vif->mac_addr,
- &vif->hw_if_index,
- virtio_eth_flag_change);
- if (args->error)
- {
- args->rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto error;
- }
-
+ vnet_eth_interface_registration_t eir = {};
+
+ eir.dev_class_index = virtio_device_class.index;
+ eir.dev_instance = vif->dev_instance;
+ eir.address = vif->mac_addr;
+ eir.cb.flag_change = virtio_eth_flag_change;
+ eir.cb.set_max_frame_size = virtio_eth_set_max_frame_size;
+ vif->hw_if_index = vnet_eth_register_interface (vnm, &eir);
}
else
{
@@ -710,18 +673,16 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
args->sw_if_index = vif->sw_if_index;
args->rv = 0;
hw = vnet_get_hw_interface (vnm, vif->hw_if_index);
- hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE;
+ cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO |
+ VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
+ cc.val = VNET_HW_IF_CAP_INT_MODE;
+
if (args->tap_flags & TAP_FLAG_GSO)
- {
- hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
- VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
- VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM;
- }
+ cc.val |= VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_TX_TCP_CKSUM |
+ VNET_HW_IF_CAP_TX_UDP_CKSUM;
else if (args->tap_flags & TAP_FLAG_CSUM_OFFLOAD)
- {
- hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
- VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM;
- }
+ cc.val |= VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
+
if ((args->tap_flags & TAP_FLAG_GSO)
&& (args->tap_flags & TAP_FLAG_GRO_COALESCE))
{
@@ -729,18 +690,18 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
}
if (vif->type == VIRTIO_IF_TYPE_TUN)
{
- hw->max_supported_packet_bytes = TUN_MAX_PACKET_BYTES;
- hw->min_packet_bytes = hw->min_supported_packet_bytes =
- TUN_MIN_PACKET_BYTES;
- hw->max_packet_bytes =
- args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES;
- vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, hw->max_packet_bytes);
+ hw->min_frame_size = TUN_MIN_PACKET_BYTES;
+ vnet_hw_interface_set_mtu (
+ vnm, hw->hw_if_index,
+ args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES);
}
+ vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc);
+ virtio_pre_input_node_enable (vm, vif);
virtio_vring_set_rx_queues (vm, vif);
+ virtio_vring_set_tx_queues (vm, vif);
vif->per_interface_next_index = ~0;
- vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP;
vnet_hw_interface_set_flags (vnm, vif->hw_if_index,
VNET_HW_INTERFACE_FLAG_LINK_UP);
/*
@@ -749,7 +710,6 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
* TUNSETCARRIER ioctl(). See tap_set_carrier().
*/
vif->host_carrier_up = 1;
- vif->cxq_vring = NULL;
goto done;
@@ -767,7 +727,11 @@ done:
if (vhost_mem)
clib_mem_free (vhost_mem);
if (old_netns_fd != -1)
- close (old_netns_fd);
+ {
+ /* in case we errored with a switched netns */
+ clib_setns (old_netns_fd);
+ close (old_netns_fd);
+ }
if (nfd != -1)
close (nfd);
}
@@ -812,6 +776,7 @@ tap_csum_offload_enable_disable (vlib_main_t * vm, u32 sw_if_index,
virtio_main_t *mm = &virtio_main;
virtio_if_t *vif;
vnet_hw_interface_t *hw;
+ vnet_hw_if_caps_change_t cc;
clib_error_t *err = 0;
int i = 0;
@@ -829,21 +794,19 @@ tap_csum_offload_enable_disable (vlib_main_t * vm, u32 sw_if_index,
_IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload);
vif->gso_enabled = 0;
vif->packet_coalesce = 0;
- vif->csum_offload_enabled = enable_disable ? 1 : 0;
-
- if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) != 0)
- {
- hw->caps &= ~VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO;
- }
+ cc.mask = VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_L4_TX_CKSUM;
if (enable_disable)
{
- hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM;
+ cc.val = VNET_HW_IF_CAP_L4_TX_CKSUM;
+ vif->csum_offload_enabled = 1;
}
else
{
- hw->caps &= ~VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM;
+ cc.val = 0;
+ vif->csum_offload_enabled = 0;
}
+ vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc);
error:
if (err)
@@ -863,6 +826,7 @@ tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, int enable_disable,
virtio_main_t *mm = &virtio_main;
virtio_if_t *vif;
vnet_hw_interface_t *hw;
+ vnet_hw_if_caps_change_t cc;
clib_error_t *err = 0;
int i = 0;
@@ -878,29 +842,25 @@ tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, int enable_disable,
unsigned int offload = enable_disable ? gso_on : gso_off;
vec_foreach_index (i, vif->tap_fds)
_IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload);
- vif->gso_enabled = enable_disable ? 1 : 0;
- vif->csum_offload_enabled = 0;
+
+ cc.mask = VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_L4_TX_CKSUM;
+
if (enable_disable)
{
- if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) == 0)
- {
- hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
- VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM;
- }
+ cc.val = cc.mask;
+ vif->gso_enabled = 1;
+ vif->csum_offload_enabled = 1;
if (is_packet_coalesce)
- {
- virtio_set_packet_coalesce (vif);
- }
+ virtio_set_packet_coalesce (vif);
}
else
{
- if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) != 0)
- {
- hw->caps &= ~(VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
- VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM);
- }
+ cc.val = 0;
+ vif->gso_enabled = 0;
+ vif->csum_offload_enabled = 0;
vif->packet_coalesce = 0;
}
+ vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc);
error:
if (err)
@@ -918,12 +878,11 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
vnet_main_t *vnm = vnet_get_main ();
virtio_main_t *mm = &virtio_main;
virtio_if_t *vif;
- virtio_vring_t *vring;
+ vnet_virtio_vring_t *vring;
vnet_hw_interface_t *hi;
tap_interface_details_t *r_tapids = NULL;
tap_interface_details_t *tapid = NULL;
- /* *INDENT-OFF* */
pool_foreach (vif, mm->interfaces) {
if ((vif->type != VIRTIO_IF_TYPE_TAP)
&& (vif->type != VIRTIO_IF_TYPE_TUN))
@@ -936,9 +895,9 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
clib_memcpy(tapid->dev_name, hi->name,
MIN (ARRAY_LEN (tapid->dev_name) - 1, vec_len (hi->name)));
vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS(0));
- tapid->rx_ring_sz = vring->size;
+ tapid->rx_ring_sz = vring->queue_size;
vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0));
- tapid->tx_ring_sz = vring->size;
+ tapid->tx_ring_sz = vring->queue_size;
tapid->tap_flags = vif->tap_flags;
clib_memcpy(&tapid->host_mac_addr, vif->host_mac_addr, 6);
if (vif->host_if_name)
@@ -967,7 +926,6 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids)
tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len;
tapid->host_mtu_size = vif->host_mtu_size;
}
- /* *INDENT-ON* */
*out_tapids = r_tapids;
diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h
index 2efaa511a49..6b88c34fe41 100644
--- a/src/vnet/devices/tap/tap.h
+++ b/src/vnet/devices/tap/tap.h
@@ -44,7 +44,8 @@ typedef struct
u32 id;
u8 mac_addr_set;
mac_address_t mac_addr;
- u8 num_rx_queues;
+ u16 num_rx_queues;
+ u16 num_tx_queues;
u16 rx_ring_sz;
u16 tx_ring_sz;
u32 tap_flags;
@@ -98,8 +99,10 @@ typedef struct
/* host mtu size, configurable through startup.conf */
int host_mtu_size;
+ u16 msg_id_base;
} tap_main_t;
+extern tap_main_t tap_main;
void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args);
int tap_delete_if (vlib_main_t * vm, u32 sw_if_index);
int tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index,
diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api
index 6b6618411a6..bf53d1bc6fe 100644
--- a/src/vnet/devices/tap/tapv2.api
+++ b/src/vnet/devices/tap/tapv2.api
@@ -43,6 +43,82 @@ enum tap_flags {
@param use_random_mac - let the system generate a unique mac address
@param mac_address - mac addr to assign to the interface if use_random not set
@param num_rx_queues - number of rx queues
+ @param num_tx_queues - number of tx queues
+ @param tx_ring_sz - the number of entries of TX ring, optional, default is 256 entries, must be power of 2
+ @param rx_ring_sz - the number of entries of RX ring, optional, default is 256 entries, must be power of 2
+ @param host_mtu_set - host MTU should be set
+ @param host_mtu_size - host MTU size
+ @param host_mac_addr_set - host side interface mac address should be set
+ @param host_mac_addr - host side interface mac address
+ @param host_ip4_prefix_set - host IPv4 ip address should be set
+ @param host_ip4_prefix - host IPv4 ip address
+ @param host_ip6_prefix_set - host IPv6 ip address should be set
+ @param host_ip6_prefix - host IPv6 ip address
+ @param host_ip4_gw_set - host IPv4 default gateway should be set
+ @param host_ip4_gw - host IPv4 default gateway
+ @param host_ip6_gw_set - host IPv6 default gateway should be set
+ @param host_ip6_gw - host IPv6 default gateway
+ @param tap_flags - flags for the TAP interface creation
+ @param host_if_name_set - host side interface name should be set
+ @param host_if_name - host side interface name
+ @param host_namespace_set - host namespace should be set
+ @param host_namespace - host namespace to attach interface to
+ @param host_bridge_set - host bridge should be set
+ @param host_bridge - host bridge to attach interface to
+ @param tag - tag
+*/
+autoendian define tap_create_v3
+{
+ u32 client_index;
+ u32 context;
+ u32 id [default=0xffffffff];
+ bool use_random_mac [default=true];
+ vl_api_mac_address_t mac_address;
+ u16 num_rx_queues [default=1];
+ u16 num_tx_queues [default=1];
+ u16 tx_ring_sz [default=256];
+ u16 rx_ring_sz [default=256];
+ bool host_mtu_set;
+ u32 host_mtu_size;
+ bool host_mac_addr_set;
+ vl_api_mac_address_t host_mac_addr;
+ bool host_ip4_prefix_set;
+ vl_api_ip4_address_with_prefix_t host_ip4_prefix;
+ bool host_ip6_prefix_set;
+ vl_api_ip6_address_with_prefix_t host_ip6_prefix;
+ bool host_ip4_gw_set;
+ vl_api_ip4_address_t host_ip4_gw;
+ bool host_ip6_gw_set;
+ vl_api_ip6_address_t host_ip6_gw;
+ vl_api_tap_flags_t tap_flags;
+ bool host_namespace_set;
+ string host_namespace[64];
+ bool host_if_name_set;
+ string host_if_name[64];
+ bool host_bridge_set;
+ string host_bridge[64];
+ string tag[];
+};
+
+/** \brief Reply for tap create reply
+ @param context - returned sender context, to match reply w/ request
+ @param retval - return code
+ @param sw_if_index - software index allocated for the new tap interface
+*/
+autoendian define tap_create_v3_reply
+{
+ u32 context;
+ i32 retval;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Initialize a new tap interface with the given parameters
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param id - interface id, 0xffffffff means auto
+ @param use_random_mac - let the system generate a unique mac address
+ @param mac_address - mac addr to assign to the interface if use_random not set
+ @param num_rx_queues - number of rx queues
@param tx_ring_sz - the number of entries of TX ring, optional, default is 256 entries, must be power of 2
@param rx_ring_sz - the number of entries of RX ring, optional, default is 256 entries, must be power of 2
@param host_mtu_set - host MTU should be set
@@ -68,6 +144,8 @@ enum tap_flags {
*/
define tap_create_v2
{
+ option deprecated;
+
u32 client_index;
u32 context;
u32 id [default=0xffffffff];
@@ -105,6 +183,8 @@ define tap_create_v2
*/
define tap_create_v2_reply
{
+ option deprecated;
+
u32 context;
i32 retval;
vl_api_interface_index_t sw_if_index;
diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c
index 08dca0dc92b..ab4189ab607 100644
--- a/src/vnet/devices/tap/tapv2_api.c
+++ b/src/vnet/devices/tap/tapv2_api.c
@@ -32,10 +32,102 @@
#include <vnet/devices/tap/tapv2.api_enum.h>
#include <vnet/devices/tap/tapv2.api_types.h>
-#define REPLY_MSG_ID_BASE msg_id_base
+#define REPLY_MSG_ID_BASE tap_main.msg_id_base
#include <vlibapi/api_helper_macros.h>
-static u16 msg_id_base;
+static void
+vl_api_tap_create_v3_t_handler (vl_api_tap_create_v3_t *mp)
+{
+ vl_api_registration_t *reg;
+ int rv;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ vnet_main_t *vnm = vnet_get_main ();
+ vlib_main_t *vm = vlib_get_main ();
+ vl_api_tap_create_v3_reply_t *rmp;
+
+ tap_create_if_args_t _a, *ap = &_a;
+
+ clib_memset (ap, 0, sizeof (*ap));
+
+ ap->id = mp->id;
+ if (!mp->use_random_mac)
+ {
+ mac_address_decode (mp->mac_address, &ap->mac_addr);
+ ap->mac_addr_set = 1;
+ }
+ ap->rx_ring_sz = mp->rx_ring_sz;
+ ap->tx_ring_sz = mp->tx_ring_sz;
+ ap->sw_if_index = (u32) ~0;
+ ap->num_rx_queues = clib_max (1, mp->num_rx_queues);
+ ap->num_tx_queues = mp->num_tx_queues;
+
+ if (mp->host_if_name_set)
+ ap->host_if_name = format (0, "%s%c", mp->host_if_name, 0);
+
+ if (mp->host_mac_addr_set)
+ {
+ mac_address_decode (mp->host_mac_addr, &ap->host_mac_addr);
+ }
+
+ if (mp->host_namespace_set)
+ ap->host_namespace = format (0, "%s%c", mp->host_namespace, 0);
+
+ if (mp->host_bridge_set)
+ ap->host_bridge = format (0, "%s%c", mp->host_bridge, 0);
+
+ if (mp->host_ip4_prefix_set)
+ {
+ ip4_address_decode (mp->host_ip4_prefix.address, &ap->host_ip4_addr);
+ ap->host_ip4_prefix_len = mp->host_ip4_prefix.len;
+ }
+
+ if (mp->host_ip6_prefix_set)
+ {
+ ip6_address_decode (mp->host_ip6_prefix.address, &ap->host_ip6_addr);
+ ap->host_ip6_prefix_len = mp->host_ip6_prefix.len;
+ }
+
+ if (mp->host_ip4_gw_set)
+ {
+ ip4_address_decode (mp->host_ip4_gw, &ap->host_ip4_gw);
+ ap->host_ip4_gw_set = 1;
+ }
+
+ if (mp->host_ip6_gw_set)
+ {
+ ip6_address_decode (mp->host_ip6_gw, &ap->host_ip6_gw);
+ ap->host_ip6_gw_set = 1;
+ }
+
+ if (mp->host_mtu_set)
+ {
+ ap->host_mtu_size = mp->host_mtu_size;
+ ap->host_mtu_set = 1;
+ }
+
+ ap->tap_flags = mp->tap_flags;
+
+ tap_create_if (vm, ap);
+
+ /* If a tag was supplied... */
+ if (vl_api_string_len (&mp->tag))
+ {
+ u8 *tag = vl_api_from_api_to_new_vec (mp, &mp->tag);
+ vnet_set_sw_interface_tag (vnm, tag, ap->sw_if_index);
+ }
+
+ vec_free (ap->host_if_name);
+ vec_free (ap->host_namespace);
+ vec_free (ap->host_bridge);
+
+ rv = ap->rv;
+ REPLY_MACRO2_END (VL_API_TAP_CREATE_V3_REPLY,
+ ({ rmp->sw_if_index = ap->sw_if_index; }));
+}
static void
vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
@@ -63,6 +155,7 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp)
ap->tx_ring_sz = ntohs (mp->tx_ring_sz);
ap->sw_if_index = (u32) ~ 0;
ap->num_rx_queues = 1;
+ ap->num_tx_queues = 1;
if (mp->num_rx_queues > 1)
ap->num_rx_queues = mp->num_rx_queues;