public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>, passt-dev@passt.top
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v2 2/4] udp: Fold checking of splice flag into udp_mmh_splice_port()
Date: Fri, 14 Jun 2024 11:51:06 +1000	[thread overview]
Message-ID: <20240614015108.2761502-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20240614015108.2761502-1-david@gibson.dropbear.id.au>

udp_mmh_splice_port() is used to determine if a UDP datagram can be
"spliced" (forwarded via a socket instead of tap).  We only invoke it if
the origin socket has the 'splice' flag set.

Fold the checking of the flag into the helper itself, which makes the
caller simpler.  It does mean we have a loop looking for a batch of
spliceable or non-spliceable packets even in the case where the flag is
clear.  This shouldn't be that expensive though, since each call to
udp_mmh_splice_port() will return without accessing memory in that case.
In any case we're going to need a similar loop in more cases with upcoming
flow table work.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 udp.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/udp.c b/udp.c
index dba75d7f..2d734081 100644
--- a/udp.c
+++ b/udp.c
@@ -466,21 +466,25 @@ static int udp_splice_new_ns(void *arg)
 
 /**
  * udp_mmh_splice_port() - Is source address of message suitable for splicing?
- * @v6:		Is @sa a sockaddr_in6 (otherwise sockaddr_in)?
+ * @uref:	UDP epoll reference for incoming message's origin socket
  * @mmh:	mmsghdr of incoming message
  *
- * Return: if @sa refers to localhost (127.0.0.1 or ::1) the port from
- *         @sa in host order, otherwise -1.
+ * Return: if source address of message in @mmh refers to localhost (127.0.0.1
+ *         or ::1) its source port (host order), otherwise -1.
  */
-static int udp_mmh_splice_port(bool v6, const struct mmsghdr *mmh)
+static int udp_mmh_splice_port(union udp_epoll_ref uref,
+			       const struct mmsghdr *mmh)
 {
 	const struct sockaddr_in6 *sa6 = mmh->msg_hdr.msg_name;
 	const struct sockaddr_in *sa4 = mmh->msg_hdr.msg_name;
 
-	if (v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
+	if (!uref.splice)
+		return -1;
+
+	if (uref.v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
 		return ntohs(sa6->sin6_port);
 
-	if (!v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
+	if (!uref.v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
 		return ntohs(sa4->sin_port);
 
 	return -1;
@@ -775,18 +779,15 @@ void udp_buf_sock_handler(const struct ctx *c, union epoll_ref ref, uint32_t eve
 
 	for (i = 0; i < n; i += m) {
 		int splicefrom = -1;
-		m = n;
 
-		if (ref.udp.splice) {
-			splicefrom = udp_mmh_splice_port(v6, mmh_recv + i);
+		splicefrom = udp_mmh_splice_port(ref.udp, mmh_recv + i);
 
-			for (m = 1; i + m < n; m++) {
-				int p;
+		for (m = 1; i + m < n; m++) {
+			int p;
 
-				p = udp_mmh_splice_port(v6, mmh_recv + i + m);
-				if (p != splicefrom)
-					break;
-			}
+			p = udp_mmh_splice_port(ref.udp, mmh_recv + i + m);
+			if (p != splicefrom)
+				break;
 		}
 
 		if (splicefrom >= 0)
-- 
@@ -466,21 +466,25 @@ static int udp_splice_new_ns(void *arg)
 
 /**
  * udp_mmh_splice_port() - Is source address of message suitable for splicing?
- * @v6:		Is @sa a sockaddr_in6 (otherwise sockaddr_in)?
+ * @uref:	UDP epoll reference for incoming message's origin socket
  * @mmh:	mmsghdr of incoming message
  *
- * Return: if @sa refers to localhost (127.0.0.1 or ::1) the port from
- *         @sa in host order, otherwise -1.
+ * Return: if source address of message in @mmh refers to localhost (127.0.0.1
+ *         or ::1) its source port (host order), otherwise -1.
  */
-static int udp_mmh_splice_port(bool v6, const struct mmsghdr *mmh)
+static int udp_mmh_splice_port(union udp_epoll_ref uref,
+			       const struct mmsghdr *mmh)
 {
 	const struct sockaddr_in6 *sa6 = mmh->msg_hdr.msg_name;
 	const struct sockaddr_in *sa4 = mmh->msg_hdr.msg_name;
 
-	if (v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
+	if (!uref.splice)
+		return -1;
+
+	if (uref.v6 && IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
 		return ntohs(sa6->sin6_port);
 
-	if (!v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
+	if (!uref.v6 && IN4_IS_ADDR_LOOPBACK(&sa4->sin_addr))
 		return ntohs(sa4->sin_port);
 
 	return -1;
@@ -775,18 +779,15 @@ void udp_buf_sock_handler(const struct ctx *c, union epoll_ref ref, uint32_t eve
 
 	for (i = 0; i < n; i += m) {
 		int splicefrom = -1;
-		m = n;
 
-		if (ref.udp.splice) {
-			splicefrom = udp_mmh_splice_port(v6, mmh_recv + i);
+		splicefrom = udp_mmh_splice_port(ref.udp, mmh_recv + i);
 
-			for (m = 1; i + m < n; m++) {
-				int p;
+		for (m = 1; i + m < n; m++) {
+			int p;
 
-				p = udp_mmh_splice_port(v6, mmh_recv + i + m);
-				if (p != splicefrom)
-					break;
-			}
+			p = udp_mmh_splice_port(ref.udp, mmh_recv + i + m);
+			if (p != splicefrom)
+				break;
 		}
 
 		if (splicefrom >= 0)
-- 
2.45.2


  parent reply	other threads:[~2024-06-14  1:51 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-14  1:51 [PATCH v2 0/4] Even more flow table preliminaries David Gibson
2024-06-14  1:51 ` [PATCH v2 1/4] util: Split construction of bind socket address from the rest of sock_l4() David Gibson
2024-06-14  1:51 ` David Gibson [this message]
2024-06-14  1:51 ` [PATCH v2 3/4] udp: Rework how we divide queued datagrams between sending methods David Gibson
2024-06-14  1:51 ` [PATCH v2 4/4] udp: Move management of udp[46]_localname into udp_splice_send() David Gibson
2024-06-14 11:14 ` [PATCH v2 0/4] Even more flow table preliminaries Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240614015108.2761502-3-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).