mirror of
https://github.com/coolsnowwolf/lede
synced 2025-01-08 11:47:42 +08:00
dnsmasq: add patch for DHCPv6 to honor IPv6 address on MAC address
This commit is contained in:
parent
e101ec4903
commit
168828486e
@ -20,7 +20,7 @@ config dnsmasq
|
||||
#list notinterface lo
|
||||
#list bogusnxdomain '64.94.110.11'
|
||||
option localservice 1 # disable to allow DNS requests from non-local subnets
|
||||
option filter_aaaa 0
|
||||
option filter_aaaa 1
|
||||
option cachesize 8000
|
||||
option mini_ttl 3600
|
||||
option ednspacket_max 1232
|
||||
|
@ -0,0 +1,166 @@
|
||||
From 93ac8f9d469ff08d41170eb6934842b3626d5fdd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
|
||||
Date: Wed, 23 Dec 2015 22:10:44 +0100
|
||||
Subject: [PATCH] DHCPv6: Honor assigning IPv6 address based on MAC address
|
||||
|
||||
Currently IPv6 addresses are assigned to tuple (IAID, DUID). When system
|
||||
changes IAID/DUID then old assigned IPv6 address cannot be reused, even
|
||||
when in config file was DHCPv6 assignment based on MAC address (and not on
|
||||
DUID).
|
||||
|
||||
IAID/DUID is changed when rebooting from one operating system to another;
|
||||
or after reinstalling system. In reality it is normal that DUID of some
|
||||
machine is changed, so people rather assign also IPv6 addresses based on
|
||||
MAC address.
|
||||
|
||||
So assigning IPv6 based on MAC address in dnsmasq is currently semi-broken.
|
||||
|
||||
This patch tries to fix it and honors IPv6 config rules with MAC address,
|
||||
to always assign particular IPv6 address to specific MAC address (when
|
||||
configured). And ignores the fact if IAID/DUID was changed.
|
||||
|
||||
Normally IPv6 address should be assigned by IAID/DUID (which also state
|
||||
DHCPv6 RFCs), but dnsmasq has already some support for assigning IPv6
|
||||
address based on MAC address, when users configured in config file.
|
||||
|
||||
So this patch just tries to fix above problem for user configuration with
|
||||
MAC addresses. It does not change assignment based on DUID.
|
||||
---
|
||||
src/rfc3315.c | 55 +++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 47 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/src/rfc3315.c
|
||||
+++ b/src/rfc3315.c
|
||||
@@ -48,7 +48,7 @@ static int build_ia(struct state *state,
|
||||
static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
|
||||
static void mark_context_used(struct state *state, struct in6_addr *addr);
|
||||
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
|
||||
-static int check_address(struct state *state, struct in6_addr *addr);
|
||||
+static int check_address(struct state *state, struct dhcp_config *config, struct in6_addr *addr);
|
||||
static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now);
|
||||
static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
||||
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option,
|
||||
@@ -688,8 +688,13 @@ static int dhcp6_no_relay(struct state *
|
||||
}
|
||||
else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
|
||||
continue; /* not an address we're allowed */
|
||||
- else if (!check_address(state, &req_addr))
|
||||
+ else if (!check_address(state, config, &req_addr))
|
||||
continue; /* address leased elsewhere */
|
||||
+ else if (state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type) &&
|
||||
+ match_netid(c->filter, solicit_tags, plain_range) &&
|
||||
+ !config_implies(config, c, &req_addr))
|
||||
+ continue; /* another static address is configured */
|
||||
|
||||
/* add address to output packet */
|
||||
add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now);
|
||||
@@ -701,7 +706,10 @@ static int dhcp6_no_relay(struct state *
|
||||
|
||||
/* Suggest configured address(es) */
|
||||
for (c = state->context; c; c = c->current)
|
||||
- if (!(c->flags & CONTEXT_CONF_USED) &&
|
||||
+ if ((!(c->flags & CONTEXT_CONF_USED) ||
|
||||
+ (state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type)
|
||||
+ )) &&
|
||||
match_netid(c->filter, solicit_tags, plain_range) &&
|
||||
config_valid(config, c, &addr, state, now))
|
||||
{
|
||||
@@ -725,6 +733,11 @@ static int dhcp6_no_relay(struct state *
|
||||
req_addr = ltmp->addr6;
|
||||
if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
|
||||
{
|
||||
+ if (state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type) &&
|
||||
+ match_netid(c->filter, solicit_tags, plain_range) &&
|
||||
+ !config_implies(config, c, &req_addr))
|
||||
+ continue; /* skip this lease because another static address is configured */
|
||||
add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now);
|
||||
mark_context_used(state, &req_addr);
|
||||
get_context_tag(state, c);
|
||||
@@ -859,7 +872,7 @@ static int dhcp6_no_relay(struct state *
|
||||
put_opt6_string(_("address unavailable"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
- else if (!check_address(state, &req_addr))
|
||||
+ else if (!check_address(state, config, &req_addr))
|
||||
{
|
||||
/* Address leased to another DUID/IAID */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
@@ -989,6 +1002,16 @@ static int dhcp6_no_relay(struct state *
|
||||
{
|
||||
unsigned int lease_time;
|
||||
|
||||
+ /* check if another static address is preferred */
|
||||
+ if (state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type) &&
|
||||
+ !config_implies(config, this_context, &req_addr))
|
||||
+ {
|
||||
+ preferred_time = valid_time = 0;
|
||||
+ message = _("deprecated");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
get_context_tag(state, this_context);
|
||||
|
||||
if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME))
|
||||
@@ -1014,6 +1037,7 @@ static int dhcp6_no_relay(struct state *
|
||||
|
||||
if (preferred_time == 0)
|
||||
message = _("deprecated");
|
||||
+ }
|
||||
|
||||
address_assigned = 1;
|
||||
}
|
||||
@@ -1070,11 +1094,22 @@ static int dhcp6_no_relay(struct state *
|
||||
ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
|
||||
{
|
||||
struct in6_addr req_addr;
|
||||
+ struct dhcp_context *c;
|
||||
+ int config_addr_ok = 1;
|
||||
|
||||
/* alignment */
|
||||
memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
|
||||
+
|
||||
+ c = address6_valid(state->context, &req_addr, tagif, 1);
|
||||
+
|
||||
+ if (c && state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type) &&
|
||||
+ !config_implies(config, c, &req_addr))
|
||||
+ {
|
||||
+ config_addr_ok = 0;
|
||||
+ }
|
||||
|
||||
- if (!address6_valid(state->context, &req_addr, tagif, 1))
|
||||
+ if (!c || !config_addr_ok)
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOTONLINK);
|
||||
@@ -1692,11 +1727,15 @@ static void mark_config_used(struct dhcp
|
||||
context->flags |= CONTEXT_CONF_USED;
|
||||
}
|
||||
|
||||
-/* make sure address not leased to another CLID/IAID */
|
||||
-static int check_address(struct state *state, struct in6_addr *addr)
|
||||
+/* check that ipv6 address belongs to config with same mac address as in state or ipv6 address is not leased to another CLID/IAID */
|
||||
+static int check_address(struct state *state, struct dhcp_config *config, struct in6_addr *addr)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
+ if (state->mac_len && config &&
|
||||
+ config_has_mac(config, state->mac, state->mac_len, state->mac_type))
|
||||
+ return 1;
|
||||
+
|
||||
if (!(lease = lease6_find_by_addr(addr, 128, 0)))
|
||||
return 1;
|
||||
|
||||
@@ -1773,7 +1812,7 @@ static int config_valid(struct dhcp_conf
|
||||
{
|
||||
setaddr6part(addr, addrpart+i);
|
||||
|
||||
- if (check_address(state, addr))
|
||||
+ if (check_address(state, config, addr))
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
choice
|
||||
prompt "Binutils Version" if TOOLCHAINOPTS
|
||||
default BINUTILS_USE_VERSION_2_34
|
||||
default BINUTILS_USE_VERSION_2_37
|
||||
help
|
||||
Select the version of binutils you wish to use.
|
||||
|
||||
|
@ -2,7 +2,6 @@ config BINUTILS_VERSION_2_32
|
||||
bool
|
||||
|
||||
config BINUTILS_VERSION_2_34
|
||||
default y if !TOOLCHAINOPTS
|
||||
bool
|
||||
|
||||
config BINUTILS_VERSION_2_35_2
|
||||
@ -12,6 +11,7 @@ config BINUTILS_VERSION_2_36_1
|
||||
bool
|
||||
|
||||
config BINUTILS_VERSION_2_37
|
||||
default y if !TOOLCHAINOPTS
|
||||
bool
|
||||
|
||||
config BINUTILS_VERSION_2_38
|
||||
|
Loading…
Reference in New Issue
Block a user