diff -urp dnsmasq-2.63-orig/src/dhcp6.c dnsmasq-2.63/src/dhcp6.c --- dnsmasq-2.63-orig/src/dhcp6.c 2012-08-16 09:04:05.000000000 -0400 +++ dnsmasq-2.63/src/dhcp6.c 2012-11-03 07:55:39.293006824 -0400 @@ -36,15 +36,31 @@ void dhcp6_init(void) #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6) int class = IPTOS_CLASS_CS6; #endif - + int oneopt = 1; + if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 || #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6) setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 || #endif + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &oneopt, sizeof(oneopt)) == -1 || !fix_fd(fd) || !set_ipv6pktinfo(fd)) die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET); + /* When bind-interfaces is set, there might be more than one dnmsasq + instance binding port 547. That's OK if they serve different networks. + Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */ + if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) + { +#ifdef SO_REUSEPORT + int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt)); +#else + int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt)); +#endif + if (rc == -1) + die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET); + } + memset(&saddr, 0, sizeof(saddr)); #ifdef HAVE_SOCKADDR_SA_LEN saddr.sin6_len = sizeof(struct sockaddr_in6);