From cd672933c9b39c4275f2e8c26cef5107ad6f2c7c Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Mon, 27 Jan 2020 22:53:07 +0000 Subject: [PATCH] Fix RA problems with two interfaces on same IPv6 subnet. --- CHANGELOG | 7 ++++++- debian/changelog | 4 +++- src/radv.c | 22 ++++++++++++---------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 42ad123..80ea482 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -64,8 +64,13 @@ version 2.81 Enhance --conf-dir to load files in a deterministic order. Thanks to Evgenii Seliavka for the suggestion and initial patch. - + In the router advert code, handle case where we have two + different interfaces on the same IPv6 net, and we're doing + RA/DHCP service on only one of them. Thanks to NIIBE Yutaka + for spotting this case and making the initial patch. + + version 2.80 Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method for the initial patch and motivation. diff --git a/debian/changelog b/debian/changelog index d9d39a2..b2fc87f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,8 +7,10 @@ dnsmasq (2.81-1) unstable; urgency=low * Add note explaining that ENABLED is SYSV-init only. (closes: #914755) * Replace ash with dash in contrib/reverse-dns. (closes: #920224) * Move to libidn2. (closes: #932695) + * Fix RA problem with two interfaces on same net, but RA service on + only one of the interfaces. (closes: #949565) - -- Simon Kelley Fri, 8 Apr 2019 17:14:15 +0000 + -- Simon Kelley Mon, 27 Jan 2020 22:31:15 +0000 dnsmasq (2.80-1) unstable; urgency=low diff --git a/src/radv.c b/src/radv.c index cad0530..7ec8cd0 100644 --- a/src/radv.c +++ b/src/radv.c @@ -891,11 +891,21 @@ static int iface_search(struct in6_addr *local, int prefix, { struct search_param *param = vparam; struct dhcp_context *context; - + struct iname *tmp; + (void)scope; (void)preferred; (void)valid; - + + /* ignore interfaces we're not doing DHCP on. */ + if (!indextoname(daemon->icmp6fd, if_index, param->name) || + !iface_check(AF_LOCAL, NULL, param->name, NULL)) + return 1; + + for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) + if (tmp->name && wildcard_match(tmp->name, param->name)) + return 1; + for (context = daemon->dhcp6; context; context = context->next) if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && prefix <= context->prefix && @@ -907,17 +917,9 @@ static int iface_search(struct in6_addr *local, int prefix, /* found an interface that's overdue for RA determine new timeout value and arrange for RA to be sent unless interface is still doing DAD.*/ - if (!(flags & IFACE_TENTATIVE)) param->iface = if_index; - /* should never fail */ - if (!indextoname(daemon->icmp6fd, if_index, param->name)) - { - param->iface = 0; - return 0; - } - new_timeout(context, param->name, param->now); /* zero timers for other contexts on the same subnet, so they don't timeout