mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Fix DHCPv6 address allocation for some pathalogical cases.
This commit is contained in:
@@ -992,6 +992,7 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr);
|
|||||||
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
|
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
|
||||||
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
||||||
int lease_type, int iaid, struct in6_addr *addr);
|
int lease_type, int iaid, struct in6_addr *addr);
|
||||||
|
void lease6_filter(int lease_type, int iaid, struct dhcp_context *context);
|
||||||
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
|
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
|
||||||
u64 lease_find_max_addr6(struct dhcp_context *context);
|
u64 lease_find_max_addr6(struct dhcp_context *context);
|
||||||
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
||||||
|
|||||||
27
src/lease.c
27
src/lease.c
@@ -562,18 +562,31 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
|||||||
memcmp(clid, lease->clid, clid_len) != 0))
|
memcmp(clid, lease->clid, clid_len) != 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clid || addr)
|
lease->flags |= LEASE_USED;
|
||||||
{
|
return lease;
|
||||||
lease->flags |= LEASE_USED;
|
|
||||||
return lease;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lease->flags &= ~LEASE_USED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lease6_filter(int lease_type, int iaid, struct dhcp_context *context)
|
||||||
|
{
|
||||||
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
|
for (lease = leases; lease; lease = lease->next)
|
||||||
|
{
|
||||||
|
/* reset "USED flag */
|
||||||
|
lease->flags &= ~LEASE_USED;
|
||||||
|
|
||||||
|
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* leases on the wrong interface get filtered out here */
|
||||||
|
if (!address6_available(context, (struct in6_addr *)&lease->hwaddr, NULL))
|
||||||
|
lease->flags |= LEASE_USED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
|
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
|
||||||
{
|
{
|
||||||
struct dhcp_lease *lease;
|
struct dhcp_lease *lease;
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
ia_option = opt6_find(opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4), ia_end, OPTION6_IAADDR, 24);
|
ia_option = opt6_find(opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4), ia_end, OPTION6_IAADDR, 24);
|
||||||
|
|
||||||
/* reset "USED" flags on leases */
|
/* reset "USED" flags on leases */
|
||||||
lease6_find(NULL, 0, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, NULL);
|
lease6_filter(ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, context);
|
||||||
|
|
||||||
o = new_opt6(ia_type);
|
o = new_opt6(ia_type);
|
||||||
put_opt6_long(iaid);
|
put_opt6_long(iaid);
|
||||||
@@ -570,7 +570,12 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"),
|
my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"),
|
||||||
daemon->addrbuff);
|
daemon->addrbuff);
|
||||||
else
|
else
|
||||||
addrp = &config->addr6;
|
{
|
||||||
|
addrp = &config->addr6;
|
||||||
|
/* may have existing lease for this address */
|
||||||
|
lease = lease6_find(clid, clid_len,
|
||||||
|
ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, addrp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* existing lease */
|
/* existing lease */
|
||||||
@@ -832,7 +837,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
iacntr = save_counter(-1);
|
iacntr = save_counter(-1);
|
||||||
|
|
||||||
/* reset "USED" flags on leases */
|
/* reset "USED" flags on leases */
|
||||||
lease6_find(NULL, 0, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, NULL);
|
lease6_filter(ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, context);
|
||||||
|
|
||||||
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
||||||
ia_end = opt6_ptr(opt, opt6_len(opt));
|
ia_end = opt6_ptr(opt, opt6_len(opt));
|
||||||
@@ -1036,7 +1041,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
||||||
|
|
||||||
/* reset "USED" flags on leases */
|
/* reset "USED" flags on leases */
|
||||||
lease6_find(NULL, 0, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, NULL);
|
lease6_filter(ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, context);
|
||||||
|
|
||||||
for (ia_option = opt6_find(ia_option, ia_end, OPTION6_IAADDR, 24);
|
for (ia_option = opt6_find(ia_option, ia_end, OPTION6_IAADDR, 24);
|
||||||
ia_option;
|
ia_option;
|
||||||
@@ -1115,7 +1120,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
ia_option = opt6_ptr(opt, ia_type == OPTION6_IA_NA ? 12 : 4);
|
||||||
|
|
||||||
/* reset "USED" flags on leases */
|
/* reset "USED" flags on leases */
|
||||||
lease6_find(NULL, 0, ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, NULL);
|
lease6_filter(ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, iaid, context);
|
||||||
|
|
||||||
for (ia_option = opt6_find(ia_option, ia_end, OPTION6_IAADDR, 24);
|
for (ia_option = opt6_find(ia_option, ia_end, OPTION6_IAADDR, 24);
|
||||||
ia_option;
|
ia_option;
|
||||||
|
|||||||
Reference in New Issue
Block a user