The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=01f8ce83242d7a8e599cf6a78b6277161d79edd4

commit 01f8ce83242d7a8e599cf6a78b6277161d79edd4
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2024-12-05 15:00:13 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2024-12-05 15:19:57 +0000

    inpcb: Factor out parts of in6_pcbbind() and in_pcbbind_setup()
    
    A large portion of these functions just determines whether the inpcb can
    bind to the address/port.  This portion has no side effects, so is a
    good candidate to move into its own helper function.  This patch does
    so, making the callers less complicated and reducing indentation.
    
    While moving this code, also make some changes:
    - Load socket options (SO_REUSEADDR etc.) only once.  There is nothing
      preventing another thread from toggling the socket options, so make
      this function easier to reason about by avoiding races.
    - When checking whether the bind address is an interface address, make a
      separate sockaddr rather than temporarily modifying the one passed to
      in_pcbbind().
    
    Reviewed by:    ae, glebius
    MFC after:      1 month
    Sponsored by:   Klara, Inc.
    Sponsored by:   Stormshield
    Differential Revision:  https://reviews.freebsd.org/D47590
---
 sys/netinet/in_pcb.c   | 172 ++++++++++++++++++--------------
 sys/netinet6/in6_pcb.c | 262 +++++++++++++++++++++++++++----------------------
 2 files changed, 242 insertions(+), 192 deletions(-)

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 7c881817ac6e..94fb406bcd2b 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -861,6 +861,93 @@ in_pcb_lport(struct inpcb *inp, struct in_addr *laddrp, 
u_short *lportp,
 #endif /* INET || INET6 */
 
 #ifdef INET
+/*
+ * Determine whether the inpcb can be bound to the specified address/port 
tuple.
+ */
+static int
+in_pcbbind_avail(struct inpcb *inp, const struct in_addr laddr,
+    const u_short lport, int sooptions, int lookupflags, struct ucred *cred)
+{
+       int reuseport, reuseport_lb;
+
+       INP_LOCK_ASSERT(inp);
+       INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);
+
+       reuseport = (sooptions & SO_REUSEPORT);
+       reuseport_lb = (sooptions & SO_REUSEPORT_LB);
+
+       if (IN_MULTICAST(ntohl(laddr.s_addr))) {
+               /*
+                * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
+                * allow complete duplication of binding if
+                * SO_REUSEPORT is set, or if SO_REUSEADDR is set
+                * and a multicast address is bound on both
+                * new and duplicated sockets.
+                */
+               if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT)) != 0)
+                       reuseport = SO_REUSEADDR | SO_REUSEPORT;
+               /*
+                * XXX: How to deal with SO_REUSEPORT_LB here?
+                * Treat same as SO_REUSEPORT for now.
+                */
+               if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT_LB)) != 0)
+                       reuseport_lb = SO_REUSEADDR | SO_REUSEPORT_LB;
+       } else if (!in_nullhost(laddr)) {
+               struct sockaddr_in sin;
+
+               memset(&sin, 0, sizeof(sin));
+               sin.sin_family = AF_INET;
+               sin.sin_len = sizeof(sin);
+               sin.sin_addr = laddr;
+
+               /*
+                * Is the address a local IP address?
+                * If INP_BINDANY is set, then the socket may be bound
+                * to any endpoint address, local or not.
+                */
+               if ((inp->inp_flags & INP_BINDANY) == 0 &&
+                   ifa_ifwithaddr_check((const struct sockaddr *)&sin) == 0)
+                       return (EADDRNOTAVAIL);
+       }
+
+       if (lport != 0) {
+               struct inpcb *t;
+
+               if (ntohs(lport) <= V_ipport_reservedhigh &&
+                   ntohs(lport) >= V_ipport_reservedlow &&
+                   priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
+                       return (EACCES);
+
+               if (!IN_MULTICAST(ntohl(laddr.s_addr)) &&
+                   priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 
0) {
+                       t = in_pcblookup_local(inp->inp_pcbinfo, laddr, lport,
+                           INPLOOKUP_WILDCARD, cred);
+                       if (t != NULL &&
+                           (inp->inp_socket->so_type != SOCK_STREAM ||
+                            in_nullhost(t->inp_faddr)) &&
+                           (!in_nullhost(laddr) ||
+                            !in_nullhost(t->inp_laddr) ||
+                            (t->inp_socket->so_options & SO_REUSEPORT) ||
+                            (t->inp_socket->so_options & SO_REUSEPORT_LB) == 
0) &&
+                           (inp->inp_cred->cr_uid != t->inp_cred->cr_uid))
+                               return (EADDRINUSE);
+               }
+               t = in_pcblookup_local(inp->inp_pcbinfo, laddr, lport,
+                   lookupflags, cred);
+               if (t != NULL && ((reuseport | reuseport_lb) &
+                   t->inp_socket->so_options) == 0) {
+#ifdef INET6
+                       if (!in_nullhost(laddr) ||
+                           !in_nullhost(t->inp_laddr) ||
+                           (inp->inp_vflag & INP_IPV6PROTO) == 0 ||
+                           (t->inp_vflag & INP_IPV6PROTO) == 0)
+#endif
+                               return (EADDRINUSE);
+               }
+       }
+       return (0);
+}
+
 /*
  * Set up a bind operation on a PCB, performing port allocation
  * as required, but do not actually modify the PCB. Callers can
@@ -878,15 +965,9 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in 
*sin, in_addr_t *laddrp,
        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
        struct in_addr laddr;
        u_short lport = 0;
-       int lookupflags = 0, reuseport = (so->so_options & SO_REUSEPORT);
+       int lookupflags, sooptions;
        int error;
 
-       /*
-        * XXX: Maybe we could let SO_REUSEPORT_LB set SO_REUSEPORT bit here
-        * so that we don't have to add to the (already messy) code below.
-        */
-       int reuseport_lb = (so->so_options & SO_REUSEPORT_LB);
-
        /*
         * No state changes, so read locks are sufficient here.
         */
