From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 90B365A031F for ; Fri, 05 Jul 2024 12:44:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1720176252; bh=f2O+E+TZRoELtyyZQf6iNcSyfkMEen3PMt+uWe8MDxQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DIEISX2X1bDYeLcMWaflP//4qn17jKoJYctaE1k8RQdtHHcwpUvi3VkejTQcj5UT4 wVpBPdbVIKQvCupQ/nban6afro1UladPhO9ZLIwKTgxXZuMk812TF+uDXBsi0pX2eT IZP7dgLZqzTHv2DvcwC8tPCNR82Yci5oK2t47R0abMNWdNwMrCBEZBKmmn9AmkA588 yN9qsIHJyfvvwgrqDROMv0cV+CXq6TbJ8ZPdX6/cWWqBhGjv4Y9cqlIqdsv4KKzT3k QD17wDVEo8g2EJ4yJj4lUlQhWC37ztawYNDkzbOXujuEoY7DWRpBGVeHQLCU3JepwS Hnc+1TA0014wA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4WFqrX06rPz4x6q; Fri, 5 Jul 2024 20:44:11 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 06/11] udp: Unify udp[46]_l2_iov Date: Fri, 5 Jul 2024 20:44:04 +1000 Message-ID: <20240705104409.3847002-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240705104409.3847002-1-david@gibson.dropbear.id.au> References: <20240705104409.3847002-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: FX7P4SXRJNEB2DLFGCSCQSDHNXUGSLBC X-Message-ID-Hash: FX7P4SXRJNEB2DLFGCSCQSDHNXUGSLBC 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: David Gibson 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: The only differences between these arrays are that udp4_l2_iov is pre-initialised to point to the IPv4 ethernet header, and IPv4 per-frame header and udp6_l2_iov points to the IPv6 versions. We already have to set up a bunch of headers per-frame, including updating udp[46]_l2_iov[i][UDP_IOV_PAYLOAD].iov_len. It makes more sense to adjust the IOV entries to point at the correct headers for the frame than to have two complete sets of iovecs. Signed-off-by: David Gibson --- udp.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/udp.c b/udp.c index 2d34f6ac..8729dea2 100644 --- a/udp.c +++ b/udp.c @@ -241,8 +241,7 @@ static struct iovec udp_iov_splice [UDP_MAX_FRAMES]; static struct mmsghdr udp_mh_splice [UDP_MAX_FRAMES]; /* IOVs for L2 frames */ -static struct iovec udp4_l2_iov [UDP_MAX_FRAMES][UDP_NUM_IOVS]; -static struct iovec udp6_l2_iov [UDP_MAX_FRAMES][UDP_NUM_IOVS]; +static struct iovec udp_l2_iov [UDP_MAX_FRAMES][UDP_NUM_IOVS]; /** @@ -305,8 +304,9 @@ void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s) static void udp_iov_init_one(const struct ctx *c, size_t i) { struct udp_payload_t *payload = &udp_payload[i]; - struct iovec *siov = &udp_iov_recv[i]; struct udp_meta_t *meta = &udp_meta[i]; + struct iovec *siov = &udp_iov_recv[i]; + struct iovec *tiov = udp_l2_iov[i]; *meta = (struct udp_meta_t) { .ip4h = L2_BUF_IP4_INIT(IPPROTO_UDP), @@ -317,34 +317,29 @@ static void udp_iov_init_one(const struct ctx *c, size_t i) udp4_eth_hdr.h_proto = htons_constant(ETH_P_IP); udp6_eth_hdr.h_proto = htons_constant(ETH_P_IPV6); + tiov[UDP_IOV_TAP] = tap_hdr_iov(c, &meta->taph); + tiov[UDP_IOV_PAYLOAD].iov_base = payload; + + /* It's useful to have separate msghdr arrays for receiving. Otherwise, + * an IPv4 recv() will alter msg_namelen, so we'd have to reset it every + * time or risk truncating the address on future IPv6 recv()s. + */ if (c->ifi4) { struct msghdr *mh = &udp4_mh_recv[i].msg_hdr; - struct iovec *tiov = udp4_l2_iov[i]; mh->msg_name = &meta->s_in; mh->msg_namelen = sizeof(struct sockaddr_in); mh->msg_iov = siov; mh->msg_iovlen = 1; - - tiov[UDP_IOV_TAP] = tap_hdr_iov(c, &meta->taph); - tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(udp4_eth_hdr); - tiov[UDP_IOV_IP] = IOV_OF_LVALUE(meta->ip4h); - tiov[UDP_IOV_PAYLOAD].iov_base = payload; } if (c->ifi6) { struct msghdr *mh = &udp6_mh_recv[i].msg_hdr; - struct iovec *tiov = udp6_l2_iov[i]; mh->msg_name = &meta->s_in; mh->msg_namelen = sizeof(struct sockaddr_in6); mh->msg_iov = siov; mh->msg_iovlen = 1; - - tiov[UDP_IOV_TAP] = tap_hdr_iov(c, &meta->taph); - tiov[UDP_IOV_ETH] = IOV_OF_LVALUE(udp6_eth_hdr); - tiov[UDP_IOV_IP] = IOV_OF_LVALUE(meta->ip6h); - tiov[UDP_IOV_PAYLOAD].iov_base = payload; } } @@ -729,22 +724,19 @@ static unsigned udp_tap_send(const struct ctx *c, size_t start, size_t n, in_port_t dstport, union epoll_ref ref, const struct timespec *now) { - struct iovec (*tap_iov)[UDP_NUM_IOVS]; struct mmsghdr *mmh_recv; size_t i = start; ASSERT(udp_meta[start].splicesrc == -1); ASSERT(ref.type == EPOLL_TYPE_UDP); - if (ref.udp.v6) { - tap_iov = udp6_l2_iov; + if (ref.udp.v6) mmh_recv = udp6_mh_recv; - } else { + else mmh_recv = udp4_mh_recv; - tap_iov = udp4_l2_iov; - } do { + struct iovec (*tap_iov)[UDP_NUM_IOVS] = &udp_l2_iov[i]; struct udp_payload_t *bp = &udp_payload[i]; struct udp_meta_t *bm = &udp_meta[i]; size_t l4len; @@ -755,14 +747,18 @@ static unsigned udp_tap_send(const struct ctx *c, size_t start, size_t n, udp6_mh_recv[i].msg_len, now); tap_hdr_update(&bm->taph, l4len + sizeof(bm->ip6h) + sizeof(udp6_eth_hdr)); + (*tap_iov)[UDP_IOV_ETH] = IOV_OF_LVALUE(udp6_eth_hdr); + (*tap_iov)[UDP_IOV_IP] = IOV_OF_LVALUE(bm->ip6h); } else { l4len = udp_update_hdr4(c, &bm->ip4h, &bm->s_in.sa4, bp, dstport, udp4_mh_recv[i].msg_len, now); tap_hdr_update(&bm->taph, l4len + sizeof(bm->ip4h) + sizeof(udp4_eth_hdr)); + (*tap_iov)[UDP_IOV_ETH] = IOV_OF_LVALUE(udp4_eth_hdr); + (*tap_iov)[UDP_IOV_IP] = IOV_OF_LVALUE(bm->ip4h); } - tap_iov[i][UDP_IOV_PAYLOAD].iov_len = l4len; + (*tap_iov)[UDP_IOV_PAYLOAD].iov_len = l4len; if (++i >= n) break; @@ -770,7 +766,7 @@ static unsigned udp_tap_send(const struct ctx *c, size_t start, size_t n, udp_meta[i].splicesrc = udp_mmh_splice_port(ref, &mmh_recv[i]); } while (udp_meta[i].splicesrc == -1); - tap_send_frames(c, &tap_iov[start][0], UDP_NUM_IOVS, i - start); + tap_send_frames(c, &udp_l2_iov[start][0], UDP_NUM_IOVS, i - start); return i - start; } -- 2.45.2