diff --git a/dnsmasq-2.81-Extend-79aba0f10ad0157fb4f48afbbcb03f094caff97a.patch b/dnsmasq-2.81-Extend-79aba0f10ad0157fb4f48afbbcb03f094caff97a.patch deleted file mode 100644 index 228f94e..0000000 --- a/dnsmasq-2.81-Extend-79aba0f10ad0157fb4f48afbbcb03f094caff97a.patch +++ /dev/null @@ -1,760 +0,0 @@ -From c491296241396d0144750f178ffd5c0e0b089a80 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Thu, 6 Feb 2020 22:09:30 +0000 -Subject: [PATCH] Extend 79aba0f10ad0157fb4f48afbbcb03f094caff97a for multiple - IPv6 addresses. - -(cherry picked from commit 137286e9baecf6a3ba97722ef1b49c851b531810) ---- - man/dnsmasq.8 | 7 +- - src/dhcp-common.c | 55 ++++-- - src/dhcp6.c | 13 +- - src/dnsmasq.h | 13 +- - src/option.c | 416 +++++++++++++++++++++++++--------------------- - src/rfc3315.c | 88 +++++----- - 6 files changed, 330 insertions(+), 262 deletions(-) - -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index 95cd3ca..d1caeed 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -1008,14 +1008,15 @@ allowed to specify the client ID as text, like this: - - A single - .B --dhcp-host --may contain an IPv4 address or an IPv6 address, or both. IPv6 addresses must be bracketed by square brackets thus: -+may contain an IPv4 address or one or more IPv6 addresses, or both. IPv6 addresses must be bracketed by square brackets thus: - .B --dhcp-host=laptop,[1234::56] - IPv6 addresses may contain only the host-identifier part: - .B --dhcp-host=laptop,[::56] - in which case they act as wildcards in constructed dhcp ranges, with --the appropriate network part inserted. For IPv6, the address may include a prefix length: -+the appropriate network part inserted. For IPv6, an address may include a prefix length: - .B --dhcp-host=laptop,[1234:50/126] --which (in this case) specifies four addresses, 1234::50 to 1234::53. This is useful -+which (in this case) specifies four addresses, 1234::50 to 1234::53. This (an the ability -+to specify multiple addresses) is useful - when a host presents either a consistent name or hardware-ID, but varying DUIDs, since it allows - dnsmasq to honour the static address allocation but assign a different adddress for each DUID. This - typically occurs when chain netbooting, as each stage of the chain gets in turn allocates an address. -diff --git a/src/dhcp-common.c b/src/dhcp-common.c -index 99d34c8..2933343 100644 ---- a/src/dhcp-common.c -+++ b/src/dhcp-common.c -@@ -271,26 +271,35 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config - { - if (!context) /* called via find_config() from lease_update_from_configs() */ - return 1; -- -- if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6))) -- return 1; - - #ifdef HAVE_DHCP6 -- if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD)) -- return 1; --#endif -+ if (context->flags & CONTEXT_V6) -+ { -+ struct addrlist *addr_list; - -- for (; context; context = context->current) --#ifdef HAVE_DHCP6 -- if (context->flags & CONTEXT_V6) -- { -- if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &context->start6, context->prefix)) -- return 1; -- } -- else -+ if (!(config->flags & CONFIG_ADDR6)) -+ return 1; -+ -+ for (; context; context = context->current) -+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) -+ { -+ if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64) -+ return 1; -+ -+ if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix)) -+ return 1; -+ } -+ } -+ else - #endif -- if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask)) -+ { -+ if (!(config->flags & CONFIG_ADDR)) - return 1; -+ -+ for (; context; context = context->current) -+ if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->start, context->netmask)) -+ return 1; -+ } - - return 0; - } -@@ -420,9 +429,19 @@ void dhcp_update_configs(struct dhcp_config *configs) - if (prot == AF_INET6 && - (!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->addr.addr.addr.addr6)) || conf_tmp == config)) - { -- memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ); -- config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS; -- config->flags &= ~CONFIG_PREFIX; -+ /* host must have exactly one address if comming from /etc/hosts. */ -+ if (!config->addr6 && (config->addr6 = whine_malloc(sizeof(struct addrlist)))) -+ { -+ config->addr6->next = NULL; -+ config->addr6->flags = 0; -+ } -+ -+ if (config->addr6 && !config->addr6->next && !(config->addr6->flags & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX))) -+ { -+ memcpy(&config->addr6->addr.addr6, &crec->addr.addr6, IN6ADDRSZ); -+ config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS; -+ } -+ - continue; - } - #endif -diff --git a/src/dhcp6.c b/src/dhcp6.c -index 11a9d83..4e28e61 100644 ---- a/src/dhcp6.c -+++ b/src/dhcp6.c -@@ -389,10 +389,15 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct - struct dhcp_config *config; - - for (config = configs; config; config = config->next) -- if ((config->flags & CONFIG_ADDR6) && -- (!net || is_same_net6(&config->addr6, net, prefix)) && -- is_same_net6(&config->addr6, addr, (config->flags & CONFIG_PREFIX) ? config->prefix : 128)) -- return config; -+ if (config->flags & CONFIG_ADDR6) -+ { -+ struct addrlist *addr_list; -+ -+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) -+ if ((!net || is_same_net6(&addr_list->addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) && -+ is_same_net6(&addr_list->addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128)) -+ return config; -+ } - - return NULL; - } -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 86b8168..08484ba 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -350,9 +350,11 @@ struct ds_config { - struct ds_config *next; - }; - --#define ADDRLIST_LITERAL 1 --#define ADDRLIST_IPV6 2 --#define ADDRLIST_REVONLY 4 -+#define ADDRLIST_LITERAL 1 -+#define ADDRLIST_IPV6 2 -+#define ADDRLIST_REVONLY 4 -+#define ADDRLIST_PREFIX 8 -+#define ADDRLIST_WILDCARD 16 - - struct addrlist { - struct all_addr addr; -@@ -774,8 +776,7 @@ struct dhcp_config { - char *hostname, *domain; - struct dhcp_netid_list *netid; - #ifdef HAVE_DHCP6 -- struct in6_addr addr6; -- int prefix; -+ struct addrlist *addr6; - #endif - struct in_addr addr; - time_t decline_time; -@@ -797,8 +798,6 @@ struct dhcp_config { - #define CONFIG_DECLINED 1024 /* address declined by client */ - #define CONFIG_BANK 2048 /* from dhcp hosts file */ - #define CONFIG_ADDR6 4096 --#define CONFIG_WILDCARD 8192 --#define CONFIG_PREFIX 32768 /* addr6 is a set, size given by prefix */ - - struct dhcp_opt { - int opt, len, flags; -diff --git a/src/option.c b/src/option.c -index 389eb02..2bbb11b 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -988,6 +988,19 @@ static void dhcp_config_free(struct dhcp_config *config) - free(list); - } - -+#ifdef HAVE_DHCP6 -+ if (config->flags & CONFIG_ADDR6) -+ { -+ struct addrlist *addr, *tmp; -+ -+ for (addr = config->addr6; addr; addr = tmp) -+ { -+ tmp = addr->next; -+ free(addr); -+ } -+ } -+#endif -+ - if (config->flags & CONFIG_NAME) - free(config->hostname); - -@@ -995,6 +1008,11 @@ static void dhcp_config_free(struct dhcp_config *config) - } - - -+ -+ -+ -+ -+ - /* This is too insanely large to keep in-line in the switch */ - static int parse_dhcp_opt(char *errstr, char *arg, int flags) - { -@@ -3053,8 +3071,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - case LOPT_BANK: - case 'G': /* --dhcp-host */ - { -- int j, k = 0; -- char *a[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - struct dhcp_config *new; - struct in_addr in; - -@@ -3064,203 +3080,227 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0; - new->hwaddr = NULL; - new->netid = NULL; -+ new->addr6 = NULL; - -- if ((a[0] = arg)) -- for (k = 1; k < 7; k++) -- if (!(a[k] = split(a[k-1]))) -- break; -- -- for (j = 0; j < k; j++) -- if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */ -- { -- char *arg = a[j]; -- -- if ((arg[0] == 'i' || arg[0] == 'I') && -- (arg[1] == 'd' || arg[1] == 'D') && -- arg[2] == ':') -- { -- if (arg[3] == '*') -- new->flags |= CONFIG_NOCLID; -- else -- { -- int len; -- arg += 3; /* dump id: */ -- if (strchr(arg, ':')) -- len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL); -- else -- { -- unhide_metas(arg); -- len = (int) strlen(arg); -- } -- -- if (len == -1) -- ret_err(_("bad hex constant")); -- else if ((new->clid = opt_malloc(len))) -- { -- new->flags |= CONFIG_CLID; -- new->clid_len = len; -- memcpy(new->clid, arg, len); -- } -- } -- } -- /* dhcp-host has strange backwards-compat needs. */ -- else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg) -- { -- struct dhcp_netid *newtag = opt_malloc(sizeof(struct dhcp_netid)); -- struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list)); -- newtag->net = opt_malloc(strlen(arg + 4) + 1); -- newlist->next = new->netid; -- new->netid = newlist; -- newlist->list = newtag; -- strcpy(newtag->net, arg+4); -- unhide_metas(newtag->net); -- } -- else if (strstr(arg, "tag:") == arg) -- ret_err(_("cannot match tags in --dhcp-host")); -+ while (arg) -+ { -+ comma = split(arg); -+ if (strchr(arg, ':')) /* ethernet address, netid or binary CLID */ -+ { -+ if ((arg[0] == 'i' || arg[0] == 'I') && -+ (arg[1] == 'd' || arg[1] == 'D') && -+ arg[2] == ':') -+ { -+ if (arg[3] == '*') -+ new->flags |= CONFIG_NOCLID; -+ else -+ { -+ int len; -+ arg += 3; /* dump id: */ -+ if (strchr(arg, ':')) -+ len = parse_hex(arg, (unsigned char *)arg, -1, NULL, NULL); -+ else -+ { -+ unhide_metas(arg); -+ len = (int) strlen(arg); -+ } -+ -+ if (len == -1) -+ { -+ dhcp_config_free(new); -+ ret_err(_("bad hex constant")); -+ } -+ else if ((new->clid = opt_malloc(len))) -+ { -+ new->flags |= CONFIG_CLID; -+ new->clid_len = len; -+ memcpy(new->clid, arg, len); -+ } -+ } -+ } -+ /* dhcp-host has strange backwards-compat needs. */ -+ else if (strstr(arg, "net:") == arg || strstr(arg, "set:") == arg) -+ { -+ struct dhcp_netid *newtag = opt_malloc(sizeof(struct dhcp_netid)); -+ struct dhcp_netid_list *newlist = opt_malloc(sizeof(struct dhcp_netid_list)); -+ newtag->net = opt_malloc(strlen(arg + 4) + 1); -+ newlist->next = new->netid; -+ new->netid = newlist; -+ newlist->list = newtag; -+ strcpy(newtag->net, arg+4); -+ unhide_metas(newtag->net); -+ } -+ else if (strstr(arg, "tag:") == arg) -+ { -+ -+ dhcp_config_free(new); -+ ret_err(_("cannot match tags in --dhcp-host")); -+ } - #ifdef HAVE_DHCP6 -- else if (arg[0] == '[' && arg[strlen(arg)-1] == ']') -- { -- char *pref; -- -- arg[strlen(arg)-1] = 0; -- arg++; -- pref = split_chr(arg, '/'); -- -- if (!inet_pton(AF_INET6, arg, &new->addr6)) -- ret_err(_("bad IPv6 address")); -- -- if (pref) -- { -- u64 addrpart = addr6part(&new->addr6); -- -- if (!atoi_check(pref, &new->prefix) || -- new->prefix > 128 || -- (((1<<(128-new->prefix))-1) & addrpart) != 0) -- { -- dhcp_config_free(new); -- ret_err(_("bad IPv6 prefix")); -- } -- -- new->flags |= CONFIG_PREFIX; -- } -- -- for (i= 0; i < 8; i++) -- if (new->addr6.s6_addr[i] != 0) -- break; -+ else if (arg[0] == '[' && arg[strlen(arg)-1] == ']') -+ { -+ char *pref; -+ struct in6_addr in6; -+ struct addrlist *new_addr; -+ -+ arg[strlen(arg)-1] = 0; -+ arg++; -+ pref = split_chr(arg, '/'); -+ -+ if (!inet_pton(AF_INET6, arg, &in6)) -+ { -+ dhcp_config_free(new); -+ ret_err(_("bad IPv6 address")); -+ } - -- /* set WILDCARD if network part all zeros */ -- if (i == 8) -- new->flags |= CONFIG_WILDCARD; -+ new_addr = opt_malloc(sizeof(struct addrlist)); -+ new_addr->next = new->addr6; -+ new_addr->flags = 0; -+ new_addr->addr.addr6 = in6; -+ new->addr6 = new_addr; -+ -+ if (pref) -+ { -+ u64 addrpart = addr6part(&in6); -+ -+ if (!atoi_check(pref, &new_addr->prefixlen) || -+ new_addr->prefixlen > 128 || -+ (((1<<(128-new_addr->prefixlen))-1) & addrpart) != 0) -+ { -+ dhcp_config_free(new); -+ ret_err(_("bad IPv6 prefix")); -+ } -+ -+ new_addr->flags |= ADDRLIST_PREFIX; -+ } - -- new->flags |= CONFIG_ADDR6; -- } -+ for (i= 0; i < 8; i++) -+ if (in6.s6_addr[i] != 0) -+ break; -+ -+ /* set WILDCARD if network part all zeros */ -+ if (i == 8) -+ new_addr->flags |= ADDRLIST_WILDCARD; -+ -+ new->flags |= CONFIG_ADDR6; -+ } - #endif -- else -- { -- struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config)); -- if ((newhw->hwaddr_len = parse_hex(a[j], newhw->hwaddr, DHCP_CHADDR_MAX, -- &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1) -- ret_err(_("bad hex constant")); -- else -- { -- -- newhw->next = new->hwaddr; -- new->hwaddr = newhw; -- } -- } -- } -- else if (strchr(a[j], '.') && (inet_pton(AF_INET, a[j], &in) > 0)) -- { -- struct dhcp_config *configs; -- -- new->addr = in; -- new->flags |= CONFIG_ADDR; -- -- /* If the same IP appears in more than one host config, then DISCOVER -- for one of the hosts will get the address, but REQUEST will be NAKed, -- since the address is reserved by the other one -> protocol loop. */ -- for (configs = daemon->dhcp_conf; configs; configs = configs->next) -- if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr) -+ else - { -- sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in)); -- return 0; -- } -- } -- else -- { -- char *cp, *lastp = NULL, last = 0; -- int fac = 1, isdig = 0; -- -- if (strlen(a[j]) > 1) -- { -- lastp = a[j] + strlen(a[j]) - 1; -- last = *lastp; -- switch (last) -+ struct hwaddr_config *newhw = opt_malloc(sizeof(struct hwaddr_config)); -+ if ((newhw->hwaddr_len = parse_hex(arg, newhw->hwaddr, DHCP_CHADDR_MAX, -+ &newhw->wildcard_mask, &newhw->hwaddr_type)) == -1) -+ { -+ free(newhw); -+ dhcp_config_free(new); -+ ret_err(_("bad hex constant")); -+ } -+ else -+ { -+ -+ newhw->next = new->hwaddr; -+ new->hwaddr = newhw; -+ } -+ } -+ } -+ else if (strchr(arg, '.') && (inet_pton(AF_INET, arg, &in) > 0)) -+ { -+ struct dhcp_config *configs; -+ -+ new->addr = in; -+ new->flags |= CONFIG_ADDR; -+ -+ /* If the same IP appears in more than one host config, then DISCOVER -+ for one of the hosts will get the address, but REQUEST will be NAKed, -+ since the address is reserved by the other one -> protocol loop. */ -+ for (configs = daemon->dhcp_conf; configs; configs = configs->next) -+ if ((configs->flags & CONFIG_ADDR) && configs->addr.s_addr == in.s_addr) - { -- case 'w': -- case 'W': -- fac *= 7; -- /* fall through */ -- case 'd': -- case 'D': -- fac *= 24; -- /* fall through */ -- case 'h': -- case 'H': -- fac *= 60; -- /* fall through */ -- case 'm': -- case 'M': -- fac *= 60; -- /* fall through */ -- case 's': -- case 'S': -- *lastp = 0; -- } -- } -- -- for (cp = a[j]; *cp; cp++) -- if (isdigit((unsigned char)*cp)) -- isdig = 1; -- else if (*cp != ' ') -- break; -+ sprintf(errstr, _("duplicate dhcp-host IP address %s"), inet_ntoa(in)); -+ return 0; -+ } -+ } -+ else -+ { -+ char *cp, *lastp = NULL, last = 0; -+ int fac = 1, isdig = 0; -+ -+ if (strlen(arg) > 1) -+ { -+ lastp = arg + strlen(arg) - 1; -+ last = *lastp; -+ switch (last) -+ { -+ case 'w': -+ case 'W': -+ fac *= 7; -+ /* fall through */ -+ case 'd': -+ case 'D': -+ fac *= 24; -+ /* fall through */ -+ case 'h': -+ case 'H': -+ fac *= 60; -+ /* fall through */ -+ case 'm': -+ case 'M': -+ fac *= 60; -+ /* fall through */ -+ case 's': -+ case 'S': -+ *lastp = 0; -+ } -+ } -+ -+ for (cp = arg; *cp; cp++) -+ if (isdigit((unsigned char)*cp)) -+ isdig = 1; -+ else if (*cp != ' ') -+ break; -+ -+ if (*cp) -+ { -+ if (lastp) -+ *lastp = last; -+ if (strcmp(arg, "infinite") == 0) -+ { -+ new->lease_time = 0xffffffff; -+ new->flags |= CONFIG_TIME; -+ } -+ else if (strcmp(arg, "ignore") == 0) -+ new->flags |= CONFIG_DISABLE; -+ else -+ { -+ if (!(new->hostname = canonicalise_opt(arg)) || -+ !legal_hostname(new->hostname)) -+ { -+ dhcp_config_free(new); -+ ret_err(_("bad DHCP host name")); -+ } -+ -+ new->flags |= CONFIG_NAME; -+ new->domain = strip_hostname(new->hostname); -+ } -+ } -+ else if (isdig) -+ { -+ new->lease_time = atoi(arg) * fac; -+ /* Leases of a minute or less confuse -+ some clients, notably Apple's */ -+ if (new->lease_time < 120) -+ new->lease_time = 120; -+ new->flags |= CONFIG_TIME; -+ } -+ } -+ -+ arg = comma; -+ } - -- if (*cp) -- { -- if (lastp) -- *lastp = last; -- if (strcmp(a[j], "infinite") == 0) -- { -- new->lease_time = 0xffffffff; -- new->flags |= CONFIG_TIME; -- } -- else if (strcmp(a[j], "ignore") == 0) -- new->flags |= CONFIG_DISABLE; -- else -- { -- if (!(new->hostname = canonicalise_opt(a[j])) || -- !legal_hostname(new->hostname)) -- ret_err(_("bad DHCP host name")); -- -- new->flags |= CONFIG_NAME; -- new->domain = strip_hostname(new->hostname); -- } -- } -- else if (isdig) -- { -- new->lease_time = atoi(a[j]) * fac; -- /* Leases of a minute or less confuse -- some clients, notably Apple's */ -- if (new->lease_time < 120) -- new->lease_time = 120; -- new->flags |= CONFIG_TIME; -- } -- } -- - daemon->dhcp_conf = new; - break; - } -- -+ - case LOPT_TAG_IF: /* --tag-if */ - { - struct tag_if *new = opt_malloc(sizeof(struct tag_if)); -diff --git a/src/rfc3315.c b/src/rfc3315.c -index f4f032e..9dc33f9 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -1793,68 +1793,72 @@ static int config_implies(struct dhcp_config *config, struct dhcp_context *conte - { - int prefix; - struct in6_addr wild_addr; -- -+ struct addrlist *addr_list; -+ - if (!config || !(config->flags & CONFIG_ADDR6)) - return 0; - -- prefix = (config->flags & CONFIG_PREFIX) ? config->prefix : 128; -- wild_addr = config->addr6; -- -- if (!is_same_net6(&context->start6, addr, context->prefix)) -- return 0; -- -- if ((config->flags & CONFIG_WILDCARD)) -+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) - { -- if (context->prefix != 64) -- return 0; -+ prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128; -+ wild_addr = addr_list->addr.addr6; -+ -+ if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64) -+ { -+ wild_addr = context->start6; -+ setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6)); -+ } -+ else if (!is_same_net6(&context->start6, addr, context->prefix)) -+ continue; - -- wild_addr = context->start6; -- setaddr6part(&wild_addr, addr6part(&config->addr6)); -+ if (is_same_net6(&wild_addr, addr, prefix)) -+ return 1; - } - -- if (is_same_net6(&wild_addr, addr, prefix)) -- return 1; -- - return 0; - } - - static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state) - { - u64 addrpart; -- -+ struct addrlist *addr_list; -+ - if (!config || !(config->flags & CONFIG_ADDR6)) - return 0; - -- addrpart = addr6part(&config->addr6); -- -- if ((config->flags & CONFIG_WILDCARD)) -+ for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) - { -- if (context->prefix != 64) -- return 0; -+ addrpart = addr6part(&addr_list->addr.addr6); -+ -+ if ((addr_list->flags & ADDRLIST_WILDCARD)) -+ { -+ if (context->prefix != 64) -+ continue; - -- *addr = context->start6; -- setaddr6part(addr, addrpart); -+ *addr = context->start6; -+ setaddr6part(addr, addrpart); -+ } -+ else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix)) -+ *addr = addr_list->addr.addr6; -+ else -+ continue; -+ -+ while(1) -+ { -+ if (check_address(state, addr)) -+ return 1; -+ -+ if (!(addr_list->flags & ADDRLIST_PREFIX)) -+ break; -+ -+ addrpart++; -+ setaddr6part(addr, addrpart); -+ if (!is_same_net6(addr, &addr_list->addr.addr6, addr_list->prefixlen)) -+ break; -+ } - } -- else if (is_same_net6(&context->start6, &config->addr6, context->prefix)) -- *addr = config->addr6; -- else -- return 0; - -- while(1) { -- if (check_address(state, addr)) -- return 1; -- -- if (!(config->flags & CONFIG_PREFIX)) -- return 0; -- -- /* config may specify a set of addresses, return first one not in use -- by another client */ -- -- addrpart++; -- setaddr6part(addr, addrpart); -- if (!is_same_net6(addr, &config->addr6, config->prefix)) -- return 0; -- } -+ return 0; - } - - /* Calculate valid and preferred times to send in leases/renewals. --- -2.21.1 - diff --git a/dnsmasq-2.81-adjust-changes-to-version-2.80.patch b/dnsmasq-2.81-adjust-changes-to-version-2.80.patch deleted file mode 100644 index 2e84d25..0000000 --- a/dnsmasq-2.81-adjust-changes-to-version-2.80.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0ced3a9527a2163bdb8f7da30a71f2f327c2e0fb Mon Sep 17 00:00:00 2001 -From: Petr Mensik -Date: Wed, 4 Mar 2020 18:57:04 +0100 -Subject: [PATCH] Adjust changes to version 2.80 - -Modify previous changes to current version. ---- - src/dhcp-common.c | 6 +++--- - src/dhcp6.c | 4 ++-- - src/option.c | 2 +- - src/rfc3315.c | 12 ++++++------ - 4 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/src/dhcp-common.c b/src/dhcp-common.c -index 2933343..ffa927d 100644 ---- a/src/dhcp-common.c -+++ b/src/dhcp-common.c -@@ -286,7 +286,7 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config - if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64) - return 1; - -- if (is_same_net6(&addr_list->addr.addr6, &context->start6, context->prefix)) -+ if (is_same_net6(&addr_list->addr.addr.addr6, &context->start6, context->prefix)) - return 1; - } - } -@@ -438,8 +438,8 @@ void dhcp_update_configs(struct dhcp_config *configs) - - if (config->addr6 && !config->addr6->next && !(config->addr6->flags & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX))) - { -- memcpy(&config->addr6->addr.addr6, &crec->addr.addr6, IN6ADDRSZ); -- config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS; -+ memcpy(&config->addr6->addr.addr.addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ); -+ config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS; - } - - continue; -diff --git a/src/dhcp6.c b/src/dhcp6.c -index 4e28e61..1dedd2f 100644 ---- a/src/dhcp6.c -+++ b/src/dhcp6.c -@@ -394,8 +394,8 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct - struct addrlist *addr_list; - - for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) -- if ((!net || is_same_net6(&addr_list->addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) && -- is_same_net6(&addr_list->addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128)) -+ if ((!net || is_same_net6(&addr_list->addr.addr.addr6, net, prefix) || ((addr_list->flags & ADDRLIST_WILDCARD) && prefix == 64)) && -+ is_same_net6(&addr_list->addr.addr.addr6, addr, (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128)) - return config; - } - -diff --git a/src/option.c b/src/option.c -index 2bbb11b..61cfb8c 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -3156,7 +3156,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - new_addr = opt_malloc(sizeof(struct addrlist)); - new_addr->next = new->addr6; - new_addr->flags = 0; -- new_addr->addr.addr6 = in6; -+ new_addr->addr.addr.addr6 = in6; - new->addr6 = new_addr; - - if (pref) -diff --git a/src/rfc3315.c b/src/rfc3315.c -index 9dc33f9..a7bf929 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -1801,12 +1801,12 @@ static int config_implies(struct dhcp_config *config, struct dhcp_context *conte - for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) - { - prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128; -- wild_addr = addr_list->addr.addr6; -+ wild_addr = addr_list->addr.addr.addr6; - - if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64) - { - wild_addr = context->start6; -- setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6)); -+ setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr.addr6)); - } - else if (!is_same_net6(&context->start6, addr, context->prefix)) - continue; -@@ -1828,7 +1828,7 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context - - for (addr_list = config->addr6; addr_list; addr_list = addr_list->next) - { -- addrpart = addr6part(&addr_list->addr.addr6); -+ addrpart = addr6part(&addr_list->addr.addr.addr6); - - if ((addr_list->flags & ADDRLIST_WILDCARD)) - { -@@ -1838,8 +1838,8 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context - *addr = context->start6; - setaddr6part(addr, addrpart); - } -- else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix)) -- *addr = addr_list->addr.addr6; -+ else if (is_same_net6(&context->start6, &addr_list->addr.addr.addr6, context->prefix)) -+ *addr = addr_list->addr.addr.addr6; - else - continue; - -@@ -1853,7 +1853,7 @@ static int config_valid(struct dhcp_config *config, struct dhcp_context *context - - addrpart++; - setaddr6part(addr, addrpart); -- if (!is_same_net6(addr, &addr_list->addr.addr6, addr_list->prefixlen)) -+ if (!is_same_net6(addr, &addr_list->addr.addr.addr6, addr_list->prefixlen)) - break; - } - } --- -2.21.1 - diff --git a/dnsmasq-2.81-prefix-ranges-or-list-of-ipv6-addresses.patch b/dnsmasq-2.81-prefix-ranges-or-list-of-ipv6-addresses.patch deleted file mode 100644 index 2898ede..0000000 --- a/dnsmasq-2.81-prefix-ranges-or-list-of-ipv6-addresses.patch +++ /dev/null @@ -1,396 +0,0 @@ -From e81e994303a89998c5796a5951192e3a0c0395bc Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Mon, 3 Feb 2020 23:58:45 +0000 -Subject: [PATCH] Support prefixed ranges of ipv6 addresses in dhcp-host. - -When a request matching the clid or mac address is -recieved the server will iterate over all candidate -addresses until it find's one that is not already -leased to a different clid/iaid and advertise -this address. - -Using multiple reservations for a single host makes it -possible to maintain a static leases only configuration -which support network booting systems with UEFI firmware -that request a new address (a new SOLICIT with a new IA_NA -option using a new IAID) for different boot modes, for -instance 'PXE over IPv6', and 'HTTP-Boot over IPv6'. Open -Virtual Machine Firmware (OVMF) and most UEFI firmware -build on the EDK2 code base exhibit this behaviour. - -(cherry picked from commit 79aba0f10ad0157fb4f48afbbcb03f094caff97a) ---- - man/dnsmasq.8 | 8 ++++- - src/dhcp-common.c | 3 +- - src/dhcp6.c | 40 ++++++----------------- - src/dnsmasq.h | 5 +-- - src/option.c | 48 +++++++++++++++++++++++++++ - src/rfc3315.c | 82 +++++++++++++++++++++++++++++++++++++++++++---- - 6 files changed, 144 insertions(+), 42 deletions(-) - -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index f01a5ba..95cd3ca 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -1013,7 +1013,13 @@ may contain an IPv4 address or an IPv6 address, or both. IPv6 addresses must be - IPv6 addresses may contain only the host-identifier part: - .B --dhcp-host=laptop,[::56] - in which case they act as wildcards in constructed dhcp ranges, with --the appropriate network part inserted. -+the appropriate network part inserted. For IPv6, the address may include a prefix length: -+.B --dhcp-host=laptop,[1234:50/126] -+which (in this case) specifies four addresses, 1234::50 to 1234::53. This is useful -+when a host presents either a consistent name or hardware-ID, but varying DUIDs, since it allows -+dnsmasq to honour the static address allocation but assign a different adddress for each DUID. This -+typically occurs when chain netbooting, as each stage of the chain gets in turn allocates an address. -+ - Note that in IPv6 DHCP, the hardware address may not be - available, though it normally is for direct-connected clients, or - clients using DHCP relays which support RFC 6939. -diff --git a/src/dhcp-common.c b/src/dhcp-common.c -index 78c1d9b..99d34c8 100644 ---- a/src/dhcp-common.c -+++ b/src/dhcp-common.c -@@ -418,10 +418,11 @@ void dhcp_update_configs(struct dhcp_config *configs) - - #ifdef HAVE_DHCP6 - if (prot == AF_INET6 && -- (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config)) -+ (!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->addr.addr.addr.addr6)) || conf_tmp == config)) - { - memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ); - config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS; -+ config->flags &= ~CONFIG_PREFIX; - continue; - } - #endif -diff --git a/src/dhcp6.c b/src/dhcp6.c -index b7cce45..11a9d83 100644 ---- a/src/dhcp6.c -+++ b/src/dhcp6.c -@@ -384,14 +384,14 @@ static int complete_context6(struct in6_addr *local, int prefix, - return 1; - } - --struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr) -+struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, struct in6_addr *addr) - { - struct dhcp_config *config; - - for (config = configs; config; config = config->next) - if ((config->flags & CONFIG_ADDR6) && -- is_same_net6(&config->addr6, net, prefix) && -- (prefix == 128 || addr6part(&config->addr6) == addr)) -+ (!net || is_same_net6(&config->addr6, net, prefix)) && -+ is_same_net6(&config->addr6, addr, (config->flags & CONFIG_PREFIX) ? config->prefix : 128)) - return config; - - return NULL; -@@ -453,16 +453,15 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c - for (d = context; d; d = d->current) - if (addr == addr6part(&d->local6)) - break; -+ -+ *ans = c->start6; -+ setaddr6part (ans, addr); - - if (!d && - !lease6_find_by_addr(&c->start6, c->prefix, addr) && -- !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, addr)) -- { -- *ans = c->start6; -- setaddr6part (ans, addr); -- return c; -- } -- -+ !config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, ans)) -+ return c; -+ - addr++; - - if (addr == addr6part(&c->end6) + 1) -@@ -516,27 +515,6 @@ struct dhcp_context *address6_valid(struct dhcp_context *context, - return NULL; - } - --int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr) --{ -- if (!config || !(config->flags & CONFIG_ADDR6)) -- return 0; -- -- if ((config->flags & CONFIG_WILDCARD) && context->prefix == 64) -- { -- *addr = context->start6; -- setaddr6part(addr, addr6part(&config->addr6)); -- return 1; -- } -- -- if (is_same_net6(&context->start6, &config->addr6, context->prefix)) -- { -- *addr = config->addr6; -- return 1; -- } -- -- return 0; --} -- - void make_duid(time_t now) - { - (void)now; -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 8d84714..86b8168 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -775,6 +775,7 @@ struct dhcp_config { - struct dhcp_netid_list *netid; - #ifdef HAVE_DHCP6 - struct in6_addr addr6; -+ int prefix; - #endif - struct in_addr addr; - time_t decline_time; -@@ -797,6 +798,7 @@ struct dhcp_config { - #define CONFIG_BANK 2048 /* from dhcp hosts file */ - #define CONFIG_ADDR6 4096 - #define CONFIG_WILDCARD 8192 -+#define CONFIG_PREFIX 32768 /* addr6 is a set, size given by prefix */ - - struct dhcp_opt { - int opt, len, flags; -@@ -1514,7 +1516,6 @@ void dhcp6_init(void); - void dhcp6_packet(time_t now); - struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr, - int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans); --int config_valid(struct dhcp_config *config, 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, -@@ -1524,7 +1525,7 @@ struct dhcp_context *address6_valid(struct dhcp_context *context, - struct dhcp_netid *netids, - int plain_range); - struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, -- int prefix, u64 addr); -+ int prefix, struct in6_addr *addr); - void make_duid(time_t now); - void dhcp_construct_contexts(time_t now); - void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, -diff --git a/src/option.c b/src/option.c -index f03a6b3..389eb02 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -965,6 +965,35 @@ static char *set_prefix(char *arg) - - return arg; - } -+ -+/* Legacy workaround, backported from 2.81 */ -+static void dhcp_config_free(struct dhcp_config *config) -+{ -+ struct hwaddr_config *mac, *tmp; -+ struct dhcp_netid_list *list, *tmplist; -+ -+ for (mac = config->hwaddr; mac; mac = tmp) -+ { -+ tmp = mac->next; -+ free(mac); -+ } -+ -+ if (config->flags & CONFIG_CLID) -+ free(config->clid); -+ -+ for (list = config->netid; list; list = tmplist) -+ { -+ free(list->list); -+ tmplist = list->next; -+ free(list); -+ } -+ -+ if (config->flags & CONFIG_NAME) -+ free(config->hostname); -+ -+ free(config); -+} -+ - - /* This is too insanely large to keep in-line in the switch */ - static int parse_dhcp_opt(char *errstr, char *arg, int flags) -@@ -1512,6 +1541,7 @@ void reset_option_bool(unsigned int opt) - daemon->options2 &= ~(1u << (opt - 32)); - } - -+ - static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only) - { - int i; -@@ -3090,12 +3120,30 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - #ifdef HAVE_DHCP6 - else if (arg[0] == '[' && arg[strlen(arg)-1] == ']') - { -+ char *pref; -+ - arg[strlen(arg)-1] = 0; - arg++; -+ pref = split_chr(arg, '/'); - - if (!inet_pton(AF_INET6, arg, &new->addr6)) - ret_err(_("bad IPv6 address")); - -+ if (pref) -+ { -+ u64 addrpart = addr6part(&new->addr6); -+ -+ if (!atoi_check(pref, &new->prefix) || -+ new->prefix > 128 || -+ (((1<<(128-new->prefix))-1) & addrpart) != 0) -+ { -+ dhcp_config_free(new); -+ ret_err(_("bad IPv6 prefix")); -+ } -+ -+ new->flags |= CONFIG_PREFIX; -+ } -+ - for (i= 0; i < 8; i++) - if (new->addr6.s6_addr[i] != 0) - break; -diff --git a/src/rfc3315.c b/src/rfc3315.c -index a20776d..f4f032e 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -55,6 +55,8 @@ static struct prefix_class *prefix_class_from_context(struct dhcp_context *conte - 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 config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state); -+static int 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, - unsigned int *min_time, struct in6_addr *addr, time_t now); - static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now); -@@ -746,7 +748,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - /* If the client asks for an address on the same network as a configured address, - offer the configured address instead, to make moving to newly-configured - addresses automatic. */ -- if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr) && check_address(state, &addr)) -+ if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state)) - { - req_addr = addr; - mark_config_used(c, &addr); -@@ -774,8 +776,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - for (c = state->context; c; c = c->current) - if (!(c->flags & CONTEXT_CONF_USED) && - match_netid(c->filter, solicit_tags, plain_range) && -- config_valid(config, c, &addr) && -- check_address(state, &addr)) -+ config_valid(config, c, &addr, state)) - { - mark_config_used(state->context, &addr); - if (have_config(config, CONFIG_TIME)) -@@ -924,14 +925,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - struct in6_addr req_addr; - struct dhcp_context *dynamic, *c; - unsigned int lease_time; -- struct in6_addr addr; - int config_ok = 0; - - /* align. */ - memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); - - if ((c = address6_valid(state->context, &req_addr, tagif, 1))) -- config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr); -+ config_ok = config_implies(config, c, &req_addr); - - if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c) - { -@@ -1061,12 +1061,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) || - (this_context = address6_valid(state->context, &req_addr, tagif, 1))) - { -- struct in6_addr addr; - unsigned int lease_time; - - get_context_tag(state, this_context); - -- if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, &req_addr) && have_config(config, CONFIG_TIME)) -+ if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME)) - lease_time = config->lease_time; - else - lease_time = this_context->lease_time; -@@ -1789,6 +1788,75 @@ static int check_address(struct state *state, struct in6_addr *addr) - } - - -+/* return true of *addr could have been generated from config. */ -+static int config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr) -+{ -+ int prefix; -+ struct in6_addr wild_addr; -+ -+ if (!config || !(config->flags & CONFIG_ADDR6)) -+ return 0; -+ -+ prefix = (config->flags & CONFIG_PREFIX) ? config->prefix : 128; -+ wild_addr = config->addr6; -+ -+ if (!is_same_net6(&context->start6, addr, context->prefix)) -+ return 0; -+ -+ if ((config->flags & CONFIG_WILDCARD)) -+ { -+ if (context->prefix != 64) -+ return 0; -+ -+ wild_addr = context->start6; -+ setaddr6part(&wild_addr, addr6part(&config->addr6)); -+ } -+ -+ if (is_same_net6(&wild_addr, addr, prefix)) -+ return 1; -+ -+ return 0; -+} -+ -+static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state) -+{ -+ u64 addrpart; -+ -+ if (!config || !(config->flags & CONFIG_ADDR6)) -+ return 0; -+ -+ addrpart = addr6part(&config->addr6); -+ -+ if ((config->flags & CONFIG_WILDCARD)) -+ { -+ if (context->prefix != 64) -+ return 0; -+ -+ *addr = context->start6; -+ setaddr6part(addr, addrpart); -+ } -+ else if (is_same_net6(&context->start6, &config->addr6, context->prefix)) -+ *addr = config->addr6; -+ else -+ return 0; -+ -+ while(1) { -+ if (check_address(state, addr)) -+ return 1; -+ -+ if (!(config->flags & CONFIG_PREFIX)) -+ return 0; -+ -+ /* config may specify a set of addresses, return first one not in use -+ by another client */ -+ -+ addrpart++; -+ setaddr6part(addr, addrpart); -+ if (!is_same_net6(addr, &config->addr6, config->prefix)) -+ return 0; -+ } -+} -+ - /* Calculate valid and preferred times to send in leases/renewals. - - Inputs are: --- -2.21.1 - diff --git a/dnsmasq-2.81-tag-filtering-of-dhcp-host-directives.patch b/dnsmasq-2.81-tag-filtering-of-dhcp-host-directives.patch deleted file mode 100644 index 3a82fe6..0000000 --- a/dnsmasq-2.81-tag-filtering-of-dhcp-host-directives.patch +++ /dev/null @@ -1,256 +0,0 @@ -From ac4d5ea9436d0196897b7a42fcc02fc4a8a13708 Mon Sep 17 00:00:00 2001 -From: Simon Kelley -Date: Fri, 7 Feb 2020 21:05:54 +0000 -Subject: [PATCH] Add tag filtering of dhcp-host directives. - -(cherry picked from commit 52ec7836139e7a11374971905e5ac0d2d02e32c0) - -Conflicts: - CHANGELOG - src/rfc3315.c ---- - man/dnsmasq.8 | 5 ++++- - src/dhcp-common.c | 42 ++++++++++++++++++++++++++++++++---------- - src/dnsmasq.h | 4 +++- - src/lease.c | 2 +- - src/option.c | 7 ++++--- - src/rfc2131.c | 6 +++--- - src/rfc3315.c | 7 ++++--- - 7 files changed, 51 insertions(+), 22 deletions(-) - -diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 -index d1caeed..2c97738 100644 ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -975,7 +975,7 @@ is also included, as described in RFC-3775 section 7.3. - tells dnsmasq to advertise the prefix without the on-link (aka L) bit set. - - .TP --.B \-G, --dhcp-host=[][,id:|*][,set:][,][,][,][,ignore] -+.B \-G, --dhcp-host=[][,id:|*][,set:][tag:][,][,][,][,ignore] - Specify per host parameters for the DHCP server. This allows a machine - with a particular hardware address to be always allocated the same - hostname, IP address and lease time. A hostname specified like this -@@ -1060,6 +1060,9 @@ ignore requests from unknown machines using - .B --dhcp-ignore=tag:!known - If the host matches only a \fB--dhcp-host\fP directive which cannot - be used because it specifies an address on different subnet, the tag "known-othernet" is set. -+ -+The tag: construct filters which dhcp-host directives are used. Tagged directives are used in preference to untagged ones. -+ - Ethernet addresses (but not client-ids) may have - wildcard bytes, so for example - .B --dhcp-host=00:20:e0:3b:13:*,ignore -diff --git a/src/dhcp-common.c b/src/dhcp-common.c -index ffa927d..3ee82a5 100644 ---- a/src/dhcp-common.c -+++ b/src/dhcp-common.c -@@ -304,11 +304,12 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config - return 0; - } - --struct dhcp_config *find_config(struct dhcp_config *configs, -- struct dhcp_context *context, -- unsigned char *clid, int clid_len, -- unsigned char *hwaddr, int hw_len, -- int hw_type, char *hostname) -+static struct dhcp_config *find_config_match(struct dhcp_config *configs, -+ struct dhcp_context *context, -+ unsigned char *clid, int clid_len, -+ unsigned char *hwaddr, int hw_len, -+ int hw_type, char *hostname, -+ struct dhcp_netid *tags, int tag_not_needed) - { - int count, new; - struct dhcp_config *config, *candidate; -@@ -320,7 +321,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - { - if (config->clid_len == clid_len && - memcmp(config->clid, clid, clid_len) == 0 && -- is_config_in_context(context, config)) -+ is_config_in_context(context, config) && -+ match_netid(config->filter, tags, tag_not_needed)) -+ - return config; - - /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and -@@ -328,7 +331,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - see lease_update_from_configs() */ - if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1 && - memcmp(config->clid, clid+1, clid_len-1) == 0 && -- is_config_in_context(context, config)) -+ is_config_in_context(context, config) && -+ match_netid(config->filter, tags, tag_not_needed)) - return config; - } - -@@ -336,14 +340,16 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - if (hwaddr) - for (config = configs; config; config = config->next) - if (config_has_mac(config, hwaddr, hw_len, hw_type) && -- is_config_in_context(context, config)) -+ is_config_in_context(context, config) && -+ match_netid(config->filter, tags, tag_not_needed)) - return config; - - if (hostname && context) - for (config = configs; config; config = config->next) - if ((config->flags & CONFIG_NAME) && - hostname_isequal(config->hostname, hostname) && -- is_config_in_context(context, config)) -+ is_config_in_context(context, config) && -+ match_netid(config->filter, tags, tag_not_needed)) - return config; - - -@@ -352,7 +358,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - - /* use match with fewest wildcard octets */ - for (candidate = NULL, count = 0, config = configs; config; config = config->next) -- if (is_config_in_context(context, config)) -+ if (is_config_in_context(context, config) && -+ match_netid(config->filter, tags, tag_not_needed)) - for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next) - if (conf_addr->wildcard_mask != 0 && - conf_addr->hwaddr_len == hw_len && -@@ -366,6 +373,21 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - return candidate; - } - -+/* Find tagged configs first. */ -+struct dhcp_config *find_config(struct dhcp_config *configs, -+ struct dhcp_context *context, -+ unsigned char *clid, int clid_len, -+ unsigned char *hwaddr, int hw_len, -+ int hw_type, char *hostname, struct dhcp_netid *tags) -+{ -+ struct dhcp_config *ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 0); -+ -+ if (!ret) -+ ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw_type, hostname, tags, 1); -+ -+ return ret; -+} -+ - void dhcp_update_configs(struct dhcp_config *configs) - { - /* Some people like to keep all static IP addresses in /etc/hosts. -diff --git a/src/dnsmasq.h b/src/dnsmasq.h -index 08484ba..1904e43 100644 ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -775,6 +775,7 @@ struct dhcp_config { - unsigned char *clid; /* clientid */ - char *hostname, *domain; - struct dhcp_netid_list *netid; -+ struct dhcp_netid *filter; - #ifdef HAVE_DHCP6 - struct addrlist *addr6; - #endif -@@ -1563,7 +1564,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs, - struct dhcp_context *context, - unsigned char *clid, int clid_len, - unsigned char *hwaddr, int hw_len, -- int hw_type, char *hostname); -+ int hw_type, char *hostname, -+ struct dhcp_netid *filter); - int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type); - #ifdef HAVE_LINUX_NETWORK - char *whichdevice(void); -diff --git a/src/lease.c b/src/lease.c -index 6012183..2332de8 100644 ---- a/src/lease.c -+++ b/src/lease.c -@@ -222,7 +222,7 @@ void lease_update_from_configs(void) - if (lease->flags & (LEASE_TA | LEASE_NA)) - continue; - else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, -- lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) && -+ lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL, NULL)) && - (config->flags & CONFIG_NAME) && - (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr)) - lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL); -diff --git a/src/option.c b/src/option.c -index 61cfb8c..d61c5f7 100644 ---- a/src/option.c -+++ b/src/option.c -@@ -3132,9 +3132,10 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma - } - else if (strstr(arg, "tag:") == arg) - { -- -- dhcp_config_free(new); -- ret_err(_("cannot match tags in --dhcp-host")); -+ struct dhcp_netid *newtag = opt_malloc(sizeof (struct dhcp_netid)); -+ newtag->net = opt_string_alloc(arg+4); -+ newtag->next = new->filter; -+ new->filter = newtag; - } - #ifdef HAVE_DHCP6 - else if (arg[0] == '[' && arg[strlen(arg)-1] == ']') -diff --git a/src/rfc2131.c b/src/rfc2131.c -index 56dc3d1..924a960 100644 ---- a/src/rfc2131.c -+++ b/src/rfc2131.c -@@ -479,7 +479,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, - mess->op = BOOTREPLY; - - config = find_config(daemon->dhcp_conf, context, clid, clid_len, -- mess->chaddr, mess->hlen, mess->htype, NULL); -+ mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid)); - - /* set "known" tag for known hosts */ - if (config) -@@ -489,7 +489,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, - netid = &known_id; - } - else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len, -- mess->chaddr, mess->hlen, mess->htype, NULL)) -+ mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid))) - { - known_id.net = "known-othernet"; - known_id.next = netid; -@@ -731,7 +731,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, - to avoid impersonation by name. */ - struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0, - mess->chaddr, mess->hlen, -- mess->htype, hostname); -+ mess->htype, hostname, run_tag_if(netid)); - if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr) - { - config = new; -diff --git a/src/rfc3315.c b/src/rfc3315.c -index a7bf929..e92ce59 100644 ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -488,7 +488,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - - if (state->clid) - { -- config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL); -+ config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)); - - if (have_config(config, CONFIG_NAME)) - { -@@ -513,7 +513,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - /* Search again now we have a hostname. - Only accept configs without CLID here, (it won't match) - to avoid impersonation by name. */ -- struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname); -+ struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags)); - if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr) - config = new; - } -@@ -564,7 +564,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ - ignore = 1; - } - else if (state->clid && -- find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL)) -+ find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, -+ state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) - { - known_id.net = "known-othernet"; - known_id.next = state->tags; --- -2.21.1 - diff --git a/dnsmasq.spec b/dnsmasq.spec index e71610b..b0402f9 100644 --- a/dnsmasq.spec +++ b/dnsmasq.spec @@ -35,14 +35,6 @@ Patch3: dnsmasq-2.78-fips.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1728701 Patch7: dnsmasq-2.80-rh1728701.patch Patch9: dnsmasq-2.80-SIOCGSTAMP.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1810172 -# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=79aba0f10ad0157fb4f48afbbcb03f094caff97a -Patch11: dnsmasq-2.81-prefix-ranges-or-list-of-ipv6-addresses.patch -# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=137286e9baecf6a3ba97722ef1b49c851b531810 -Patch12: dnsmasq-2.81-Extend-79aba0f10ad0157fb4f48afbbcb03f094caff97a.patch -Patch13: dnsmasq-2.81-adjust-changes-to-version-2.80.patch -# http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=52ec7836139e7a11374971905e5ac0d2d02e32c0 -Patch14: dnsmasq-2.81-tag-filtering-of-dhcp-host-directives.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1647464 # http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=29ae3083981ea82f535f77ea54bbd538f1224a9e Patch15: dnsmasq-2.81-restore-ability-to-answer-non-recursive-requests.patch