@@ -896,7 +977,10 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in 
*sin, in_addr_t *laddrp,
        laddr.s_addr = *laddrp;
        if (sin != NULL && laddr.s_addr != INADDR_ANY)
                return (EINVAL);
-       if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT|SO_REUSEPORT_LB)) == 0)
+
+       lookupflags = 0;
+       sooptions = atomic_load_int(&so->so_options);
+       if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT | SO_REUSEPORT_LB)) == 0)
                lookupflags = INPLOOKUP_WILDCARD;
        if (sin == NULL) {
                if ((error = prison_local_ip4(cred, &laddr)) != 0)
@@ -918,73 +1002,11 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr_in 
*sin, in_addr_t *laddrp,
                }
                laddr = sin->sin_addr;
 
-               /* NB: lport is left as 0 if the port isn't being changed. */
-               if (IN_MULTICAST(ntohl(laddr.s_addr))) {
-                       /*
-                        * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
-                        * allow complete duplication of binding if
-                        * SO_REUSEPORT is set, or if SO_REUSEADDR is set
-                        * and a multicast address is bound on both
-                        * new and duplicated sockets.
-                        */
-                       if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0)
-                               reuseport = SO_REUSEADDR|SO_REUSEPORT;
-                       /*
-                        * XXX: How to deal with SO_REUSEPORT_LB here?
-                        * Treat same as SO_REUSEPORT for now.
-                        */
-                       if ((so->so_options &
-                           (SO_REUSEADDR|SO_REUSEPORT_LB)) != 0)
-                               reuseport_lb = SO_REUSEADDR|SO_REUSEPORT_LB;
-               } else if (!in_nullhost(laddr)) {
-                       sin->sin_port = 0;              /* yech... */
-                       bzero(&sin->sin_zero, sizeof(sin->sin_zero));
-                       /*
-                        * Is the address a local IP address?
-                        * If INP_BINDANY is set, then the socket may be bound
-                        * to any endpoint address, local or not.
-                        */
-                       if ((inp->inp_flags & INP_BINDANY) == 0 &&
-                           ifa_ifwithaddr_check(
-                           (const struct sockaddr *)sin) == 0)
-                               return (EADDRNOTAVAIL);
-               }
-               if (lport) {
-                       struct inpcb *t;
-
-                       if (ntohs(lport) <= V_ipport_reservedhigh &&
-                           ntohs(lport) >= V_ipport_reservedlow &&
-                           priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
-                               return (EACCES);
-
-                       if (!IN_MULTICAST(ntohl(laddr.s_addr)) &&
-                           priv_check_cred(inp->inp_cred, 
PRIV_NETINET_REUSEPORT) != 0) {
-                               t = in_pcblookup_local(pcbinfo, laddr, lport,
-                                   INPLOOKUP_WILDCARD, cred);
-                               if (t != NULL &&
-                                   (so->so_type != SOCK_STREAM ||
-                                    in_nullhost(t->inp_faddr)) &&
-                                   (!in_nullhost(laddr) ||
-                                    !in_nullhost(t->inp_laddr) ||
-                                    (t->inp_socket->so_options & SO_REUSEPORT) 
||
-                                    (t->inp_socket->so_options & 
SO_REUSEPORT_LB) == 0) &&
-                                   (inp->inp_cred->cr_uid !=
-                                    t->inp_cred->cr_uid))
-                                       return (EADDRINUSE);
-                       }
-                       t = in_pcblookup_local(pcbinfo, laddr, lport,
-                           lookupflags, cred);
-                       if (t != NULL && ((reuseport | reuseport_lb) &
-                           t->inp_socket->so_options) == 0) {
-#ifdef INET6
-                               if (!in_nullhost(laddr) ||
-                                   !in_nullhost(t->inp_laddr) ||
-                                   (inp->inp_vflag & INP_IPV6PROTO) == 0 ||
-                                   (t->inp_vflag & INP_IPV6PROTO) == 0)
-#endif
-                                       return (EADDRINUSE);
-                       }
-               }
+               /* See if this address/port combo is available. */
+               error = in_pcbbind_avail(inp, laddr, lport, sooptions,
+                   lookupflags, cred);
+               if (error != 0)
+                       return (error);
        }
        if (*lportp != 0)
                lport = *lportp;
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 639ec68e19e2..6b5a9d3706be 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -160,27 +160,157 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb 
*inp, struct ucred *cred)
        return (0);
 }
 
+/*
+ * Determine whether the inpcb can be bound to the specified address/port 
tuple.
+ */
+static int
+in6_pcbbind_avail(struct inpcb *inp, const struct sockaddr_in6 *sin6,
+    int sooptions, int lookupflags, struct ucred *cred)
+{
+       const struct in6_addr *laddr;
+       int reuseport, reuseport_lb;
+       u_short lport;
+
+       INP_LOCK_ASSERT(inp);
+       INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);
+
+       laddr = &sin6->sin6_addr;
+       lport = sin6->sin6_port;
+
+       reuseport = (sooptions & SO_REUSEPORT);
+       reuseport_lb = (sooptions & SO_REUSEPORT_LB);
+
+       if (IN6_IS_ADDR_MULTICAST(laddr)) {
+               /*
+                * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
+                * allow compepte duplication of binding if
+                * SO_REUSEPORT is set, or if SO_REUSEADDR is set
+                * and a multicast address is bound on both
+                * new and duplicated sockets.
+                */
+               if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT)) != 0)
+                       reuseport = SO_REUSEADDR | SO_REUSEPORT;
+               /*
+                * XXX: How to deal with SO_REUSEPORT_LB here?
+                * Treat same as SO_REUSEPORT for now.
+                */
+               if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT_LB)) != 0)
+                       reuseport_lb = SO_REUSEADDR | SO_REUSEPORT_LB;
+       } else if (!IN6_IS_ADDR_UNSPECIFIED(laddr)) {
+               struct sockaddr_in6 sin6;
+               struct epoch_tracker et;
+               struct ifaddr *ifa;
+
+               memset(&sin6, 0, sizeof(sin6));
+               sin6.sin6_family = AF_INET6;
+               sin6.sin6_len = sizeof(sin6);
+               sin6.sin6_addr = *laddr;
+
+               NET_EPOCH_ENTER(et);
+               if ((ifa = ifa_ifwithaddr((const struct sockaddr *)&sin6)) ==
+                   NULL && (inp->inp_flags & INP_BINDANY) == 0) {
+                       NET_EPOCH_EXIT(et);
+                       return (EADDRNOTAVAIL);
+               }
+
+               /*
+                * XXX: bind to an anycast address might accidentally
+                * cause sending a packet with anycast source address.
+                * We should allow to bind to a deprecated address, since
+                * the application dares to use it.
+                */
+               if (ifa != NULL &&
+                   ((struct in6_ifaddr *)ifa)->ia6_flags &
+                   (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY | IN6_IFF_DETACHED)) {
+                       NET_EPOCH_EXIT(et);
+                       return (EADDRNOTAVAIL);
+               }
+               NET_EPOCH_EXIT(et);
+       }
+
+       if (lport != 0) {
+               struct inpcb *t;
+
+               if (ntohs(lport) <= V_ipport_reservedhigh &&
+                   ntohs(lport) >= V_ipport_reservedlow &&
+                   priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
+                       return (EACCES);
+
+               if (!IN6_IS_ADDR_MULTICAST(laddr) &&
+                   priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) !=
+                   0) {
+                       t = in6_pcblookup_local(inp->inp_pcbinfo, laddr, lport,
+                           INPLOOKUP_WILDCARD, cred);
+                       if (t != NULL &&
+                           (inp->inp_socket->so_type != SOCK_STREAM ||
+                            IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
+                           (!IN6_IS_ADDR_UNSPECIFIED(laddr) ||
+                            !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
+                            (t->inp_socket->so_options & SO_REUSEPORT) ||
+                            (t->inp_socket->so_options & SO_REUSEPORT_LB) == 
0) &&
+                           (inp->inp_cred->cr_uid != t->inp_cred->cr_uid))
+                               return (EADDRINUSE);
+
+#ifdef INET
+                       if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
+                           IN6_IS_ADDR_UNSPECIFIED(laddr)) {
+                               struct sockaddr_in sin;
+
+                               in6_sin6_2_sin(&sin, sin6);
+                               t = in_pcblookup_local(inp->inp_pcbinfo,
+                                   sin.sin_addr, lport, INPLOOKUP_WILDCARD,
+                                   cred);
+                               if (t != NULL &&
+                                   (inp->inp_socket->so_type != SOCK_STREAM ||
+                                    in_nullhost(t->inp_faddr)) &&
+                                   (inp->inp_cred->cr_uid !=
+                                    t->inp_cred->cr_uid))
+                                       return (EADDRINUSE);
+                       }
+#endif
+               }
+               t = in6_pcblookup_local(inp->inp_pcbinfo, laddr, lport,
+                   lookupflags, cred);
+               if (t != NULL && ((reuseport | reuseport_lb) &
+                   t->inp_socket->so_options) == 0)
+                       return (EADDRINUSE);
+#ifdef INET
+               if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
+                   IN6_IS_ADDR_UNSPECIFIED(laddr)) {
+                       struct sockaddr_in sin;
+
+                       in6_sin6_2_sin(&sin, sin6);
+                       t = in_pcblookup_local(inp->inp_pcbinfo, sin.sin_addr,
+                          lport, lookupflags, cred);
+                       if (t != NULL && ((reuseport | reuseport_lb) &
+                           t->inp_socket->so_options) == 0 &&
+                           (!in_nullhost(t->inp_laddr) ||
+                            (t->inp_vflag & INP_IPV6PROTO) != 0)) {
+                               return (EADDRINUSE);
+                       }
+               }
+#endif
+       }
+       return (0);
+}
+
 int
 in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 *sin6, struct ucred *cred)
 {
        struct socket *so = inp->inp_socket;
        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
        u_short lport = 0;
-       int error, lookupflags = 0;
-       int reuseport = (so->so_options & SO_REUSEPORT);
-
-       /*
-        * XXX: Maybe we could let SO_REUSEPORT_LB set SO_REUSEPORT bit here
-        * so that we don't have to add to the (already messy) code below.
-        */
-       int reuseport_lb = (so->so_options & SO_REUSEPORT_LB);
+       int error, lookupflags, sooptions;
 
        INP_WLOCK_ASSERT(inp);
        INP_HASH_WLOCK_ASSERT(pcbinfo);
 
        if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
                return (EINVAL);
-       if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT|SO_REUSEPORT_LB)) == 0)
+
+       lookupflags = 0;
+       sooptions = atomic_load_int(&so->so_options);
+       if ((sooptions & (SO_REUSEADDR | SO_REUSEPORT | SO_REUSEPORT_LB)) == 0)
                lookupflags = INPLOOKUP_WILDCARD;
        if (sin6 == NULL) {
                if ((error = prison_local_ip6(cred, &inp->in6p_laddr,
@@ -199,115 +329,13 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr_in6 
*sin6, struct ucred *cred)
                    ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0))) != 0)
                        return (error);
 
