From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 380F85A027D for ; Fri, 25 Nov 2022 08:29:28 +0100 (CET) Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4NJRM42lQ6z4xTx; Fri, 25 Nov 2022 18:29:20 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=201602; t=1669361360; bh=nDaJVmy3643S/TRFal9V7cF+UKc9/nQv4e/IFzb7O7A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jNu5TMSfmRk5e/B0DiZGrCV2XXyxty5quf/P4g7ldj4Pw3AhGYyIlw5CiiwVPVLiW z3k28OdxcZPlckysgy5bogXd3pCJucfNeyX6JT5l5R9AbYAsa1e8KEH5WrYQUNBhDa SItrffUBGHonArJGWgAP3n/uSMH0YfBDKIdxF9b4= From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v3 14/16] udp: Unify buffers for tap and splice paths Date: Fri, 25 Nov 2022 18:29:14 +1100 Message-Id: <20221125072916.3060938-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221125072916.3060938-1-david@gibson.dropbear.id.au> References: <20221125072916.3060938-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: NIULHUBD2RCXDXUAQPYMRMYPQII2HQWV X-Message-ID-Hash: NIULHUBD2RCXDXUAQPYMRMYPQII2HQWV 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.3 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: We maintain a set of buffers for UDP packets to be forwarded via the tap interface in udp[46]_l2_buf. We then have a separate set of buffers for packets to be "spliced" in udp_splice_buf[]. However, we only use one of these at a time, so we can share the buffer space. For the receiving splice packets we can not only re-use the data buffers but also the udp[46]_l2_iov_sock and udp[46]_l2_mh_sock control structures. For sending the splice packets we keep the same data buffers, but we need specific control structures. We create udp[46]_iov_splice - we can't reuse udp_l2_iov_sock[] because we need to write iov_len as we're writing spliced packets, but the tap path expects iov_len to remain the same (it only uses it for receive). Likewise we create udp[46]_mh_splice with the mmsghdr structures for sending spliced packets. As well as needing to reference different iovs, these need to all reference udp_splice_namebuf instead of individual msg_name fields for each slot. Signed-off-by: David Gibson --- udp.c | 71 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/udp.c b/udp.c index 03e88c5..4fc5c5c 100644 --- a/udp.c +++ b/udp.c @@ -219,9 +219,6 @@ struct udp6_l2_buf_t { #endif udp6_l2_buf[UDP_MAX_FRAMES]; -static struct sockaddr_storage udp_splice_namebuf; -static uint8_t udp_splice_buf[UDP_MAX_FRAMES][USHRT_MAX]; - /* recvmmsg()/sendmmsg() data for tap */ static struct iovec udp4_l2_iov_sock [UDP_MAX_FRAMES]; static struct iovec udp6_l2_iov_sock [UDP_MAX_FRAMES]; @@ -236,11 +233,13 @@ static struct mmsghdr udp4_l2_mh_tap [UDP_MAX_FRAMES]; static struct mmsghdr udp6_l2_mh_tap [UDP_MAX_FRAMES]; /* recvmmsg()/sendmmsg() data for "spliced" connections */ -static struct iovec udp_iov_recv [UDP_MAX_FRAMES]; -static struct mmsghdr udp_mmh_recv [UDP_MAX_FRAMES]; +static struct sockaddr_storage udp_splice_namebuf; -static struct iovec udp_iov_sendto [UDP_MAX_FRAMES]; -static struct mmsghdr udp_mmh_sendto [UDP_MAX_FRAMES]; +static struct iovec udp4_iov_splice [UDP_MAX_FRAMES]; +static struct iovec udp6_iov_splice [UDP_MAX_FRAMES]; + +static struct mmsghdr udp4_mh_splice [UDP_MAX_FRAMES]; +static struct mmsghdr udp6_mh_splice [UDP_MAX_FRAMES]; /** * udp_invert_portmap() - Compute reverse port translations for return packets @@ -522,16 +521,25 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, { in_port_t src, dst = ref.r.p.udp.udp.port; int s, v6 = ref.r.p.udp.udp.v6, n, i; + struct mmsghdr *mmh_recv, *mmh_send; if (!(events & EPOLLIN)) return; - n = recvmmsg(ref.r.s, udp_mmh_recv, UDP_MAX_FRAMES, 0, NULL); + if (v6) { + mmh_recv = udp6_l2_mh_sock; + mmh_send = udp6_mh_splice; + } else { + mmh_recv = udp4_l2_mh_sock; + mmh_send = udp4_mh_splice; + } + + n = recvmmsg(ref.r.s, mmh_recv, UDP_MAX_FRAMES, 0, NULL); if (n <= 0) return; - src = sa_port(v6, udp_mmh_recv[0].msg_hdr.msg_name); + src = sa_port(v6, mmh_recv[0].msg_hdr.msg_name); if (ref.r.p.udp.udp.ns) { src += c->udp.fwd_in.rdelta[src]; @@ -562,11 +570,8 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, udp_splice_ns[v6][src].ts = now->tv_sec; } - for (i = 0; i < n; i++) { - struct msghdr *mh_s = &udp_mmh_sendto[i].msg_hdr; - - mh_s->msg_iov->iov_len = udp_mmh_recv[i].msg_len; - } + for (i = 0; i < n; i++) + mmh_send[i].msg_hdr.msg_iov->iov_len = mmh_recv[i].msg_len; if (v6) { *((struct sockaddr_in6 *)&udp_splice_namebuf) = @@ -586,7 +591,7 @@ static void udp_sock_handler_splice(const struct ctx *c, union epoll_ref ref, }); } - sendmmsg(s, udp_mmh_sendto, n, MSG_NOSIGNAL); + sendmmsg(s, mmh_send, n, MSG_NOSIGNAL); } /** @@ -1163,37 +1168,23 @@ int udp_sock_init_ns(void *arg) */ static void udp_splice_iov_init(void) { - struct mmsghdr *h; - struct iovec *iov; int i; - for (i = 0, h = udp_mmh_recv; i < UDP_MAX_FRAMES; i++, h++) { - struct msghdr *mh = &h->msg_hdr; - - if (!i) { - mh->msg_name = &udp_splice_namebuf; - mh->msg_namelen = sizeof(udp_splice_namebuf); - } - - mh->msg_iov = &udp_iov_recv[i]; - mh->msg_iovlen = 1; - } - for (i = 0, iov = udp_iov_recv; i < UDP_MAX_FRAMES; i++, iov++) { - iov->iov_base = udp_splice_buf[i]; - iov->iov_len = sizeof(udp_splice_buf[i]); - } + for (i = 0; i < UDP_MAX_FRAMES; i++) { + struct msghdr *mh4 = &udp4_mh_splice[i].msg_hdr; + struct msghdr *mh6 = &udp6_mh_splice[i].msg_hdr; - for (i = 0, h = udp_mmh_sendto; i < UDP_MAX_FRAMES; i++, h++) { - struct msghdr *mh = &h->msg_hdr; + mh4->msg_name = mh6->msg_name = &udp_splice_namebuf; + mh4->msg_namelen = sizeof(udp_splice_namebuf); + mh6->msg_namelen = sizeof(udp_splice_namebuf); - mh->msg_name = &udp_splice_namebuf; - mh->msg_namelen = sizeof(udp_splice_namebuf); + udp4_iov_splice[i].iov_base = udp4_l2_buf[i].data; + udp6_iov_splice[i].iov_base = udp6_l2_buf[i].data; - mh->msg_iov = &udp_iov_sendto[i]; - mh->msg_iovlen = 1; + mh4->msg_iov = &udp4_iov_splice[i]; + mh6->msg_iov = &udp6_iov_splice[i]; + mh4->msg_iovlen = mh6->msg_iovlen = 1; } - for (i = 0, iov = udp_iov_sendto; i < UDP_MAX_FRAMES; i++, iov++) - iov->iov_base = udp_splice_buf[i]; } /** -- 2.38.1