Add --shared-network DHCP configuration.
diff --git a/src/dhcp6.c b/src/dhcp6.c
index 7e6e3df..5badc46 100644
--- a/src/dhcp6.c
+++ b/src/dhcp6.c
@@ -299,89 +299,114 @@
 			     unsigned int valid, void *vparam)
 {
   struct dhcp_context *context;
+  struct shared_network *share;
   struct dhcp_relay *relay;
   struct iface_param *param = vparam;
   struct iname *tmp;
  
   (void)scope; /* warning */
   
-  if (if_index == param->ind)
-    {
-      if (IN6_IS_ADDR_LINKLOCAL(local))
-	param->ll_addr = *local;
-      else if (IN6_IS_ADDR_ULA(local))
-	param->ula_addr = *local;
-
-      if (!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
-	     is used as a default for the DNS server option. */
-	  param->fallback = *local;
-	  
-	  for (context = daemon->dhcp6; context; context = context->next)
-	    {
-	      if ((context->flags & CONTEXT_DHCP) &&
-		  !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
-		  prefix <= context->prefix &&
-		  is_same_net6(local, &context->start6, context->prefix) &&
-		  is_same_net6(local, &context->end6, context->prefix))
-		{
-		  
-		  
-		  /* link it onto the current chain if we've not seen it before */
-		  if (context->current == context)
-		    {
-		      struct dhcp_context *tmp, **up;
-		      
-		      /* use interface values only for constructed contexts */
-		      if (!(context->flags & CONTEXT_CONSTRUCTED))
-			preferred = valid = 0xffffffff;
-		      else if (flags & IFACE_DEPRECATED)
-			preferred = 0;
-		      
-		      if (context->flags & CONTEXT_DEPRECATE)
-			preferred = 0;
-		      
-		      /* order chain, longest preferred time first */
-		      for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
-			if (tmp->preferred <= preferred)
-			  break;
-			else
-			  up = &tmp->current;
-		      
-		      context->current = *up;
-		      *up = context;
-		      context->local6 = *local;
-		      context->preferred = preferred;
-		      context->valid = valid;
-		    }
-		}
-	    }
-	}
-
-      for (relay = daemon->relay6; relay; relay = relay->next)
-	if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay &&
-	    (IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
-	  {
-	    relay->current = param->relay;
-	    param->relay = relay;
-	    param->relay_local = *local;
-	  }
+  if (if_index != param->ind)
+    return 1;
+  
+  if (IN6_IS_ADDR_LINKLOCAL(local))
+    param->ll_addr = *local;
+  else if (IN6_IS_ADDR_ULA(local))
+    param->ula_addr = *local;
       
-    }          
- 
- return 1;
+  if (IN6_IS_ADDR_LOOPBACK(local) ||
+      IN6_IS_ADDR_LINKLOCAL(local) ||
+      IN6_IS_ADDR_MULTICAST(local))
+    return 1;
+  
+  /* 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
+     is used as a default for the DNS server option. */
+  param->fallback = *local;
+  
+  for (context = daemon->dhcp6; context; context = context->next)
+    if ((context->flags & CONTEXT_DHCP) &&
+	!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
+	prefix <= context->prefix &&
+	context->current == context)
+      {
+	if (is_same_net6(local, &context->start6, context->prefix) &&
+	    is_same_net6(local, &context->end6, context->prefix))
+	  {
+	    struct dhcp_context *tmp, **up;
+	    
+	    /* use interface values only for constructed contexts */
+	    if (!(context->flags & CONTEXT_CONSTRUCTED))
+	      preferred = valid = 0xffffffff;
+	    else if (flags & IFACE_DEPRECATED)
+	      preferred = 0;
+		    
+	    if (context->flags & CONTEXT_DEPRECATE)
+	      preferred = 0;
+	    
+	    /* order chain, longest preferred time first */
+	    for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
+	      if (tmp->preferred <= preferred)
+		break;
+	      else
+		up = &tmp->current;
+	    
+	    context->current = *up;
+	    *up = context;
+	    context->local6 = *local;
+	    context->preferred = preferred;
+	    context->valid = valid;
+	  }
+	else
+	  {
+	    for (share = daemon->shared_networks; share; share = share->next)
+	      {
+		/* IPv4 shared_address - ignore */
+		if (share->shared_addr.s_addr != 0)
+		  continue;
+			
+		if (share->if_index != 0)
+		  {
+		    if (share->if_index != if_index)
+		      continue;
+		  }
+		else
+		  {
+		    if (!IN6_ARE_ADDR_EQUAL(&share->match_addr6, local))
+		      continue;
+		  }
+		
+		if (is_same_net6(&share->shared_addr6, &context->start6, context->prefix) &&
+		    is_same_net6(&share->shared_addr6, &context->end6, context->prefix))
+		  {
+		    context->current = param->current;
+		    param->current = context;
+		    context->local6 = *local;
+		    context->preferred = context->flags & CONTEXT_DEPRECATE ? 0 :0xffffffff;
+		    context->valid = 0xffffffff;
+		  }
+	      }
+	  }      
+      }
+
+  for (relay = daemon->relay6; relay; relay = relay->next)
+    if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay &&
+	(IN6_IS_ADDR_UNSPECIFIED(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->relay_local)))
+      {
+	relay->current = param->relay;
+	param->relay = relay;
+	param->relay_local = *local;
+      }
+     
+  return 1;
 }
 
 struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr)