From: Souvik Dey Date: Sun, 9 Oct 2016 03:38:26 +0000 (+0800) Subject: net/virtio: set MTU X-Git-Tag: spdx-start~5628 X-Git-Url: http://git.droids-corp.org/?p=dpdk.git;a=commitdiff_plain;h=4ec2424a61163e37138a597a11a9fa5011ee8c34 net/virtio: set MTU Virtio interfaces do not currently allow the user to specify a particular Maximum Transmission Unit (MTU). Consequently, the MTU of Virtio interfaces is typically set to the Ethernet default value of 1500. This is problematic in the case of cloud deployments, in which a specific (and potentially non-standard) MTU needs to be set by a DHCP server, which needs to be honored by all interfaces across the traffic path.To acheive this Virtio interfaces should support setting of MTU. In case when GRE/VXLAN tunneling is used for internal communication, there will be an overhead added by the infrastructure in the packet over and above the ETHER MTU of 1518. So to take care of this overhead in these cases the DHCP server corrects the L3 MTU to 1454. But since virtio interfaces was not having the MTU set functionality that MTU sent by the DHCP server was ignored and the instance will still send packets with 1500 MTU which after encapsulation will become more than 1518 and eventually gets dropped in the infrastructure. By adding an additional 'set_mtu' function to the Virtio driver, we can honor the MTU sent by the DHCP server. The dhcp server/controller can then leverage this 'set_mtu' functionality to resolve the above mentioned issue of packets getting dropped due to incorrect size. Signed-off-by: Souvik Dey Reviewed-by: Mark Kavanagh Acked-by: Yuanhan Liu --- diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index b4dfc0a9de..39bb5f78a0 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -652,6 +652,23 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "Failed to disable allmulticast"); } +#define VLAN_TAG_LEN 4 /* 802.3ac tag (not DMA'd) */ +static int +virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +{ + struct virtio_hw *hw = dev->data->dev_private; + uint32_t ether_hdr_len = ETHER_HDR_LEN + VLAN_TAG_LEN + + hw->vtnet_hdr_size; + uint32_t frame_size = mtu + ether_hdr_len; + + if (mtu < ETHER_MIN_MTU || frame_size > VIRTIO_MAX_RX_PKTLEN) { + PMD_INIT_LOG(ERR, "MTU should be between %d and %d\n", + ETHER_MIN_MTU, VIRTIO_MAX_RX_PKTLEN - ether_hdr_len); + return -EINVAL; + } + return 0; +} + /* * dev_ops for virtio, bare necessities for basic operation */ @@ -664,7 +681,7 @@ static const struct eth_dev_ops virtio_eth_dev_ops = { .promiscuous_disable = virtio_dev_promiscuous_disable, .allmulticast_enable = virtio_dev_allmulticast_enable, .allmulticast_disable = virtio_dev_allmulticast_disable, - + .mtu_set = virtio_mtu_set, .dev_infos_get = virtio_dev_info_get, .stats_get = virtio_dev_stats_get, .xstats_get = virtio_dev_xstats_get,