Blob Blame History Raw
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