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=m1ddSKw9; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 59FF25A0274 for ; Mon, 02 Mar 2026 01:46:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1772412374; bh=mmKpRFBaGblWSVkbRwamXx7TsfZz7aRK+26C21UF4r4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=m1ddSKw9ZHLG4G8jdIdkvt2rF5xE2tDw4QKrOG2RiAy06TZsjqldFbuSMJmykkqpa ZkcBMEQ6SKAm9jI6CPNwCW2pwYPZQApgcPVlX62rFyYgwo6Ep6qewSwiqrW9Gf61IQ TCS88eze1GXrmKeupY9e1KiS32TzGp2baBZ1BxAyu4vo+HnLdeJ12jggPXnTm58fzm ihVzIYgKDDgqyArnx3A9XMlKhdduwt38VakoJu1wQQHVePLiD1VfgbRISPIw9JKlg2 lK5BU70ylelQBid/bZBsWwaxWaSVgDqkOUB/+0ge09aHrV1UXLDKdWoyLrNYwlMKB8 efda+PzWy0Xdg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4fPKxL5XxRz4wC6; Mon, 02 Mar 2026 11:46:14 +1100 (AEDT) Date: Mon, 2 Mar 2026 11:24:15 +1100 From: David Gibson To: Laurent Vivier Subject: Re: [PATCH 07/12] udp_vu: Use iov_tail in udp_vu_prepare() Message-ID: References: <20260227140330.2216753-1-lvivier@redhat.com> <20260227140330.2216753-8-lvivier@redhat.com> MIME-Version: 1.0 In-Reply-To: <20260227140330.2216753-8-lvivier@redhat.com> 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 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="uG2a/5Z1BDeVlJhc" Content-Disposition: inline Message-ID-Hash: HQIVJJQXQJ2GRWZT2IHXCKOQLGP262UL X-Message-ID-Hash: HQIVJJQXQJ2GRWZT2IHXCKOQLGP262UL 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: --uG2a/5Z1BDeVlJhc Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Feb 27, 2026 at 03:03:25PM +0100, Laurent Vivier wrote: > Rework udp_vu_prepare() to use IOV_REMOVE_HEADER() and IOV_PUT_HEADER() > to walk through Ethernet, IP and UDP headers instead of the layout-specif= ic > helpers (vu_eth(), vu_ip(), vu_payloadv4(), vu_payloadv6()) that assume a > contiguous buffer. The payload length is now implicit in the iov_tail, s= o > drop the dlen parameter. >=20 > Signed-off-by: Laurent Vivier LGTM, a few nits below. > --- > iov.c | 1 - > udp_vu.c | 63 ++++++++++++++++++++++++++++++-------------------------- > 2 files changed, 34 insertions(+), 30 deletions(-) >=20 > diff --git a/iov.c b/iov.c > index 2cf23d284e4a..7c9641968271 100644 > --- a/iov.c > +++ b/iov.c > @@ -304,7 +304,6 @@ void *iov_peek_header_(struct iov_tail *tail, void *v= , size_t len, size_t align) > * > * Return: number of bytes written > */ > -/* cppcheck-suppress unusedFunction */ > size_t iov_put_header_(struct iov_tail *tail, const void *v, size_t len) > { > =09size_t l =3D len; > diff --git a/udp_vu.c b/udp_vu.c > index dd8904d65a38..6d87f4872268 100644 > --- a/udp_vu.c > +++ b/udp_vu.c > @@ -101,52 +101,54 @@ static ssize_t udp_vu_sock_recv(struct iov_tail *da= ta, int s, bool v6) > * @c:=09=09Execution context > * @data:=09IO vector tail for the frame > * @toside:=09Address information for one side of the flow > - * @dlen:=09Packet data length > * > * Return: Layer-4 length > */ > static size_t udp_vu_prepare(const struct ctx *c, const struct iov_tail = *data, > -=09=09=09 const struct flowside *toside, ssize_t dlen) > +=09=09=09 const struct flowside *toside) > { > -=09const struct iovec *iov =3D data->iov; > -=09struct ethhdr *eh; > +=09struct iov_tail current =3D *data; > +=09struct ethhdr *eh, eh_storage; > +=09struct udphdr *uh, uh_storage; > =09size_t l4len; > =20 > =09/* ethernet header */ > -=09eh =3D vu_eth(iov[0].iov_base); > +=09eh =3D IOV_REMOVE_HEADER(¤t, eh_storage); > =20 > =09memcpy(eh->h_dest, c->guest_mac, sizeof(eh->h_dest)); > =09memcpy(eh->h_source, c->our_tap_mac, sizeof(eh->h_source)); > =20 > =09/* initialize header */ > =09if (inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr)) { > -=09=09struct iphdr *iph =3D vu_ip(iov[0].iov_base); > -=09=09struct udp_payload_t *bp =3D vu_payloadv4(iov[0].iov_base); > -=09=09const struct iovec payload_iov =3D { > -=09=09=09.iov_base =3D bp->data, > -=09=09=09.iov_len =3D dlen, > -=09=09}; > -=09=09struct iov_tail payload =3D IOV_TAIL(&payload_iov, 1, 0); > +=09=09struct iphdr *iph, iph_storage; > =20 > =09=09eh->h_proto =3D htons(ETH_P_IP); > =20 > +=09=09iph =3D IOV_REMOVE_HEADER(¤t, iph_storage); > =09=09*iph =3D (struct iphdr)L2_BUF_IP4_INIT(IPPROTO_UDP); > =20 > -=09=09l4len =3D udp_update_hdr4(iph, &bp->uh, &payload, toside, true); > +=09=09uh =3D IOV_REMOVE_HEADER(¤t, uh_storage); > +=09=09l4len =3D udp_update_hdr4(iph, uh, ¤t, toside, true); > + > +=09=09current =3D *data; > +=09=09IOV_PUT_HEADER(¤t, eh); > +=09=09IOV_PUT_HEADER(¤t, iph); > +=09=09IOV_PUT_HEADER(¤t, uh); The puts for eh and uh can be factored out of the if/else. > =09} else { > -=09=09struct ipv6hdr *ip6h =3D vu_ip(iov[0].iov_base); > -=09=09struct udp_payload_t *bp =3D vu_payloadv6(iov[0].iov_base); > -=09=09const struct iovec payload_iov =3D { > -=09=09=09.iov_base =3D bp->data, > -=09=09=09.iov_len =3D dlen, > -=09=09}; > -=09=09struct iov_tail payload =3D IOV_TAIL(&payload_iov, 1, 0); > +=09=09struct ipv6hdr *ip6h, ip6h_storage; > =20 > =09=09eh->h_proto =3D htons(ETH_P_IPV6); > =20 > +=09=09ip6h =3D IOV_REMOVE_HEADER(¤t, ip6h_storage); > =09=09*ip6h =3D (struct ipv6hdr)L2_BUF_IP6_INIT(IPPROTO_UDP); > =20 > -=09=09l4len =3D udp_update_hdr6(ip6h, &bp->uh, &payload, toside, true); > +=09=09uh =3D IOV_REMOVE_HEADER(¤t, uh_storage); > +=09=09l4len =3D udp_update_hdr6(ip6h, uh, ¤t, toside, true); > + > +=09=09current =3D *data; > +=09=09IOV_PUT_HEADER(¤t, eh); > +=09=09IOV_PUT_HEADER(¤t, ip6h); > +=09=09IOV_PUT_HEADER(¤t, uh); > =09} > =20 > =09return l4len; > @@ -165,9 +167,10 @@ static void udp_vu_csum(const struct flowside *tosid= e, > =09struct iov_tail payload =3D *data; > =09struct udphdr *uh, uh_storage; > =09bool ipv4 =3D src4 && dst4; > +=09int hdrlen =3D sizeof(struct ethhdr) + > +=09=09 (ipv4 ? sizeof(struct iphdr) : sizeof(struct ipv6hdr)); > =20 > -=09iov_drop_header(&payload, > -=09=09=09udp_vu_hdrlen(!ipv4) - sizeof(struct udphdr)); > +=09iov_drop_header(&payload, hdrlen); udp_vu_prepare() and udp_vu_csum() independently locate the UDP header, but they're called in fairly close proximity. Would it make more sense to pass the UDP header and payload tail separately to each of them? > =09uh =3D IOV_REMOVE_HEADER(&payload, uh_storage); > =20 > =09if (ipv4) > @@ -208,8 +211,8 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s, i= nt n, flow_sidx_t tosidx) > =09} > =20 > =09for (i =3D 0; i < n; i++) { > +=09=09int elem_cnt, elem_used; > =09=09ssize_t dlen; > -=09=09int elem_cnt; > =20 > =09=09vu_init_elem(elem, iov_vu, ARRAY_SIZE(elem)); > =20 > @@ -225,18 +228,20 @@ void udp_vu_sock_to_tap(const struct ctx *c, int s,= int n, flow_sidx_t tosidx) > =09=09=09vu_queue_rewind(vq, elem_cnt); > =09=09=09continue; > =09=09} > +=09=09elem_used =3D data.cnt; > =20 > =09=09/* release unused buffers */ > -=09=09vu_queue_rewind(vq, elem_cnt - data.cnt); > +=09=09vu_queue_rewind(vq, elem_cnt - elem_used); > =20 > =09=09if (data.cnt > 0) { > -=09=09=09vu_set_vnethdr(vdev, data.iov[0].iov_base, data.cnt); > -=09=09=09udp_vu_prepare(c, &data, toside, dlen); > +=09=09=09vu_set_vnethdr(vdev, data.iov[0].iov_base, elem_used); > +=09=09=09iov_drop_header(&data, VNET_HLEN); > +=09=09=09udp_vu_prepare(c, &data, toside); > =09=09=09if (*c->pcap) { > =09=09=09=09udp_vu_csum(toside, &data); > -=09=09=09=09pcap_iov(data.iov, data.cnt, VNET_HLEN); > +=09=09=09=09pcap_iov(data.iov, data.cnt, 0); > =09=09=09} > -=09=09=09vu_flush(vdev, vq, elem, data.cnt); > +=09=09=09vu_flush(vdev, vq, elem, elem_used); > =09=09} > =09} > } > --=20 > 2.53.0 >=20 --=20 David Gibson (he or they)=09| I'll have my music baroque, and my code david AT gibson.dropbear.id.au=09| minimalist, thank you, not the other way =09=09=09=09| around. http://www.ozlabs.org/~dgibson --uG2a/5Z1BDeVlJhc Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmmk2K4ACgkQzQJF27ox 2GfsXQ//QFDFhqaWHAb/QQDMBqhyw3hLeH5o4yu8CmBAXb2ojaPMztsPqB3+RzFh Jq2/PPAPePYWVKjb+F15JUPmdsteNfbfAgKaEN9nxNxRpqDNk2WrajSLIkqvGNPw eMqnyS0iIuShuEAHsIVd6rQhy9SMryuQ8/q8lOuWAf8TnAdRW4ogM+b+SVMHt9po rasVyYI49/2nnB8RcorP/2ZawACNTFZw331ISTncIGfOo+A4GiyynGH7YbiJUVD8 gRRIDQy52n4P3hW32aa+JnfcJWBIPM9gAFuRCZOR9VbTy+7d+qx/OHPrqk6DJn3v DVvxzfrutqdN/M/g0f9JL1TEDpWPOcjpjWmHfqSAw5BgAX8Kn6eP+Uv/v+57ikSS 5GYFB1UZm4rVgQ5Ey2BOMbm5MqfLeDBAxUkfxkj+tXj3E/CFmGL+wyko6yS+AnBj lwCpc0CZN+zgVfRAb+mOt1u8Z1SesSI+hWAb0ifx5uj8w3viRV0XPfAmjL3auA0l mp7fw757KIYFCsj5C1OeFuMHxcAAuSCMGtcjJ4/HJkNjm8+8byxVkmjOXMkN0YpM FbmtYnFeUfkUUGJmIGDzKcj7XyaHLZK4hthNlHvS0apBP/NNizTgNiqUlmyhwWgu c5mp0yHhbyOVERCQzmvNbB8xwFkvIyTNCxhaZW5wQhPSGl8acEA= =sBzl -----END PGP SIGNATURE----- --uG2a/5Z1BDeVlJhc--