-               lport = sin6->sin6_port;
-               if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
-                       /*
-                        * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
-                        * allow compepte duplication of binding if
-                        * SO_REUSEPORT is set, or if SO_REUSEADDR is set
-                        * and a multicast address is bound on both
-                        * new and duplicated sockets.
-                        */
-                       if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) != 0)
-                               reuseport = SO_REUSEADDR|SO_REUSEPORT;
-                       /*
-                        * XXX: How to deal with SO_REUSEPORT_LB here?
-                        * Treat same as SO_REUSEPORT for now.
-                        */
-                       if ((so->so_options &
-                           (SO_REUSEADDR|SO_REUSEPORT_LB)) != 0)
-                               reuseport_lb = SO_REUSEADDR|SO_REUSEPORT_LB;
-               } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
-                       struct epoch_tracker et;
-                       struct ifaddr *ifa;
-
-                       sin6->sin6_port = 0;            /* yech... */
-                       NET_EPOCH_ENTER(et);
-                       if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6)) ==
-                           NULL &&
-                           (inp->inp_flags & INP_BINDANY) == 0) {
-                               NET_EPOCH_EXIT(et);
-                               return (EADDRNOTAVAIL);
-                       }
-
-                       /*
-                        * XXX: bind to an anycast address might accidentally
-                        * cause sending a packet with anycast source address.
-                        * We should allow to bind to a deprecated address, 
since
-                        * the application dares to use it.
-                        */
-                       if (ifa != NULL &&
-                           ((struct in6_ifaddr *)ifa)->ia6_flags &
-                           
(IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) {
-                               NET_EPOCH_EXIT(et);
-                               return (EADDRNOTAVAIL);
-                       }
-                       NET_EPOCH_EXIT(et);
-               }
-               if (lport) {
-                       struct inpcb *t;
-
-                       if (ntohs(lport) <= V_ipport_reservedhigh &&
-                           ntohs(lport) >= V_ipport_reservedlow &&
-                           priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT))
-                               return (EACCES);
-
-                       if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) &&
-                           priv_check_cred(inp->inp_cred, 
PRIV_NETINET_REUSEPORT) != 0) {
-                               t = in6_pcblookup_local(pcbinfo,
-                                   &sin6->sin6_addr, lport,
-                                   INPLOOKUP_WILDCARD, cred);
-                               if (t != NULL &&
-                                   (so->so_type != SOCK_STREAM ||
-                                    IN6_IS_ADDR_UNSPECIFIED(&t->in6p_faddr)) &&
-                                   (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) 
||
-                                    !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
-                                    (t->inp_socket->so_options & SO_REUSEPORT) 
||
-                                    (t->inp_socket->so_options & 
SO_REUSEPORT_LB) == 0) &&
-                                   (inp->inp_cred->cr_uid !=
-                                    t->inp_cred->cr_uid))
-                                       return (EADDRINUSE);
-
-#ifdef INET
-                               if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
-                                   IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
-                                       struct sockaddr_in sin;
-
-                                       in6_sin6_2_sin(&sin, sin6);
-                                       t = in_pcblookup_local(pcbinfo,
-                                           sin.sin_addr, lport,
-                                           INPLOOKUP_WILDCARD, cred);
-                                       if (t != NULL &&
-                                           (so->so_type != SOCK_STREAM ||
-                                            in_nullhost(t->inp_faddr)) &&
-                                           (inp->inp_cred->cr_uid !=
-                                            t->inp_cred->cr_uid))
-                                               return (EADDRINUSE);
-                               }
-#endif
-                       }
-                       t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
-                           lport, lookupflags, cred);
-                       if (t != NULL && ((reuseport | reuseport_lb) &
-                           t->inp_socket->so_options) == 0)
-                               return (EADDRINUSE);
-#ifdef INET
-                       if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
-                           IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
-                               struct sockaddr_in sin;
+               /* See if this address/port combo is available. */
+               error = in6_pcbbind_avail(inp, sin6, sooptions, lookupflags,
+                   cred);
+               if (error != 0)
+                       return (error);
 
-                               in6_sin6_2_sin(&sin, sin6);
-                               t = in_pcblookup_local(pcbinfo, sin.sin_addr,
-                                  lport, lookupflags, cred);
-                               if (t != NULL && ((reuseport | reuseport_lb) &
-                                   t->inp_socket->so_options) == 0 &&
-                                   (!in_nullhost(t->inp_laddr) ||
-                                    (t->inp_vflag & INP_IPV6PROTO) != 0)) {
-                                       return (EADDRINUSE);
-                               }
-                       }
-#endif
-               }
+               lport = sin6->sin6_port;
                inp->in6p_laddr = sin6->sin6_addr;
        }
        if (lport == 0) {

Reply via email to