From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=jzDanRyL; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id C37505A026D for ; Fri, 10 Apr 2026 09:23:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1775805798; bh=GV7LID3qu1f9nvi/lAD+sviQRSvuIDkT6Kf9Ip9A2XA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=jzDanRyLvzCjDhqUM/aKaQwn21jX/rS72BTpSuLr6ni/53o7fG3h3dKZqEHjL+NF0 HUcum9YZwV0YUHMFG4NtGik7RPmnaN/OdzCSCdJJnfm12lz00HdR4ITG6FQXQupPgV ylv/eaXHQAuIuF7G0hOGZlzqjR898eigoei268mpUiLNP9qdVNUGmfW/WsY8ghk2bU 9EdNHZU19jff2IeSYYdXFUXNZZJoJ1fjtRw+dKI04e7uVmVuwRqLtIplnmQ4dDoe+f +3EBVESKsMtI07jx1FEkWE3kNXzZOX5KBOBByBNwxXVOfiRgK3FA3rRk6PS4Y/Ngxp TF9vu8OTSCNug== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fsSvV2lb1z4wK5; Fri, 10 Apr 2026 17:23:18 +1000 (AEST) Date: Fri, 10 Apr 2026 17:23:12 +1000 From: David Gibson To: Laurent Vivier Subject: Re: [PATCH v2 09/10] tcp: Pass explicit data length to tcp_fill_headers() Message-ID: References: <20260403163811.3209635-1-lvivier@redhat.com> <20260403163811.3209635-10-lvivier@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="X4rcHk9MnY4ykQEf" Content-Disposition: inline In-Reply-To: <20260403163811.3209635-10-lvivier@redhat.com> Message-ID-Hash: 767ZLO2JH3YHNPSMVQN7PKIIFJUUW6X3 X-Message-ID-Hash: 767ZLO2JH3YHNPSMVQN7PKIIFJUUW6X3 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --X4rcHk9MnY4ykQEf Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Apr 03, 2026 at 06:38:10PM +0200, Laurent Vivier wrote: > tcp_fill_headers() computed the TCP payload length from iov_tail_size(), > but with vhost-user multibuffer frames, the iov_tail will be larger than > the actual data. Pass the data length explicitly so that IP total > length, pseudo-header, and checksum computations use the correct value. >=20 > Signed-off-by: Laurent Vivier Reviewed-by: David Gibson > --- > tcp.c | 5 +++-- > tcp_buf.c | 3 ++- > tcp_internal.h | 2 +- > tcp_vu.c | 9 +++++---- > 4 files changed, 11 insertions(+), 8 deletions(-) >=20 > diff --git a/tcp.c b/tcp.c > index 49c6fb57ce16..6b0e25f33bf1 100644 > --- a/tcp.c > +++ b/tcp.c > @@ -945,6 +945,7 @@ static void tcp_fill_header(struct tcphdr *th, > * @ip6h: Pointer to IPv6 header, or NULL > * @th: Pointer to TCP header > * @payload: TCP payload > + * @dlen: TCP payload length > * @ip4_check: IPv4 checksum, if already known > * @seq: Sequence number for this segment > * @no_tcp_csum: Do not set TCP checksum > @@ -955,11 +956,11 @@ size_t tcp_fill_headers(const struct ctx *c, struct= tcp_tap_conn *conn, > struct ethhdr *eh, > struct iphdr *ip4h, struct ipv6hdr *ip6h, > struct tcphdr *th, struct iov_tail *payload, > - const uint16_t *ip4_check, uint32_t seq, > + size_t dlen, const uint16_t *ip4_check, uint32_t seq, > bool no_tcp_csum) > { > const struct flowside *tapside =3D TAPFLOW(conn); > - size_t l4len =3D iov_tail_size(payload) + sizeof(*th); > + size_t l4len =3D dlen + sizeof(*th); > uint8_t *omac =3D conn->f.tap_omac; > size_t l3len =3D l4len; > uint32_t psum =3D 0; > diff --git a/tcp_buf.c b/tcp_buf.c > index 41965b107567..27151854033c 100644 > --- a/tcp_buf.c > +++ b/tcp_buf.c > @@ -190,7 +190,8 @@ static void tcp_l2_buf_fill_headers(const struct ctx = *c, > else > ip6h =3D iov[TCP_IOV_IP].iov_base; > =20 > - l2len =3D tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &tail, check, s= eq, > + l2len =3D tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &tail, > + iov_tail_size(&tail), check, seq, > no_tcp_csum); > tap_hdr_update(taph, l2len); > } > diff --git a/tcp_internal.h b/tcp_internal.h > index d9408852571f..a0fa19f4ed11 100644 > --- a/tcp_internal.h > +++ b/tcp_internal.h > @@ -187,7 +187,7 @@ size_t tcp_fill_headers(const struct ctx *c, struct t= cp_tap_conn *conn, > struct ethhdr *eh, > struct iphdr *ip4h, struct ipv6hdr *ip6h, > struct tcphdr *th, struct iov_tail *payload, > - const uint16_t *ip4_check, uint32_t seq, > + size_t dlen, const uint16_t *ip4_check, uint32_t seq, > bool no_tcp_csum); > =20 > int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn, > diff --git a/tcp_vu.c b/tcp_vu.c > index 4eba7b8a5190..8c1894dca7fe 100644 > --- a/tcp_vu.c > +++ b/tcp_vu.c > @@ -136,7 +136,7 @@ int tcp_vu_send_flag(const struct ctx *c, struct tcp_= tap_conn *conn, int flags) > seq--; > =20 > tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, > - NULL, seq, !*c->pcap); > + optlen, NULL, seq, !*c->pcap); > =20 > vu_pad(&flags_elem[0].in_sg[0], l2len); > =20 > @@ -280,12 +280,13 @@ static ssize_t tcp_vu_sock_recv(const struct ctx *c= , struct vu_virtq *vq, > * @conn: Connection pointer > * @iov: Pointer to the array of IO vectors > * @iov_cnt: Number of entries in @iov > + * @dlen: Data length > * @check: Checksum, if already known > * @no_tcp_csum: Do not set TCP checksum > * @push: Set PSH flag, last segment in a batch > */ > static void tcp_vu_prepare(const struct ctx *c, struct tcp_tap_conn *con= n, > - struct iovec *iov, size_t iov_cnt, > + struct iovec *iov, size_t iov_cnt, size_t dlen, > const uint16_t **check, bool no_tcp_csum, bool push) > { > const struct flowside *toside =3D TAPFLOW(conn); > @@ -329,7 +330,7 @@ static void tcp_vu_prepare(const struct ctx *c, struc= t tcp_tap_conn *conn, > th->ack =3D 1; > th->psh =3D push; > =20 > - tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, > + tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, dlen, > *check, conn->seq_to_tap, no_tcp_csum); > if (ip4h) > *check =3D &ip4h->check; > @@ -457,7 +458,7 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct= tcp_tap_conn *conn) > check =3D NULL; > previous_dlen =3D dlen; > =20 > - tcp_vu_prepare(c, conn, iov, buf_cnt, &check, !*c->pcap, push); > + tcp_vu_prepare(c, conn, iov, buf_cnt, dlen, &check, !*c->pcap, push); > =20 > /* Pad first/single buffer only, it's at least ETH_ZLEN long */ > l2len =3D dlen + hdrlen - VNET_HLEN; > --=20 > 2.53.0 >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --X4rcHk9MnY4ykQEf Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmnYpWAACgkQzQJF27ox 2Gc0xw/+NS1gpNzljy0TdRSNOVuXApYzhMf4xy1B7yojJgXQakTTjPZFw1PFa5U3 HyPpBHkdsxcJWtJyRq3cSGEIiFJW5QnUHYQxf5eF52LF3LMbWWuC8Gr/D8NPPRaq l4LHZ5/7hGzwujsCxIAuUUBrwH3/Cm0VWaD4fupXpKRzLy9WhiTXB1y3c1Dqbgnv CCmhXRM6qkaYqfX0vr8bGYd9hUPWPvufG4irqC1FadMfpt286HmXZw3hohdeSqve /4S2YoWxrm9sULPo2MZgvf4oDtv+DuoS7yig7zSWF0kISgFFsqemQkak6BFqPK+L kvsKngqOaFC4fHzPDVwUqA75JzOLyZLzBOa3dxUVFTqwAqveVJK0RCJi3p5QHMky /PlgN/mJAkV4B7Khq08g+t6w1EmGbCfiC+3qAtCXOmp60DlTbbbCUHWXMgw+/ppA jXH/7BZ+IaGwrzcYOEo747j0T/fDh3rUHS3S3e7iCCr7MbseKyHa60d2Z7A/o30Z CjriqCZGjvH8YB17+QyCAHshx1zbO7Lom1TAoHaa4exV6DMOOcqYOMwsNteKRrbG cLVG3K/UWE4jbAcwUvV7WizHRRDIW4aJWq5QxKOSUdxZf0WOXqJ/lcR+7JZxbuUd Jt2wr5w1Rg9QFdMP5MDOooq/LdpuvJuoZGtFWP7MFJuzsD3dsx8= =dK7W -----END PGP SIGNATURE----- --X4rcHk9MnY4ykQEf--