in_pcbbind and in6_pcbbind both extends SO_REUSEADDR for multicast addresses so that it turns into a SO_REUSEPORT. But the check is done in such a way that you cannot bind a SO_REUSEPORT-enabled socket to a multicast address *after* you bound a SO_REUSEADDR-enabled socket to the same address.
*But:* due to how the struct in_pcb are handled, if you : 1) bind a SO_REUSEADDR-enabled socket to a multicast address, 2) then bind a SO_REUSEADDR|SO_REUSEPORT-enabled socket to the same address, as a result you can now bind a SO_REUSEPORT-enabled socket to this address. The regress test in regress/sys/netinet/in_pcbbind reproduce this behaviour (be sure to get v1.2 for Makefile and runtest.c) This diff allow SO_REUSEPORT-only socket to be bound after SO_REUSEADDR-only. ok ? Index: netinet/in_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.194 diff -u -p -r1.194 in_pcb.c --- netinet/in_pcb.c 3 Dec 2015 21:57:59 -0000 1.194 +++ netinet/in_pcb.c 9 Dec 2015 15:22:16 -0000 @@ -318,7 +318,7 @@ in_pcbbind(struct inpcb *inp, struct mbu * and a multicast address is bound on both * new and duplicated sockets. */ - if (so->so_options & SO_REUSEADDR) + if (so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin->sin_addr.s_addr != INADDR_ANY) { sin->sin_port = 0; /* yech... */ Index: netinet6/in6_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_pcb.c,v retrieving revision 1.83 diff -u -p -r1.83 in6_pcb.c --- netinet6/in6_pcb.c 2 Dec 2015 22:13:44 -0000 1.83 +++ netinet6/in6_pcb.c 9 Dec 2015 15:22:16 -0000 @@ -214,7 +214,7 @@ in6_pcbbind(struct inpcb *inp, struct mb * and a multicast address is bound on both * new and duplicated sockets. */ - if (so->so_options & SO_REUSEADDR) + if (so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) reuseport = SO_REUSEADDR | SO_REUSEPORT; } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { struct ifaddr *ifa = NULL;