Index: sys/netinet/in_pcb.c =================================================================== --- sys/netinet/in_pcb.c (revision 225885) +++ sys/netinet/in_pcb.c (working copy) @@ -575,8 +575,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockadd ntohl(t->inp_faddr.s_addr) == INADDR_ANY) && (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || ntohl(t->inp_laddr.s_addr) != INADDR_ANY || - (t->inp_socket->so_options & - SO_REUSEPORT) == 0) && + (t->inp_flags2 & INP_REUSEPORT) == 0) && (inp->inp_cred->cr_uid != t->inp_cred->cr_uid)) return (EADDRINUSE); @@ -595,14 +594,15 @@ in_pcbbind_setup(struct inpcb *inp, struct sockadd (reuseport & tw->tw_so_options) == 0) return (EADDRINUSE); } else if (t && - (reuseport & t->inp_socket->so_options) == 0) { + (reuseport == 0 || + (t->inp_flags2 & INP_REUSEPORT) == 0)) { #ifdef INET6 if (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || ntohl(t->inp_laddr.s_addr) != INADDR_ANY || - INP_SOCKAF(so) == - INP_SOCKAF(t->inp_socket)) + (inp->inp_vflag & INP_IPV6PROTO) == 0 || + (t->inp_vflag & INP_IPV6PROTO) == 0) #endif return (EADDRINUSE); } @@ -1867,6 +1867,11 @@ in_pcbinshash_internal(struct inpcb *inp, int do_p KASSERT((inp->inp_flags & INP_INHASHLIST) == 0, ("in_pcbinshash: INP_INHASHLIST")); + if ((inp->inp_socket->so_options & SO_REUSEPORT) != 0 || + (IN_MULTICAST(ntohl(inp->inp_laddr.s_addr)) && + (inp->inp_socket->so_options & SO_REUSEADDR) != 0)) + inp->inp_flags2 |= INP_REUSEPORT; + #ifdef INET6 if (inp->inp_vflag & INP_IPV6) hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */; Index: sys/netinet/in_pcb.h =================================================================== --- sys/netinet/in_pcb.h (revision 225885) +++ sys/netinet/in_pcb.h (working copy) @@ -540,6 +540,7 @@ void inp_4tuple_get(struct inpcb *inp, uint32_t * #define INP_LLE_VALID 0x00000001 /* cached lle is valid */ #define INP_RT_VALID 0x00000002 /* cached rtentry is valid */ #define INP_PCBGROUPWILD 0x00000004 /* in pcbgroup wildcard list */ +#define INP_REUSEPORT 0x00000008 /* socket SO_REUSEPORT option is set */ /* * Flags passed to in_pcblookup*() functions.