92 lines
2.6 KiB
Diff
92 lines
2.6 KiB
Diff
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
|