From 168828486e422f227ee5b83c3617229c47e7f75e Mon Sep 17 00:00:00 2001 From: lean Date: Mon, 12 Sep 2022 01:24:33 +0800 Subject: [PATCH] dnsmasq: add patch for DHCPv6 to honor IPv6 address on MAC address --- .../network/services/dnsmasq/files/dhcp.conf | 2 +- ...igning-IPv6-address-based-on-MAC-add.patch | 166 ++++++++++++++++++ toolchain/binutils/Config.in | 2 +- toolchain/binutils/Config.version | 2 +- 4 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch diff --git a/package/network/services/dnsmasq/files/dhcp.conf b/package/network/services/dnsmasq/files/dhcp.conf index 94d20432c..29c9d705f 100644 --- a/package/network/services/dnsmasq/files/dhcp.conf +++ b/package/network/services/dnsmasq/files/dhcp.conf @@ -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 diff --git a/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch b/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch new file mode 100644 index 000000000..4dd7e22b3 --- /dev/null +++ b/package/network/services/dnsmasq/patches/300-DHCPv6-Honor-assigning-IPv6-address-based-on-MAC-add.patch @@ -0,0 +1,166 @@ +From 93ac8f9d469ff08d41170eb6934842b3626d5fdd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +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; + } + } diff --git a/toolchain/binutils/Config.in b/toolchain/binutils/Config.in index dcc203807..7be854b02 100644 --- a/toolchain/binutils/Config.in +++ b/toolchain/binutils/Config.in @@ -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. diff --git a/toolchain/binutils/Config.version b/toolchain/binutils/Config.version index c20a682b3..0d8533a22 100644 --- a/toolchain/binutils/Config.version +++ b/toolchain/binutils/Config.version @@ -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