git: 3aff4ccdd714 - main - netinet: Remove IP(V6)_BINDMULTI

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 27 Feb 2023 15:03:45 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=3aff4ccdd714105db340d68f1a2aea2f46e99122

commit 3aff4ccdd714105db340d68f1a2aea2f46e99122
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-02-27 14:52:28 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-02-27 15:03:11 +0000

    netinet: Remove IP(V6)_BINDMULTI
    
    This option was added in commit 0a100a6f1ee5 but was never completed.
    In particular, there is no logic to map flowids to different listening
    sockets, so it accomplishes basically the same thing as SO_REUSEPORT.
    Meanwhile, we've since added SO_REUSEPORT_LB, which at least tries to
    balance among listening sockets using a hash of the 4-tuple and some
    optional NUMA policy.
    
    The option was never documented or completed, and an exp-run revealed
    nothing using it in the ports tree.  Moreover, it complicates the
    already very complicated in_pcbbind_setup(), and the checking in
    in_pcbbind_check_bindmulti() is insufficient.  So, let's remove it.
    
    PR:             261398 (exp-run)
    Reviewed by:    glebius
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D38574
---
 sys/netinet/in.h          |  1 -
 sys/netinet/in_pcb.c      | 47 ++---------------------------------------------
 sys/netinet/in_pcb.h      |  4 ----
 sys/netinet/ip_output.c   |  8 --------
 sys/netinet6/in6.h        |  1 -
 sys/netinet6/in6_pcb.c    | 18 ++----------------
 sys/netinet6/ip6_output.c |  9 ---------
 7 files changed, 4 insertions(+), 84 deletions(-)

diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 44d64190ed01..99809b3ebaa4 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -463,7 +463,6 @@ VNET_DECLARE(uint32_t, in_loopback_mask);
 				     /* unused; was IP_FAITH */
 #define	IP_ONESBCAST		23   /* bool: send all-ones broadcast */
 #define	IP_BINDANY		24   /* bool: allow bind to any address */
-#define	IP_BINDMULTI		25   /* bool: allow multiple listeners on a tuple */
 #define	IP_RSS_LISTEN_BUCKET	26   /* int; set RSS listen bucket */
 #define	IP_ORIGDSTADDR		27   /* bool: receive IP dst addr/port w/dgram */
 #define	IP_RECVORIGDSTADDR      IP_ORIGDSTADDR
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index a23c89fe8033..ce95ece8f5f2 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -860,36 +860,6 @@ inp_so_options(const struct inpcb *inp)
 }
 #endif /* INET || INET6 */
 
-/*
- * Check if a new BINDMULTI socket is allowed to be created.
- *
- * ni points to the new inp.
- * oi points to the existing inp.
- *
- * This checks whether the existing inp also has BINDMULTI and
- * whether the credentials match.
- */
-int
-in_pcbbind_check_bindmulti(const struct inpcb *ni, const struct inpcb *oi)
-{
-	/* Check permissions match */
-	if ((ni->inp_flags2 & INP_BINDMULTI) &&
-	    (ni->inp_cred->cr_uid !=
-	    oi->inp_cred->cr_uid))
-		return (0);
-
-	/* Check the existing inp has BINDMULTI set */
-	if ((ni->inp_flags2 & INP_BINDMULTI) &&
-	    ((oi->inp_flags2 & INP_BINDMULTI) == 0))
-		return (0);
-
-	/*
-	 * We're okay - either INP_BINDMULTI isn't set on ni, or
-	 * it is and it matches the checks.
-	 */
-	return (1);
-}
-
 #ifdef INET
 /*
  * Set up a bind operation on a PCB, performing port allocation
@@ -993,8 +963,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
 	 * XXX
 	 * This entire block sorely needs a rewrite.
 	 */
