Virtio interfaces should also support setting of mtu, as in case of cloud it is expected to have the consistent mtu across the infrastructure that the dhcp server sends and not hardcoded to 1500(default). In case when GRE/VXLAN tunneling is used, it adds overheads to the total size of 1518, and in that cases the DHCP server corrects the L3 MTU to 1454 to take care of the overhead. BUt since virtio interfaces was not having the mtu set that mtu sent by dhcp was ignored and teh instance will still send packets with 1500 mtu which afetr encapsulation will become more than 1518 and eventually gets dropped in the infrastructure. This issue can be solved by honoring the mtu 1454 sent by dhcp server, which this below patch will take care.
Changes in v5: Incorporated review comments. Changes in v4: Incorporated review comments. Changes in v3: Corrected few style errors as reported by sys-stv. Changes in v2: Incorporated review comments. Signed-off-by: Souvik Dey <sodey at sonusnet.com> --- drivers/net/virtio/virtio_ethdev.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 07d6449..da16ad4 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -653,12 +653,20 @@ virtio_dev_allmulticast_disable(struct rte_eth_dev *dev) PMD_INIT_LOG(ERR, "Failed to disable allmulticast"); } +#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */ + +static int virtio_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +{ + struct rte_eth_dev_info dev_info; + uint32_t ether_hdr_len = ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE; + uint32_t frame_size = mtu + ether_hdr_len; + + virtio_dev_info_get(dev, &dev_info); + + if (frame_size < ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) { + PMD_INIT_LOG(ERR, "MTU should be between %d and %d\n", + (ETHER_MIN_MTU - ether_hdr_len), + (dev_info.max_rx_pktlen - ether_hdr_len)); + return -EINVAL; + } + return 0; +} @@ -677,7 +685,6 @@ static const struct eth_dev_ops virtio_eth_dev_ops = { .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, -- 2.9.3.windows.1