mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Add --shared-network DHCP configuration.
This commit is contained in:
177
src/dhcp6.c
177
src/dhcp6.c
@@ -299,89 +299,114 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
||||
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 = ¶m->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(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->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 = ¶m->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(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->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)
|
||||
|
||||
Reference in New Issue
Block a user