dnsmasq/dnsmasq-2.81-Extend-79aba0f10ad0157fb4f48afbbcb03f094caff97a.patch
Petr Menšík cde7b60662 Support multiple static leases for single mac on IPv6 (#1810172)
In some cases, DUID will change for the same machine during network
boot. Support assigning small blocks of IPv6 addresses to work around
changing DUID.
2020-03-06 22:44:46 +01:00

761 lines
21 KiB
Diff

From c491296241396d0144750f178ffd5c0e0b089a80 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
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