From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: passt.top; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fVaWi7/L; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by passt.top (Postfix) with ESMTPS id A9F545A026E for ; Wed, 01 Apr 2026 23:55:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1775080515; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zEJIDflouQARMmhEmYcb0fRW6sEv8nPwBJlyKGahuHY=; b=fVaWi7/L+mu8GHdaugF0GtrZc/jyKQx6UROIho43i8XtZe3i0J/M1+nMpbQS61MTv605VL oOccbBl4WEIDFnAeBXHR0qGIz8qfl9QVSsVg6+DIdXL4a9TJeUvPmQHt6vNVG3bjJ4YWNt q6G3vByrHL6rSyWsXLcKsac9KWqfgYs= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-541-EHZqMQC_NrWPsM4PhSJb1g-1; Wed, 01 Apr 2026 17:55:14 -0400 X-MC-Unique: EHZqMQC_NrWPsM4PhSJb1g-1 X-Mimecast-MFC-AGG-ID: EHZqMQC_NrWPsM4PhSJb1g_1775080513 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 82BE61800612 for ; Wed, 1 Apr 2026 21:55:13 +0000 (UTC) Received: from lenovo-t14s.redhat.corp (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BA91A1800767; Wed, 1 Apr 2026 21:55:12 +0000 (UTC) From: Laurent Vivier To: passt-dev@passt.top Subject: [PATCH v4 2/4] tcp_vu: Build headers on the stack and write them into the iovec Date: Wed, 1 Apr 2026 23:55:06 +0200 Message-ID: <20260401215508.2149752-3-lvivier@redhat.com> In-Reply-To: <20260401215508.2149752-1-lvivier@redhat.com> References: <20260401215508.2149752-1-lvivier@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: DSWcQ4R_3E6IDKJupm-AJMDWAVMB0DTOC7zPuZA2FEg_1775080513 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true Message-ID-Hash: Z733KWX5HPLZEINEKV66DBLU5GEMBUSN X-Message-ID-Hash: Z733KWX5HPLZEINEKV66DBLU5GEMBUSN X-MailFrom: lvivier@redhat.com 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: Laurent Vivier 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: tcp_vu_prepare() currently assumes the first iovec element provided by the guest is large enough to hold all L2-L4 headers, and builds them in place via pointer casts into iov[0].iov_base. This assumption is enforced by an assert(). Since the headers in the buffer are uninitialized anyway, we can just as well build the Ethernet, IP, and TCP headers on the stack instead, and write them into the iovec with IOV_PUSH_HEADER(). This mirrors the approach already used in udp_vu_prepare(), and prepares for support of elements with multiple iovecs. Signed-off-by: Laurent Vivier --- tcp_vu.c | 60 ++++++++++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/tcp_vu.c b/tcp_vu.c index 23d2b62acacb..484f60774448 100644 --- a/tcp_vu.c +++ b/tcp_vu.c @@ -295,49 +295,41 @@ static void tcp_vu_prepare(const struct ctx *c, struct tcp_tap_conn *conn, bool v6 = !(inany_v4(&toside->eaddr) && inany_v4(&toside->oaddr)); size_t hdrlen = tcp_vu_hdrlen(v6); struct iov_tail payload = IOV_TAIL(iov, iov_cnt, hdrlen); - char *base = iov[0].iov_base; - struct ipv6hdr *ip6h = NULL; - struct iphdr *ip4h = NULL; - struct tcphdr *th; - struct ethhdr *eh; - - /* we guess the first iovec provided by the guest can embed - * all the headers needed by L2 frame, including any padding - */ - assert(iov[0].iov_len >= hdrlen); + struct ipv6hdr ip6h; + struct iphdr ip4h; + struct tcphdr th; + struct ethhdr eh; - eh = vu_eth(base); - - memcpy(eh->h_dest, c->guest_mac, sizeof(eh->h_dest)); + memcpy(eh.h_dest, c->guest_mac, sizeof(eh.h_dest)); /* initialize header */ - if (!v6) { - eh->h_proto = htons(ETH_P_IP); - - ip4h = vu_ip(base); - *ip4h = (struct iphdr)L2_BUF_IP4_INIT(IPPROTO_TCP); - th = vu_payloadv4(base); - } else { - eh->h_proto = htons(ETH_P_IPV6); + if (!v6) + ip4h = (struct iphdr)L2_BUF_IP4_INIT(IPPROTO_TCP); + else + ip6h = (struct ipv6hdr)L2_BUF_IP6_INIT(IPPROTO_TCP); - ip6h = vu_ip(base); - *ip6h = (struct ipv6hdr)L2_BUF_IP6_INIT(IPPROTO_TCP); + memset(&th, 0, sizeof(th)); + th.doff = sizeof(th) / 4; + th.ack = 1; + th.psh = push; - th = vu_payloadv6(base); - } + tcp_fill_headers(c, conn, &eh, v6 ? NULL : &ip4h, v6 ? &ip6h : NULL, &th, + &payload, dlen, *csum_flags, conn->seq_to_tap); - memset(th, 0, sizeof(*th)); - th->doff = sizeof(*th) / 4; - th->ack = 1; - th->psh = push; + /* Preserve TCP_CSUM, overwrite IP4_CSUM as we set the checksum */ + if (!v6) + *csum_flags = (*csum_flags & TCP_CSUM) | ip4h.check; - tcp_fill_headers(c, conn, eh, ip4h, ip6h, th, &payload, dlen, - *csum_flags, conn->seq_to_tap); + /* write headers */ + payload = IOV_TAIL(iov, iov_cnt, VNET_HLEN); - /* Preserve TCP_CSUM, overwrite IP4_CSUM as we set the checksum */ - if (ip4h) - *csum_flags = (*csum_flags & TCP_CSUM) | ip4h->check; + IOV_PUSH_HEADER(&payload, eh); + if (!v6) + IOV_PUSH_HEADER(&payload, ip4h); + else + IOV_PUSH_HEADER(&payload, ip6h); + IOV_PUSH_HEADER(&payload, th); } /** -- 2.53.0