aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2026-02-23 15:10:26 +0100
committerStefano Brivio <sbrivio@redhat.com>2026-02-24 12:05:58 +0100
commitde5b69491fdd95bd7d997a4b7c2972bd3ceb1101 (patch)
treeca71417cc535796b039f3bd17638828007619441
parentc3201915c436b47481396f0ae95b52efed084ef3 (diff)
downloadpasst-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar.gz
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar.bz2
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar.lz
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar.xz
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.tar.zst
passt-de5b69491fdd95bd7d997a4b7c2972bd3ceb1101.zip
tcp_vu: vu_pad() expects l2 length
tcp_vu_hdrlen() returns a length that includes VNET_HLEN (the virtio net header), but vu_pad() expects the Layer-2 frame length, which should not include the virtio header. Passing the inflated length means short frames aren't padded to the minimum 60-byte Ethernet frame size (ETH_ZLEN). Subtract VNET_HLEN from hdrlen when computing the l2 length passed to vu_pad() in both tcp_vu_send_flag() and tcp_vu_data_from_sock(). Fixes: 0cb8f9003654 ("tcp, udp: Pad batched frames for vhost-user modes to 60 bytes (802.3 minimum)") Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp_vu.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/tcp_vu.c b/tcp_vu.c
index 3847a4e..2c9ddba 100644
--- a/tcp_vu.c
+++ b/tcp_vu.c
@@ -71,8 +71,8 @@ int tcp_vu_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
{
struct vu_dev *vdev = c->vdev;
struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE];
- size_t optlen, hdrlen;
struct vu_virtq_element flags_elem[2];
+ size_t optlen, hdrlen, l2len;
struct ipv6hdr *ip6h = NULL;
struct iphdr *ip4h = NULL;
struct iovec flags_iov[2];
@@ -137,7 +137,8 @@ int tcp_vu_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload,
NULL, seq, !*c->pcap);
- vu_pad(&flags_elem[0].in_sg[0], hdrlen + optlen);
+ l2len = optlen + hdrlen - VNET_HLEN;
+ vu_pad(&flags_elem[0].in_sg[0], l2len);
if (*c->pcap)
pcap_iov(&flags_elem[0].in_sg[0], 1, VNET_HLEN);
@@ -446,6 +447,7 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
int buf_cnt = head[i + 1] - head[i];
ssize_t dlen = iov_size(iov, buf_cnt) - hdrlen;
bool push = i == head_cnt - 1;
+ size_t l2len;
vu_set_vnethdr(vdev, iov->iov_base, buf_cnt);
@@ -457,7 +459,8 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
tcp_vu_prepare(c, conn, iov, buf_cnt, &check, !*c->pcap, push);
/* Pad first/single buffer only, it's at least ETH_ZLEN long */
- vu_pad(iov, dlen + hdrlen);
+ l2len = dlen + hdrlen - VNET_HLEN;
+ vu_pad(iov, l2len);
if (*c->pcap)
pcap_iov(iov, buf_cnt, VNET_HLEN);