mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
DHCPv6 address allocation - same DUID, two IAIDs
This commit is contained in:
38
src/dhcp6.c
38
src/dhcp6.c
@@ -328,6 +328,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* can dynamically allocate addr */
|
||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids)
|
||||
@@ -352,6 +353,22 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* address OK if configured */
|
||||
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids)
|
||||
{
|
||||
struct dhcp_context *tmp;
|
||||
|
||||
for (tmp = context; tmp; tmp = tmp->current)
|
||||
if ((tmp->flags & CONTEXT_STATIC) &&
|
||||
is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
|
||||
match_netid(tmp->filter, netids, 1))
|
||||
return tmp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dhcp_context *narrow_context6(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids)
|
||||
@@ -366,21 +383,12 @@ struct dhcp_context *narrow_context6(struct dhcp_context *context,
|
||||
|
||||
struct dhcp_context *tmp;
|
||||
|
||||
if (!(tmp = address6_available(context, taddr, netids)))
|
||||
{
|
||||
for (tmp = context; tmp; tmp = tmp->current)
|
||||
if (match_netid(tmp->filter, netids, 1) &&
|
||||
is_same_net6(taddr, &tmp->start6, tmp->prefix) &&
|
||||
(tmp->flags & CONTEXT_STATIC))
|
||||
break;
|
||||
|
||||
if (!tmp)
|
||||
for (tmp = context; tmp; tmp = tmp->current)
|
||||
if (match_netid(tmp->filter, netids, 1) &&
|
||||
is_same_net6(taddr, &tmp->start6, tmp->prefix) &&
|
||||
!(tmp->flags & CONTEXT_PROXY))
|
||||
break;
|
||||
}
|
||||
if (!(tmp = address6_available(context, taddr, netids)) &&
|
||||
!(tmp = address6_valid(context, taddr, netids)))
|
||||
for (tmp = context; tmp; tmp = tmp->current)
|
||||
if (match_netid(tmp->filter, netids, 1) &&
|
||||
is_same_net6(taddr, &tmp->start6, tmp->prefix))
|
||||
break;
|
||||
|
||||
/* Only one context allowed now */
|
||||
if (tmp)
|
||||
|
||||
@@ -1149,6 +1149,9 @@ int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr);
|
||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids);
|
||||
struct dhcp_context *narrow_context6(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids);
|
||||
|
||||
@@ -525,32 +525,38 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
|
||||
requested_time = opt6_uint(ia_option, 16, 4);
|
||||
struct dhcp_context *dynamic;
|
||||
|
||||
if (!address6_available(context, req_addr, tags) &&
|
||||
(!have_config(config, CONFIG_ADDR6) || memcmp(&config->addr6, req_addr, IN6ADDRSZ) != 0))
|
||||
if ((dynamic = address6_available(context, req_addr, tags)) || address6_valid(context, req_addr, tags))
|
||||
{
|
||||
if (msg_type == DHCP6REQUEST)
|
||||
if (!dynamic && !(have_config(config, CONFIG_ADDR6) && memcmp(&config->addr6, req_addr, IN6ADDRSZ) == 0))
|
||||
{
|
||||
/* host has a lease, but it's not on the correct link */
|
||||
/* Static range, not configured. */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOTONLINK);
|
||||
put_opt6_string("Not on link");
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_string("Address unavailable");
|
||||
end_opt6(o1);
|
||||
}
|
||||
else if (lease6_find_by_addr(req_addr, 128, 0) &&
|
||||
!(lease = lease6_find(clid, clid_len, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, req_addr)))
|
||||
{
|
||||
/* Address leased to another DUID/IAID */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_string("Address in use");
|
||||
end_opt6(o1);
|
||||
}
|
||||
else
|
||||
addrp = req_addr;
|
||||
}
|
||||
else if ((lease = lease6_find(NULL, 0, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
|
||||
iaid, req_addr)) &&
|
||||
(clid_len != lease->clid_len ||
|
||||
memcmp(clid, lease->clid, clid_len) != 0))
|
||||
else if (msg_type == DHCP6REQUEST)
|
||||
{
|
||||
/* Address leased to another DUID */
|
||||
/* requested address not on the correct link */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_string("Address in use");
|
||||
put_opt6_short(DHCP6NOTONLINK);
|
||||
put_opt6_string("Not on link");
|
||||
end_opt6(o1);
|
||||
}
|
||||
else
|
||||
addrp = req_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user