From 63db7dcdbf4f8d528a6c04f73c338a686ad8a5fe Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 14 Jun 2024 11:51:06 +1000 Subject: [PATCH] udp: Fold checking of splice flag into udp_mmh_splice_port() 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 Signed-off-by: Stefano Brivio --- udp.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/udp.c b/udp.c index dba75d7..2d73408 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)