-				if (t &&
-				    ((inp->inp_flags2 & INP_BINDMULTI) == 0) &&
+				if (t != NULL &&
 				    (so->so_type != SOCK_STREAM ||
 				     ntohl(t->inp_faddr.s_addr) == INADDR_ANY) &&
 				    (ntohl(sin->sin_addr.s_addr) != INADDR_ANY ||
@@ -1004,20 +973,10 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
 				    (inp->inp_cred->cr_uid !=
 				     t->inp_cred->cr_uid))
 					return (EADDRINUSE);
-
-				/*
-				 * If the socket is a BINDMULTI socket, then
-				 * the credentials need to match and the
-				 * original socket also has to have been bound
-				 * with BINDMULTI.
-				 */
-				if (t && (! in_pcbbind_check_bindmulti(inp, t)))
-					return (EADDRINUSE);
 			}
 			t = in_pcblookup_local(pcbinfo, sin->sin_addr,
 			    lport, lookupflags, cred);
-			if (t && ((inp->inp_flags2 & INP_BINDMULTI) == 0) &&
-			    (reuseport & inp_so_options(t)) == 0 &&
+			if (t != NULL && (reuseport & inp_so_options(t)) == 0 &&
 			    (reuseport_lb & inp_so_options(t)) == 0) {
 #ifdef INET6
 				if (ntohl(sin->sin_addr.s_addr) !=
@@ -1028,8 +987,6 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in *sin, in_addr_t *laddrp,
 				    (t->inp_vflag & INP_IPV6PROTO) == 0)
 #endif
 						return (EADDRINUSE);
-				if (t && (! in_pcbbind_check_bindmulti(inp, t)))
-					return (EADDRINUSE);
 			}
 		}
 	}
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index f15fd0db4dfb..9ab9ed87528e 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -669,7 +669,6 @@ int	inp_so_options(const struct inpcb *inp);
 #define	INP_REUSEPORT		0x00000008 /* SO_REUSEPORT option is set */
 /*				0x00000010 */
 #define	INP_REUSEADDR		0x00000020 /* SO_REUSEADDR option is set */
-#define	INP_BINDMULTI		0x00000040 /* IP_BINDMULTI option is set */
 #define	INP_RSS_BUCKET_SET	0x00000080 /* IP_RSS_LISTEN_BUCKET is set */
 #define	INP_RECVFLOWID		0x00000100 /* populate recv datagram with flow info */
 #define	INP_RECVRSSBUCKETID	0x00000200 /* populate recv datagram with bucket id */
@@ -734,9 +733,6 @@ void	in_pcbinfo_destroy(struct inpcbinfo *);
 void	in_pcbstorage_init(void *);
 void	in_pcbstorage_destroy(void *);
 
-int	in_pcbbind_check_bindmulti(const struct inpcb *ni,
-	    const struct inpcb *oi);
-
 void	in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
 int	in_pcballoc(struct socket *, struct inpcbinfo *);
 int	in_pcbbind(struct inpcb *, struct sockaddr_in *, struct ucred *);
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index e62935b247da..13ba15050769 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1166,7 +1166,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 					break;
 			}
 			/* FALLTHROUGH */
-		case IP_BINDMULTI:
 #ifdef	RSS
 		case IP_RSS_LISTEN_BUCKET:
 #endif
@@ -1262,9 +1261,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 			case IP_RECVTOS:
 				OPTSET(INP_RECVTOS);
 				break;
-			case IP_BINDMULTI:
-				OPTSET2(INP_BINDMULTI, optval);
-				break;
 			case IP_RECVFLOWID:
 				OPTSET2(INP_RECVFLOWID, optval);
 				break;
@@ -1416,7 +1412,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 		case IP_DONTFRAG:
 		case IP_BINDANY:
 		case IP_RECVTOS:
-		case IP_BINDMULTI:
 		case IP_FLOWID:
 		case IP_FLOWTYPE:
 		case IP_RECVFLOWID:
@@ -1509,9 +1504,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
 				optval = OPTBIT2(INP_RECVRSSBUCKETID);
 				break;
 #endif
