summaryrefslogtreecommitdiffstats
path: root/src/ipv6.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-03-31 22:33:25 +0100
committerRoy Marples <roy@marples.name>2020-03-31 22:33:25 +0100
commit67d90035be1ec5286de30b9e50094cae9223b83f (patch)
tree5a2adcb16bce8e578e7f247b25aa0e014377dadf /src/ipv6.c
parent93df4147ea44a8b6adb439dff48c5647e5ffb9d0 (diff)
downloaddhcpcd-67d90035be1ec5286de30b9e50094cae9223b83f.tar.xz
ND: If a secondary router adds the same prefix, use it's address
With slaac private, it will generate a new address which would be wrong.
Diffstat (limited to 'src/ipv6.c')
-rw-r--r--src/ipv6.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/ipv6.c b/src/ipv6.c
index 000db984..51b4c9b7 100644
--- a/src/ipv6.c
+++ b/src/ipv6.c
@@ -1509,17 +1509,26 @@ struct ipv6_addr *
ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
uint8_t prefix_len, unsigned int flags)
{
- struct ipv6_addr *ia;
+ struct ipv6_addr *ia, *iaf;
char buf[INET6_ADDRSTRLEN];
const char *cbp;
bool tempaddr;
int addr_flags;
+#ifdef IPV6_AF_TEMPORARY
+ tempaddr = flags & IPV6_AF_TEMPORARY;
+#else
+ tempaddr = false;
+#endif
+
/* If adding a new DHCP / RA derived address, check current flags
* from an existing address. */
- ia = ipv6_iffindaddr(ifp, addr, 0);
- if (ia != NULL) {
- addr_flags = ia->addr_flags;
+ if (flags & IPV6_AF_AUTOCONF)
+ iaf = ipv6nd_iffindprefix(ifp, addr, prefix_len);
+ else
+ iaf = ipv6_iffindaddr(ifp, addr, 0);
+ if (iaf != NULL) {
+ addr_flags = iaf->addr_flags;
flags |= IPV6_AF_ADDED;
} else
addr_flags = IN6_IFF_TENTATIVE;
@@ -1540,21 +1549,19 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr,
TAILQ_INIT(&ia->pd_pfxs);
#endif
-#ifdef IPV6_AF_TEMPORARY
- tempaddr = ia->flags & IPV6_AF_TEMPORARY;
-#else
- tempaddr = false;
-#endif
-
if (prefix_len == 128)
goto makepfx;
else if (ia->flags & IPV6_AF_AUTOCONF && !tempaddr) {
ia->prefix = *addr;
- ia->dadcounter = ipv6_makeaddr(&ia->addr, ifp,
- &ia->prefix,
- ia->prefix_len);
- if (ia->dadcounter == -1)
- goto err;
+ if (iaf != NULL)
+ memcpy(&ia->addr, &iaf->addr, sizeof(ia->addr));
+ else {
+ ia->dadcounter = ipv6_makeaddr(&ia->addr, ifp,
+ &ia->prefix,
+ ia->prefix_len);
+ if (ia->dadcounter == -1)
+ goto err;
+ }
} else if (ia->flags & IPV6_AF_RAPFX) {
ia->prefix = *addr;
#ifdef __sun