summaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/virtio
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/virtio')
-rw-r--r--src/vnet/devices/virtio/cli.c2
-rw-r--r--src/vnet/devices/virtio/pci.c61
-rw-r--r--src/vnet/devices/virtio/pci.h13
-rw-r--r--src/vnet/devices/virtio/virtio.api4
-rw-r--r--src/vnet/devices/virtio/virtio_api.c4
5 files changed, 77 insertions, 7 deletions
diff --git a/src/vnet/devices/virtio/cli.c b/src/vnet/devices/virtio/cli.c
index 956284c9716..10b545edb5e 100644
--- a/src/vnet/devices/virtio/cli.c
+++ b/src/vnet/devices/virtio/cli.c
@@ -42,6 +42,8 @@ virtio_pci_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
;
else if (unformat (line_input, "feature-mask 0x%llx", &feature_mask))
args.features = feature_mask;
+ else if (unformat (line_input, "gso-enabled"))
+ args.gso_enabled = 1;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c
index 3736225b25c..f53552a8436 100644
--- a/src/vnet/devices/virtio/pci.c
+++ b/src/vnet/devices/virtio/pci.c
@@ -557,6 +557,27 @@ virtio_pci_send_ctrl_msg (vlib_main_t * vm, virtio_if_t * vif,
}
static int
+virtio_pci_enable_gso (vlib_main_t * vm, virtio_if_t * vif)
+{
+ virtio_main_t *vim = &virtio_main;
+ struct virtio_ctrl_msg gso_hdr;
+ virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
+
+ gso_hdr.ctrl.class = VIRTIO_NET_CTRL_GUEST_OFFLOADS;
+ gso_hdr.ctrl.cmd = VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET;
+ gso_hdr.status = VIRTIO_NET_ERR;
+ u64 offloads = VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO);
+ clib_memcpy (gso_hdr.data, &offloads, sizeof (offloads));
+
+ status = virtio_pci_send_ctrl_msg (vm, vif, &gso_hdr, sizeof (offloads));
+ virtio_log_debug (vim, vif, "enable gso");
+ return status;
+}
+
+static int
virtio_pci_enable_multiqueue (vlib_main_t * vm, virtio_if_t * vif,
u16 num_queues)
{
@@ -720,8 +741,18 @@ virtio_negotiate_features (vlib_main_t * vm, virtio_if_t * vif,
* if features are not requested
* default: all supported features
*/
- u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
+ u64 supported_features = VIRTIO_FEATURE (VIRTIO_NET_F_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_CSUM)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_MTU)
| VIRTIO_FEATURE (VIRTIO_NET_F_MAC)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GSO)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_GUEST_UFO)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO4)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_TSO6)
+ | VIRTIO_FEATURE (VIRTIO_NET_F_HOST_UFO)
| VIRTIO_FEATURE (VIRTIO_NET_F_MRG_RXBUF)
| VIRTIO_FEATURE (VIRTIO_NET_F_STATUS)
| VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)
@@ -1175,14 +1206,31 @@ virtio_pci_create_if (vlib_main_t * vm, virtio_pci_create_if_args_t * args)
else
vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
- if ((vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ)) &&
- (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ)))
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_VQ))
{
- if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
- virtio_log_warning (vim, vif, "multiqueue is not set");
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) &&
+ args->gso_enabled)
+ {
+ if (virtio_pci_enable_gso (vm, vif))
+ {
+ virtio_log_warning (vim, vif, "gso is not enabled");
+ }
+ else
+ {
+ vif->gso_enabled = 1;
+ hw->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+ vnm->interface_main.gso_interface_count++;
+ }
+ }
+ if (vif->features & VIRTIO_FEATURE (VIRTIO_NET_F_MQ))
+ {
+ if (virtio_pci_enable_multiqueue (vm, vif, vif->max_queue_pairs))
+ virtio_log_warning (vim, vif, "multiqueue is not set");
+ }
}
return;
+
error:
virtio_pci_delete_if (vm, vif);
args->rv = VNET_API_ERROR_INVALID_INTERFACE;
@@ -1212,6 +1260,9 @@ virtio_pci_delete_if (vlib_main_t * vm, virtio_if_t * vif)
virtio_pci_legacy_reset (vm, vif);
+ if (vif->gso_enabled)
+ vnm->interface_main.gso_interface_count--;
+
if (vif->hw_if_index)
{
vnet_hw_interface_set_flags (vnm, vif->hw_if_index, 0);
diff --git a/src/vnet/devices/virtio/pci.h b/src/vnet/devices/virtio/pci.h
index dcf9b146463..b1e29162108 100644
--- a/src/vnet/devices/virtio/pci.h
+++ b/src/vnet/devices/virtio/pci.h
@@ -101,10 +101,22 @@ typedef enum
* at the end of the used ring. Guest should ignore the used->flags field. */ \
_ (VHOST_USER_F_PROTOCOL_FEATURES, 30)
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2
#define VIRTIO_NET_F_MTU 3
#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */
#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */
+/*
+ * Control network offloads
+ * Reconfigures the network offloads that Guest can handle.
+ * Available with the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ * Command data format matches the feature bit mask exactly.
+ * See VIRTIO_NET_F_GUEST_* for the list of offloads
+ * that can be enabled/disabled.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
+
/* Common configuration */
#define VIRTIO_PCI_CAP_COMMON_CFG 1
/* Notifications */
@@ -233,6 +245,7 @@ typedef struct
u8 mac_addr_set;
u8 mac_addr[6];
u64 features;
+ u8 gso_enabled;
clib_error_t *error;
} virtio_pci_create_if_args_t;
diff --git a/src/vnet/devices/virtio/virtio.api b/src/vnet/devices/virtio/virtio.api
index 3a40fa9a952..9e81b35c175 100644
--- a/src/vnet/devices/virtio/virtio.api
+++ b/src/vnet/devices/virtio/virtio.api
@@ -22,8 +22,7 @@ option version = "1.0.0";
0-15 domain, 16-23 bus, 24-28 slot, 29-31 function
@param use_random_mac - let the system generate a unique mac address
@param mac_address - mac addr to assign to the interface if use_radom not set
- @param tx_ring_sz - the number of entries of TX ring
- @param rx_ring_sz - the number of entries of RX ring
+ @param gso_enabled - enable gso feature if available, 1 to enable
@param features - the virtio features which driver should negotiate with device
*/
define virtio_pci_create
@@ -33,6 +32,7 @@ define virtio_pci_create
u32 pci_addr;
u8 use_random_mac;
u8 mac_address[6];
+ u8 gso_enabled;
u64 features;
};
diff --git a/src/vnet/devices/virtio/virtio_api.c b/src/vnet/devices/virtio/virtio_api.c
index 82ff791a866..d73e6f877d5 100644
--- a/src/vnet/devices/virtio/virtio_api.c
+++ b/src/vnet/devices/virtio/virtio_api.c
@@ -66,6 +66,10 @@ vl_api_virtio_pci_create_t_handler (vl_api_virtio_pci_create_t * mp)
ap->mac_addr_set = 1;
}
ap->sw_if_index = (u32) ~ 0;
+ if (mp->gso_enabled)
+ ap->gso_enabled = 1;
+ else
+ ap->gso_enabled = 0;
ap->features = clib_net_to_host_u64 (mp->features);
virtio_pci_create_if (vm, ap);