Blame SOURCES/0014-tcp-udp-Fix-partial-success-return-codes-in-tcp-udp-.patch

f07426
From 8f71f17cc087fc80f1cbe9b71852b95916a9afbc Mon Sep 17 00:00:00 2001
f07426
From: Stefano Brivio <sbrivio@redhat.com>
f07426
Date: Wed, 8 Mar 2023 12:38:39 +0100
f07426
Subject: [PATCH 14/20] tcp, udp: Fix partial success return codes in
f07426
 {tcp,udp}_sock_init()
f07426
f07426
The comments say we should return 0 on partial success, and an error
f07426
code on complete failure. Rationale: if the user configures a port
f07426
forwarding, and we succeed to bind that port for IPv4 or IPv6 only,
f07426
that might actually be what the user intended.
f07426
f07426
Adjust the two functions to reflect the comments.
f07426
f07426
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
f07426
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
f07426
(cherry picked from commit 5aea2f88ab5f63f01885109a4afb1271607fc06b)
f07426
---
f07426
 tcp.c | 21 +++++++++------------
f07426
 udp.c | 30 ++++++++++++++----------------
f07426
 2 files changed, 23 insertions(+), 28 deletions(-)
f07426
f07426
diff --git a/tcp.c b/tcp.c
f07426
index 482c2f9..001fa50 100644
f07426
--- a/tcp.c
f07426
+++ b/tcp.c
f07426
@@ -2929,7 +2929,7 @@ static int tcp_sock_init_af(const struct ctx *c, int af, in_port_t port,
f07426
 int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr,
f07426
 		  const char *ifname, in_port_t port)
f07426
 {
f07426
-	int ret = 0, af_ret;
f07426
+	int r4 = SOCKET_MAX + 1, r6 = SOCKET_MAX + 1;
f07426
 
f07426
 	if (af == AF_UNSPEC && c->ifi4 && c->ifi6)
f07426
 		/* Attempt to get a dual stack socket */
f07426
@@ -2937,19 +2937,16 @@ int tcp_sock_init(const struct ctx *c, sa_family_t af, const void *addr,
f07426
 			return 0;
f07426
 
f07426
 	/* Otherwise create a socket per IP version */
f07426
-	if ((af == AF_INET  || af == AF_UNSPEC) && c->ifi4) {
f07426
-		af_ret = tcp_sock_init_af(c, AF_INET, port, addr, ifname);
f07426
-		if (af_ret < 0)
f07426
-			ret = af_ret;
f07426
-	}
f07426
+	if ((af == AF_INET  || af == AF_UNSPEC) && c->ifi4)
f07426
+		r4 = tcp_sock_init_af(c, AF_INET, port, addr, ifname);
f07426
 
f07426
-	if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) {
f07426
-		af_ret = tcp_sock_init_af(c, AF_INET6, port, addr, ifname);
f07426
-		if (af_ret < 0)
f07426
-			ret = af_ret;
f07426
-	}
f07426
+	if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6)
f07426
+		r6 = tcp_sock_init_af(c, AF_INET6, port, addr, ifname);
f07426
 
f07426
-	return ret;
f07426
+	if (IN_INTERVAL(0, SOCKET_MAX, r4) || IN_INTERVAL(0, SOCKET_MAX, r6))
f07426
+		return 0;
f07426
+
f07426
+	return r4 < 0 ? r4 : r6;
f07426
 }
f07426
 
f07426
 /**
f07426
diff --git a/udp.c b/udp.c
f07426
index 9a43835..20ee0f2 100644
f07426
--- a/udp.c
f07426
+++ b/udp.c
f07426
@@ -962,7 +962,7 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
f07426
 		  const void *addr, const char *ifname, in_port_t port)
f07426
 {
f07426
 	union udp_epoll_ref uref = { .u32 = 0 };
f07426
-	int s, ret = 0;
f07426
+	int s, r4 = SOCKET_MAX + 1, r6 = SOCKET_MAX + 1;
f07426
 
f07426
 	if (ns) {
f07426
 		uref.udp.port = (in_port_t)(port +
f07426
@@ -978,8 +978,8 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
f07426
 		uref.udp.orig = true;
f07426
 
f07426
 		if (!ns) {
f07426
-			s = sock_l4(c, AF_INET, IPPROTO_UDP, addr, ifname,
f07426
-				    port, uref.u32);
f07426
+			r4 = s = sock_l4(c, AF_INET, IPPROTO_UDP, addr,
f07426
+					 ifname, port, uref.u32);
f07426
 
f07426
 			udp_tap_map[V4][uref.udp.port].sock = s < 0 ? -1 : s;
f07426
 			udp_splice_init[V4][port].sock = s < 0 ? -1 : s;
f07426
@@ -987,13 +987,10 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
f07426
 			struct in_addr loopback = { htonl(INADDR_LOOPBACK) };
f07426
 			uref.udp.ns = true;
f07426
 
f07426
-			s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback,
f07426
-				    ifname, port, uref.u32);
f07426
+			r4 = s = sock_l4(c, AF_INET, IPPROTO_UDP, &loopback,
f07426
+					 ifname, port, uref.u32);
f07426
 			udp_splice_ns[V4][port].sock = s < 0 ? -1 : s;
f07426
 		}
f07426
-
f07426
-		if (s < 0)
f07426
-			ret = s;
f07426
 	}
f07426
 
f07426
 	if ((af == AF_INET6 || af == AF_UNSPEC) && c->ifi6) {
f07426
@@ -1002,24 +999,25 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
f07426
 		uref.udp.orig = true;
f07426
 
f07426
 		if (!ns) {
f07426
-			s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr, ifname,
f07426
-				    port, uref.u32);
f07426
+			r6 = s = sock_l4(c, AF_INET6, IPPROTO_UDP, addr,
f07426
+					 ifname, port, uref.u32);
f07426
 
f07426
 			udp_tap_map[V6][uref.udp.port].sock = s < 0 ? -1 : s;
f07426
 			udp_splice_init[V6][port].sock = s < 0 ? -1 : s;
f07426
 		} else {
f07426
 			uref.udp.ns = true;
f07426
 
f07426
-			s = sock_l4(c, AF_INET6, IPPROTO_UDP, &in6addr_loopback,
f07426
-				    ifname, port, uref.u32);
f07426
+			r6 = s = sock_l4(c, AF_INET6, IPPROTO_UDP,
f07426
+					 &in6addr_loopback,
f07426
+					 ifname, port, uref.u32);
f07426
 			udp_splice_ns[V6][port].sock = s < 0 ? -1 : s;
f07426
 		}
f07426
-
f07426
-		if (s < 0)
f07426
-			ret = s;
f07426
 	}
f07426
 
f07426
-	return ret;
f07426
+	if (IN_INTERVAL(0, SOCKET_MAX, r4) || IN_INTERVAL(0, SOCKET_MAX, r6))
f07426
+		return 0;
f07426
+
f07426
+	return r4 < 0 ? r4 : r6;
f07426
 }
f07426
 
f07426
 /**
f07426
-- 
f07426
2.39.2
f07426