From d474b81de672a7f630929bc45172ccc5538debf7 Mon Sep 17 00:00:00 2001 From: Tomas Hozza Date: Nov 19 2012 09:47:40 +0000 Subject: dhcp6 support fixes (#867054) --- diff --git a/dnsmasq-2.63-dhcp6-access-control.patch b/dnsmasq-2.63-dhcp6-access-control.patch new file mode 100644 index 0000000..87e900d --- /dev/null +++ b/dnsmasq-2.63-dhcp6-access-control.patch @@ -0,0 +1,91 @@ +diff --git a/src/dhcp6.c b/src/dhcp6.c +index 718a262..5525ca5 100644 +--- a/src/dhcp6.c ++++ b/src/dhcp6.c +@@ -21,7 +21,7 @@ + struct iface_param { + struct dhcp_context *current; + struct in6_addr fallback; +- int ind; ++ int ind, addr_match; + }; + + static int complete_context6(struct in6_addr *local, int prefix, +@@ -87,7 +87,6 @@ void dhcp6_packet(time_t now) + char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + } control_u; + struct sockaddr_in6 from; +- struct all_addr dest; + ssize_t sz; + struct ifreq ifr; + struct iname *tmp; +@@ -114,15 +113,15 @@ void dhcp6_packet(time_t now) + p.c = CMSG_DATA(cmptr); + + if_index = p.p->ipi6_ifindex; +- dest.addr.addr6 = p.p->ipi6_addr; + } + + if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name)) + return; + +- if (!iface_check(AF_INET6, (struct all_addr *)&dest, ifr.ifr_name)) +- return; +- ++ for (tmp = daemon->if_except; tmp; tmp = tmp->next) ++ if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) ++ return; ++ + for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) + if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) + return; +@@ -136,11 +135,23 @@ void dhcp6_packet(time_t now) + + parm.current = NULL; + parm.ind = if_index; ++ parm.addr_match = 0; + memset(&parm.fallback, 0, IN6ADDRSZ); + + if (!iface_enumerate(AF_INET6, &parm, complete_context6)) + return; + ++ if (daemon->if_names || daemon->if_addrs) ++ { ++ ++ for (tmp = daemon->if_names; tmp; tmp = tmp->next) ++ if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0)) ++ break; ++ ++ if (!tmp && !parm.addr_match) ++ return; ++ } ++ + lease_prune(NULL, now); /* lose any expired leases */ + + port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback, +@@ -167,15 +178,23 @@ static int complete_context6(struct in6_addr *local, int prefix, + { + struct dhcp_context *context; + struct iface_param *param = vparam; +- ++ struct iname *tmp; ++ + (void)scope; /* warning */ + (void)dad; +- ++ + if (if_index == param->ind && + !IN6_IS_ADDR_LOOPBACK(local) && + !IN6_IS_ADDR_LINKLOCAL(local) && + !IN6_IS_ADDR_MULTICAST(local)) + { ++ /* if we have --listen-address config, see if the ++ arrival interface has a matching address. */ ++ for (tmp = daemon->if_addrs; tmp; tmp = tmp->next) ++ if (tmp->addr.sa.sa_family == AF_INET6 && ++ IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local)) ++ param->addr_match = 1; ++ + /* Determine a globally address on the arrival interface, even + if we have no matching dhcp-context, because we're only + allocating on remote subnets via relays. This diff --git a/dnsmasq-2.63-ip6-reuseaddr.patch b/dnsmasq-2.63-ip6-reuseaddr.patch new file mode 100644 index 0000000..af2f043 --- /dev/null +++ b/dnsmasq-2.63-ip6-reuseaddr.patch @@ -0,0 +1,36 @@ +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); diff --git a/dnsmasq.spec b/dnsmasq.spec index c706791..9880eea 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -11,7 +11,7 @@ Name: dnsmasq Version: 2.63 -Release: 2%{?extraversion}%{?dist} +Release: 3%{?extraversion}%{?dist} Summary: A lightweight DHCP/caching DNS server Group: System Environment/Daemons @@ -19,6 +19,10 @@ License: GPLv2 URL: http://www.thekelleys.org.uk/dnsmasq/ Source0: http://www.thekelleys.org.uk/dnsmasq/%{?extrapath}%{name}-%{version}%{?extraversion}.tar.gz Source1: %{name}.service + +Patch0: dnsmasq-2.63-ip6-reuseaddr.patch +Patch1: dnsmasq-2.63-dhcp6-access-control.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: dbus-devel @@ -52,6 +56,9 @@ query/remove a DHCP server's leases. %prep %setup -q -n %{name}-%{version}%{?extraversion} +%patch0 -p1 -b .ip6_reuseaddr +%patch1 -p1 -b .dhcp6_access_ctrl + # use /var/lib/dnsmasq instead of /var/lib/misc for file in dnsmasq.conf.example man/dnsmasq.8 man/es/dnsmasq.8 src/config.h; do sed -i 's|/var/lib/misc/dnsmasq.leases|/var/lib/dnsmasq/dnsmasq.leases|g' "$file" @@ -130,6 +137,9 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/dhcp_* %changelog +* Mon Nov 19 2012 Tomas Hozza - 2.63-3 +- dhcp6 support fixes (#867054) + * Tue Oct 23 2012 Tomas Hozza - 2.63-2 - Introduce new systemd-rpm macros in dnsmasq spec file (#850096)