-			case IP_BINDMULTI:
-				optval = OPTBIT2(INP_BINDMULTI);
-				break;
 			case IP_VLAN_PCP:
 				if (OPTBIT2(INP_2PCP_SET)) {
 					optval = (inp->inp_flags2 &
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index f9823fa97d03..23a31010d081 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -484,7 +484,6 @@ struct route_in6 {
 
 #define	IPV6_BINDANY		64 /* bool: allow bind to any address */
 
-#define	IPV6_BINDMULTI		65 /* bool; allow multibind to same addr/port */
 #define	IPV6_RSS_LISTEN_BUCKET	66 /* int; set RSS listen bucket */
 #define	IPV6_FLOWID		67 /* int; flowid of given socket */
 #define	IPV6_FLOWTYPE		68 /* int; flowtype of given socket */
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 92a1ea840af2..8b1f97f322ef 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -249,8 +249,7 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
 				t = in6_pcblookup_local(pcbinfo,
 				    &sin6->sin6_addr, lport,
 				    INPLOOKUP_WILDCARD, cred);
-				if (t &&
-				    ((inp->inp_flags2 & INP_BINDMULTI) == 0) &&
+				if (t != NULL &&
 				    (so->so_type != SOCK_STREAM ||
 				     IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
 				    (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
@@ -261,15 +260,6 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
 				     t->inp_cred->cr_uid))
 					return (EADDRINUSE);
 
-				/*
-				 * If the socket is a BINDMULTI socket, then
-				 * the credentials need to match and the
-				 * original socket also has to have been bound
-				 * with BINDMULTI.
-				 */
-				if (t && (! in_pcbbind_check_bindmulti(inp, t)))
-					return (EADDRINUSE);
-
 #ifdef INET
 				if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
 				    IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
@@ -279,17 +269,13 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
 					t = in_pcblookup_local(pcbinfo,
 					    sin.sin_addr, lport,
 					    INPLOOKUP_WILDCARD, cred);
-					if (t &&
-					    ((inp->inp_flags2 & INP_BINDMULTI) == 0) &&
+					if (t != NULL &&
 					    (so->so_type != SOCK_STREAM ||
 					     ntohl(t->inp_faddr.s_addr) ==
 					      INADDR_ANY) &&
 					    (inp->inp_cred->cr_uid !=
 					     t->inp_cred->cr_uid))
 						return (EADDRINUSE);
-
-					if (t && (! in_pcbbind_check_bindmulti(inp, t)))
-						return (EADDRINUSE);
 				}
 #endif
 			}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index bce5ed846227..01c6ba5b41d4 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1752,7 +1752,6 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
 			case IPV6_AUTOFLOWLABEL:
 			case IPV6_ORIGDSTADDR:
 			case IPV6_BINDANY:
-			case IPV6_BINDMULTI:
 #ifdef	RSS
 			case IPV6_RSS_LISTEN_BUCKET:
 #endif
@@ -1933,10 +1932,6 @@ do {									\
 				case IPV6_BINDANY:
 					OPTSET(INP_BINDANY);
 					break;
-
-				case IPV6_BINDMULTI:
-					OPTSET2(INP_BINDMULTI, optval);
-					break;
 #ifdef	RSS
 				case IPV6_RSS_LISTEN_BUCKET:
 					if ((optval >= 0) &&
@@ -2195,7 +2190,6 @@ do {									\
 			case IPV6_RSSBUCKETID:
 			case IPV6_RECVRSSBUCKETID:
 #endif
-			case IPV6_BINDMULTI:
 			case IPV6_VLAN_PCP:
 				switch (optname) {
 				case IPV6_RECVHOPOPTS:
@@ -2290,9 +2284,6 @@ do {									\
 					break;
 #endif
 
-				case IPV6_BINDMULTI:
-					optval = OPTBIT2(INP_BINDMULTI);
-					break;
 
 				case IPV6_VLAN_PCP:
 					if (OPTBIT2(INP_2PCP_SET)) {