aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2023-02-27 14:52:28 +0000
committerMark Johnston <markj@FreeBSD.org>2023-02-27 15:03:11 +0000
commit3aff4ccdd714105db340d68f1a2aea2f46e99122 (patch)
treee533e475b94b6a503069463c19ca5f3e92f55157
parentb9199d152f3d61f93c21d63e3c85a5863f9d71e9 (diff)
downloadsrc-3aff4ccdd714105db340d68f1a2aea2f46e99122.tar.gz
src-3aff4ccdd714105db340d68f1a2aea2f46e99122.zip
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
-rw-r--r--sys/netinet/in.h1
-rw-r--r--sys/netinet/in_pcb.c47
-rw-r--r--sys/netinet/in_pcb.h4
-rw-r--r--sys/netinet/ip_output.c8
-rw-r--r--sys/netinet6/in6.h1
-rw-r--r--sys/netinet6/in6_pcb.c18
-rw-r--r--sys/netinet6/ip6_output.c9
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)) {