diff options
author | Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 2019-08-03 20:55:52 +0100 |
---|---|---|
committer | Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | 2019-08-03 20:55:52 +0100 |
commit | fc5d46dc62285ff16deae26818764eafce17f0a6 (patch) | |
tree | 3e774451ab444ad0232dcedae26efbcc5efbab56 /package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch | |
parent | a2754667291bef7e2e5f003e0f9c3296dcfd1959 (diff) |
Revert "dnsmasq: backport latest patches"
This reverts commit e9eec39aacde450ba87598d85987b374ce6aed95.
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Diffstat (limited to 'package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch')
-rw-r--r-- | package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch | 626 |
1 files changed, 0 insertions, 626 deletions
diff --git a/package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch b/package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch deleted file mode 100644 index 637a027f6b..0000000000 --- a/package/network/services/dnsmasq/patches/0046-Add-shared-network-DHCP-configuration.patch +++ /dev/null @@ -1,626 +0,0 @@ -From ae5b7e04a1025167f1b80840e61432a3cea9625c Mon Sep 17 00:00:00 2001 -From: Simon Kelley <simon@thekelleys.org.uk> -Date: Wed, 27 Mar 2019 22:33:28 +0000 -Subject: [PATCH 46/57] Add --shared-network DHCP configuration. - -Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> ---- - CHANGELOG | 5 ++ - man/dnsmasq.8 | 21 ++++++ - src/dhcp.c | 76 ++++++++++++++++++---- - src/dhcp6.c | 175 ++++++++++++++++++++++++++++---------------------- - src/dnsmasq.h | 11 ++++ - src/option.c | 41 ++++++++++++ - src/rfc2131.c | 97 +++++++++++++++++----------- - src/rfc3315.c | 40 +++++++++--- - 8 files changed, 332 insertions(+), 134 deletions(-) - ---- a/CHANGELOG -+++ b/CHANGELOG -@@ -34,6 +34,11 @@ version 2.81 - tries not to request capabilities not required by its - configuration. - -+ Add --shared-network config. This enables allocation of addresses -+ the DHCP server in subnets where the server (or relay) doesn't -+ have an interface on the network in that subnet. Many thanks to -+ plank.de for sponsoring this feature. -+ - - version 2.80 - Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method ---- a/man/dnsmasq.8 -+++ b/man/dnsmasq.8 -@@ -1741,6 +1741,27 @@ It is permissible to add more than one a - \fB--bridge-interface=int1,alias1,alias2\fP is exactly equivalent to - \fB--bridge-interface=int1,alias1 --bridge-interface=int1,alias2\fP - .TP -+.B --shared-network=<interface>|<addr>,<addr> -+The DHCP server determines which dhcp ranges are useable for allocating and -+address to a DHCP client based on the network from which the DHCP request arrives, -+and the IP configuration of the server's interface on that network. The shared-network -+option extends the available subnets (and therefore dhcp ranges) beyond the -+subnets configured on the arrival interface. The first argument is either the -+name of an interface or an address which is configured on a local interface, and the -+second argument is an address which defines another subnet on which addresses can be allocated. -+To be useful, there must be suitable dhcp-range which allows address allocation on this subnet -+and this dhcp-range MUST include the netmask. Use shared-network also needs extra -+consideration of routing. Dnsmasq doesn't have the usual information which it uses to -+determine the default route, so the default route option (or other routing) MUST be -+manually configured. The client must have a route to the server: if the two-address form -+of shared-network is used, this will be to the first specified address. If the interface,address -+form is used, there must be a route to all of the addresses configured on the interface. -+ -+The two-address form of shared-network is also usable with a DHCP relay: the first address -+is the address of the relay and the second, as before, specifies an extra subnet which -+may be allocated. -+ -+.TP - .B \-s, --domain=<domain>[,<address range>[,local]] - Specifies DNS domains for the DHCP server. Domains may be be given - unconditionally (without the IP range) or for limited IP ranges. This has two effects; ---- a/src/dhcp.c -+++ b/src/dhcp.c -@@ -507,33 +507,83 @@ static int check_listen_addrs(struct in_ - - Note that the current chain may be superseded later for configured hosts or those coming via gateways. */ - --static int complete_context(struct in_addr local, int if_index, char *label, -- struct in_addr netmask, struct in_addr broadcast, void *vparam) -+static void guess_range_netmask(struct in_addr addr, struct in_addr netmask) - { - struct dhcp_context *context; -- struct dhcp_relay *relay; -- struct iface_param *param = vparam; - -- (void)label; -- - for (context = daemon->dhcp; context; context = context->next) -- { -- if (!(context->flags & CONTEXT_NETMASK) && -- (is_same_net(local, context->start, netmask) || -- is_same_net(local, context->end, netmask))) -+ if (!(context->flags & CONTEXT_NETMASK) && -+ (is_same_net(addr, context->start, netmask) || -+ is_same_net(addr, context->end, netmask))) - { - if (context->netmask.s_addr != netmask.s_addr && -- !(is_same_net(local, context->start, netmask) && -- is_same_net(local, context->end, netmask))) -+ !(is_same_net(addr, context->start, netmask) && -+ is_same_net(addr, context->end, netmask))) - { - strcpy(daemon->dhcp_buff, inet_ntoa(context->start)); - strcpy(daemon->dhcp_buff2, inet_ntoa(context->end)); - my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"), - daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask)); - } -- context->netmask = netmask; -+ context->netmask = netmask; - } -+} -+ -+static int complete_context(struct in_addr local, int if_index, char *label, -+ struct in_addr netmask, struct in_addr broadcast, void *vparam) -+{ -+ struct dhcp_context *context; -+ struct dhcp_relay *relay; -+ struct iface_param *param = vparam; -+ struct shared_network *share; -+ -+ (void)label; -+ -+ for (share = daemon->shared_networks; share; share = share->next) -+ { - -+#ifdef HAVE_DHCP6 -+ if (share->shared_addr.s_addr == 0) -+ continue; -+#endif -+ -+ if (share->if_index != 0) -+ { -+ if (share->if_index != if_index) -+ continue; -+ } -+ else -+ { -+ if (share->match_addr.s_addr != local.s_addr) -+ continue; -+ } -+ -+ for (context = daemon->dhcp; context; context = context->next) -+ { -+ if (context->netmask.s_addr != 0 && -+ is_same_net(share->shared_addr, context->start, context->netmask) && -+ is_same_net(share->shared_addr, context->end, context->netmask)) -+ { -+ /* link it onto the current chain if we've not seen it before */ -+ if (context->current == context) -+ { -+ /* For a shared network, we have no way to guess what the default route should be. */ -+ context->router.s_addr = 0; -+ context->local = local; /* Use configured address for Server Identifier */ -+ context->current = param->current; -+ param->current = context; -+ } -+ -+ if (!(context->flags & CONTEXT_BRDCAST)) -+ context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr; -+ } -+ } -+ } -+ -+ guess_range_netmask(local, netmask); -+ -+ for (context = daemon->dhcp; context; context = context->next) -+ { - if (context->netmask.s_addr != 0 && - is_same_net(local, context->start, context->netmask) && - is_same_net(local, context->end, context->netmask)) ---- a/src/dhcp6.c -+++ b/src/dhcp6.c -@@ -299,89 +299,114 @@ static int complete_context6(struct in6_ - unsigned int valid, void *vparam) - { - struct dhcp_context *context; -+ struct shared_network *share; - struct dhcp_relay *relay; - struct iface_param *param = vparam; - struct iname *tmp; - - (void)scope; /* warning */ - -- if (if_index == param->ind) -- { -- if (IN6_IS_ADDR_LINKLOCAL(local)) -- param->ll_addr = *local; -- else if (IN6_IS_ADDR_ULA(local)) -- param->ula_addr = *local; -- -- if (!IN6_IS_ADDR_LOOPBACK(local) && -- !IN6_IS_ADDR_LINKLOCAL(local) && -- !IN6_IS_ADDR_MULTICAST(local)) -- { -- /* if we have --listen-address config, see if the -- arrival interface has a matching address. */ -- for (tmp = daemon->if_addrs; tmp; tmp = tmp->next) -- if (tmp->addr.sa.sa_family == AF_INET6 && -- IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local)) -- param->addr_match = 1; -- -- /* Determine a globally address on the arrival interface, even -- if we have no matching dhcp-context, because we're only -- allocating on remote subnets via relays. This -- is used as a default for the DNS server option. */ -- param->fallback = *local; -- -- for (context = daemon->dhcp6; context; context = context->next) -- { -- if ((context->flags & CONTEXT_DHCP) && -- !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && -- prefix <= context->prefix && -- is_same_net6(local, &context->start6, context->prefix) && -- is_same_net6(local, &context->end6, context->prefix)) -- { -- -- -- /* link it onto the current chain if we've not seen it before */ -- if (context->current == context) -- { -- struct dhcp_context *tmp, **up; -- -- /* use interface values only for constructed contexts */ -- if (!(context->flags & CONTEXT_CONSTRUCTED)) -- preferred = valid = 0xffffffff; -- else if (flags & IFACE_DEPRECATED) -- preferred = 0; -- -- if (context->flags & CONTEXT_DEPRECATE) -- preferred = 0; -- -- /* order chain, longest preferred time first */ -- for (up = ¶m->current, tmp = param->current; tmp; tmp = tmp->current) -- if (tmp->preferred <= preferred) -- break; -- else -- up = &tmp->current; -- -- context->current = *up; -- *up = context; -- context->local6 = *local; -- context->preferred = preferred; -- context->valid = valid; -- } -- } -- } -- } -- -- for (relay = daemon->relay6; relay; relay = relay->next) -- if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay && -- (IN6_IS_ADDR_UNSPECIFIED(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->relay_local))) -+ if (if_index != param->ind) -+ return 1; -+ -+ if (IN6_IS_ADDR_LINKLOCAL(local)) -+ param->ll_addr = *local; -+ else if (IN6_IS_ADDR_ULA(local)) -+ param->ula_addr = *local; -+ -+ if (IN6_IS_ADDR_LOOPBACK(local) || -+ IN6_IS_ADDR_LINKLOCAL(local) || -+ IN6_IS_ADDR_MULTICAST(local)) -+ return 1; -+ -+ /* if we have --listen-address config, see if the -+ arrival interface has a matching address. */ -+ for (tmp = daemon->if_addrs; tmp; tmp = tmp->next) -+ if (tmp->addr.sa.sa_family == AF_INET6 && -+ IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local)) -+ param->addr_match = 1; -+ -+ /* Determine a globally address on the arrival interface, even -+ if we have no matching dhcp-context, because we're only -+ allocating on remote subnets via relays. This -+ is used as a default for the DNS server option. */ -+ param->fallback = *local; -+ -+ for (context = daemon->dhcp6; context; context = context->next) -+ if ((context->flags & CONTEXT_DHCP) && -+ !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && -+ prefix <= context->prefix && -+ context->current == context) -+ { -+ if (is_same_net6(local, &context->start6, context->prefix) && -+ is_same_net6(local, &context->end6, context->prefix)) - { -- relay->current = param->relay; -- param->relay = relay; -- param->relay_local = *local; -+ struct dhcp_context *tmp, **up; -+ -+ /* use interface values only for constructed contexts */ -+ if (!(context->flags & CONTEXT_CONSTRUCTED)) -+ preferred = valid = 0xffffffff; -+ else if (flags & IFACE_DEPRECATED) -+ preferred = 0; -+ -+ if (context->flags & CONTEXT_DEPRECATE) -+ preferred = 0; -+ -+ /* order chain, longest preferred time first */ -+ for (up = ¶m->current, tmp = param->current; tmp; tmp = tmp->current) -+ if (tmp->preferred <= preferred) -+ break; -+ else -+ up = &tmp->current; -+ -+ context->current = *up; -+ *up = context; -+ context->local6 = *local; -+ context->preferred = preferred; -+ context->valid = valid; - } -- -- } -- -- return 1; -+ else -+ { -+ for (share = daemon->shared_networks; share; share = share->next) -+ { -+ /* IPv4 shared_address - ignore */ -+ if (share->shared_addr.s_addr != 0) -+ continue; -+ -+ if (share->if_index != 0) -+ { -+ if (share->if_index != if_index) -+ continue; -+ } -+ else -+ { -+ if (!IN6_ARE_ADDR_EQUAL(&share->match_addr6, local)) -+ continue; -+ } -+ -+ if (is_same_net6(&share->shared_addr6, &context->start6, context->prefix) && -+ is_same_net6(&share->shared_addr6, &context->end6, context->prefix)) -+ { -+ context->current = param->current; -+ param->current = context; -+ context->local6 = *local; -+ context->preferred = context->flags & CONTEXT_DEPRECATE ? 0 :0xffffffff; -+ context->valid = 0xffffffff; -+ } -+ } -+ } -+ } -+ -+ for (relay = daemon->relay6; relay; relay = relay->next) -+ if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay && -+ (IN6_IS_ADDR_UNSPECIFIED(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->relay_local))) -+ { -+ relay->current = param->relay; -+ param->relay = relay; -+ param->relay_local = *local; -+ } -+ -+ return 1; - } - - struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr) ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -910,6 +910,16 @@ struct dhcp_context { - struct dhcp_context *next, *current; - }; - -+struct shared_network { -+ int if_index; -+ struct in_addr match_addr, shared_addr; -+#ifdef HAVE_DHCP6 -+ /* shared_addr == 0 for IP6 entries. */ -+ struct in6_addr match_addr6, shared_addr6; -+#endif -+ struct shared_network *next; -+}; -+ - #define CONTEXT_STATIC (1u<<0) - #define CONTEXT_NETMASK (1u<<1) - #define CONTEXT_BRDCAST (1u<<2) -@@ -1107,6 +1117,7 @@ extern struct daemon { - struct ping_result *ping_results; - FILE *lease_stream; - struct dhcp_bridge *bridges; -+ struct shared_network *shared_networks; - #ifdef HAVE_DHCP6 - int duid_len; - unsigned char *duid; ---- a/src/option.c -+++ b/src/option.c -@@ -166,6 +166,7 @@ struct myoption { - #define LOPT_UBUS 354 - #define LOPT_NAME_MATCH 355 - #define LOPT_CAA 356 -+#define LOPT_SHARED_NET 357 - - #ifdef HAVE_GETOPT_LONG - static const struct option opts[] = -@@ -259,6 +260,7 @@ static const struct myoption opts[] = - { "ptr-record", 1, 0, LOPT_PTR }, - { "naptr-record", 1, 0, LOPT_NAPTR }, - { "bridge-interface", 1, 0 , LOPT_BRIDGE }, -+ { "shared-network", 1, 0, LOPT_SHARED_NET }, - { "dhcp-option-force", 1, 0, LOPT_FORCE }, - { "tftp-no-blocksize", 0, 0, LOPT_NOBLOCK }, - { "log-dhcp", 0, 0, LOPT_LOG_OPTS }, -@@ -431,6 +433,7 @@ static struct { - { '3', ARG_DUP, "[=tag:<tag>]...", gettext_noop("Enable dynamic address allocation for bootp."), NULL }, - { '4', ARG_DUP, "set:<tag>,<mac address>", gettext_noop("Map MAC address (with wildcards) to option set."), NULL }, - { LOPT_BRIDGE, ARG_DUP, "<iface>,<alias>..", gettext_noop("Treat DHCP requests on aliases as arriving from interface."), NULL }, -+ { LOPT_SHARED_NET, ARG_DUP, "<iface>|<addr>,<addr>", gettext_noop("Specify extra networks sharing a broadcast domain for DHCP"), NULL}, - { '5', OPT_NO_PING, NULL, gettext_noop("Disable ICMP echo address checking in the DHCP server."), NULL }, - { '6', ARG_ONE, "<path>", gettext_noop("Shell script to run on DHCP lease creation and destruction."), NULL }, - { LOPT_LUASCRIPT, ARG_DUP, "path", gettext_noop("Lua script to run on DHCP lease creation and destruction."), NULL }, -@@ -2873,6 +2876,44 @@ static int one_opt(int option, char *arg - } - - #ifdef HAVE_DHCP -+ case LOPT_SHARED_NET: /* --shared-network */ -+ { -+ struct shared_network *new = opt_malloc(sizeof(struct shared_network)); -+ -+#ifdef HAVE_DHCP6 -+ new->shared_addr.s_addr = 0; -+#endif -+ new->if_index = 0; -+ -+ if (!(comma = split(arg))) -+ { -+ snerr: -+ free(new); -+ ret_err(_("bad shared-network")); -+ } -+ -+ if (inet_pton(AF_INET, comma, &new->shared_addr)) -+ { -+ if (!inet_pton(AF_INET, arg, &new->match_addr) && -+ !(new->if_index = if_nametoindex(arg))) -+ goto snerr; -+ } -+#ifdef HAVE_DHCP6 -+ else if (inet_pton(AF_INET6, comma, &new->shared_addr6)) -+ { -+ if (!inet_pton(AF_INET6, arg, &new->match_addr6) && -+ !(new->if_index = if_nametoindex(arg))) -+ goto snerr; -+ } -+#endif -+ else -+ goto snerr; -+ -+ new->next = daemon->shared_networks; -+ daemon->shared_networks = new; -+ break; -+ } -+ - case 'F': /* --dhcp-range */ - { - int k, leasepos = 2; ---- a/src/rfc2131.c -+++ b/src/rfc2131.c -@@ -274,8 +274,9 @@ size_t dhcp_reply(struct dhcp_context *c - if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr) - { - struct dhcp_context *context_tmp, *context_new = NULL; -+ struct shared_network *share = NULL; - struct in_addr addr; -- int force = 0; -+ int force = 0, via_relay = 0; - - if (subnet_addr.s_addr) - { -@@ -286,6 +287,7 @@ size_t dhcp_reply(struct dhcp_context *c - { - addr = mess->giaddr; - force = 1; -+ via_relay = 1; - } - else - { -@@ -302,42 +304,65 @@ size_t dhcp_reply(struct dhcp_context *c - } - - if (!context_new) -- for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next) -- { -- struct in_addr netmask = context_tmp->netmask; -+ { -+ for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next) -+ { -+ struct in_addr netmask = context_tmp->netmask; -+ -+ /* guess the netmask for relayed networks */ -+ if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0) -+ { -+ if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr))) -+ netmask.s_addr = htonl(0xff000000); -+ else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr))) -+ netmask.s_addr = htonl(0xffff0000); -+ else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr))) -+ netmask.s_addr = htonl(0xffffff00); -+ } - -- /* guess the netmask for relayed networks */ -- if (!(context_tmp->flags & CONTEXT_NETMASK) && context_tmp->netmask.s_addr == 0) -- { -- if (IN_CLASSA(ntohl(context_tmp->start.s_addr)) && IN_CLASSA(ntohl(context_tmp->end.s_addr))) -- netmask.s_addr = htonl(0xff000000); -- else if (IN_CLASSB(ntohl(context_tmp->start.s_addr)) && IN_CLASSB(ntohl(context_tmp->end.s_addr))) -- netmask.s_addr = htonl(0xffff0000); -- else if (IN_CLASSC(ntohl(context_tmp->start.s_addr)) && IN_CLASSC(ntohl(context_tmp->end.s_addr))) -- netmask.s_addr = htonl(0xffffff00); -- } -- -- /* This section fills in context mainly when a client which is on a remote (relayed) -- network renews a lease without using the relay, after dnsmasq has restarted. */ -- if (netmask.s_addr != 0 && -- is_same_net(addr, context_tmp->start, netmask) && -- is_same_net(addr, context_tmp->end, netmask)) -- { -- context_tmp->netmask = netmask; -- if (context_tmp->local.s_addr == 0) -- context_tmp->local = fallback; -- if (context_tmp->router.s_addr == 0) -- context_tmp->router = mess->giaddr; -- -- /* fill in missing broadcast addresses for relayed ranges */ -- if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 ) -- context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr; -- -- context_tmp->current = context_new; -- context_new = context_tmp; -- } -- } -- -+ /* check to see is a context is OK because of a shared address on -+ the relayed subnet. */ -+ if (via_relay) -+ for (share = daemon->shared_networks; share; share = share->next) -+ { -+#ifdef HAVE_DHCP6 -+ if (share->shared_addr.s_addr == 0) -+ continue; -+#endif -+ if (share->if_index != 0 || -+ share->match_addr.s_addr != mess->giaddr.s_addr) -+ continue; -+ -+ if (netmask.s_addr != 0 && -+ is_same_net(share->shared_addr, context_tmp->start, netmask) && -+ is_same_net(share->shared_addr, context_tmp->end, netmask)) -+ break; -+ } -+ -+ /* This section fills in context mainly when a client which is on a remote (relayed) -+ network renews a lease without using the relay, after dnsmasq has restarted. */ -+ if (share || -+ (netmask.s_addr != 0 && -+ is_same_net(addr, context_tmp->start, netmask) && -+ is_same_net(addr, context_tmp->end, netmask))) -+ { -+ context_tmp->netmask = netmask; -+ if (context_tmp->local.s_addr == 0) -+ context_tmp->local = fallback; -+ if (context_tmp->router.s_addr == 0 && !share) -+ context_tmp->router = mess->giaddr; -+ -+ /* fill in missing broadcast addresses for relayed ranges */ -+ if (!(context_tmp->flags & CONTEXT_BRDCAST) && context_tmp->broadcast.s_addr == 0 ) -+ context_tmp->broadcast.s_addr = context_tmp->start.s_addr | ~context_tmp->netmask.s_addr; -+ -+ context_tmp->current = context_new; -+ context_new = context_tmp; -+ } -+ -+ } -+ } -+ - if (context_new || force) - context = context_new; - } ---- a/src/rfc3315.c -+++ b/src/rfc3315.c -@@ -134,21 +134,41 @@ static int dhcp6_maybe_relay(struct stat - else - { - struct dhcp_context *c; -+ struct shared_network *share = NULL; - state->context = NULL; -- -+ - if (!IN6_IS_ADDR_LOOPBACK(state->link_address) && - !IN6_IS_ADDR_LINKLOCAL(state->link_address) && - !IN6_IS_ADDR_MULTICAST(state->link_address)) - for (c = daemon->dhcp6; c; c = c->next) -- if ((c->flags & CONTEXT_DHCP) && -- !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && -- is_same_net6(state->link_address, &c->start6, c->prefix) && -- is_same_net6(state->link_address, &c->end6, c->prefix)) -- { -- c->preferred = c->valid = 0xffffffff; -- c->current = state->context; -- state->context = c; -- } -+ { -+ for (share = daemon->shared_networks; share; share = share->next) -+ { -+ if (share->shared_addr.s_addr != 0) -+ continue; -+ -+ if (share->if_index != 0 || -+ !IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6)) -+ continue; -+ -+ if ((c->flags & CONTEXT_DHCP) && -+ !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && -+ is_same_net6(&share->shared_addr6, &c->start6, c->prefix) && -+ is_same_net6(&share->shared_addr6, &c->end6, c->prefix)) -+ break; -+ } -+ -+ if (share || -+ ((c->flags & CONTEXT_DHCP) && -+ !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && -+ is_same_net6(state->link_address, &c->start6, c->prefix) && -+ is_same_net6(state->link_address, &c->end6, c->prefix))) -+ { -+ c->preferred = c->valid = 0xffffffff; -+ c->current = state->context; -+ state->context = c; -+ } -+ } - - if (!state->context) - { |