etc/protocols - sync with NetBSD-8
[minix.git] / external / bsd / dhcpcd / dist / ipv6.c
blob434bf546838e2783f4cb8622f83f920b9d2eb79f
1 #include <sys/cdefs.h>
2 __RCSID("$NetBSD: ipv6.c,v 1.14 2015/08/21 10:39:00 roy Exp $");
4 /*
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
7 * All rights reserved
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/stat.h>
36 #include <net/if.h>
37 #include <net/route.h>
38 #include <netinet/in.h>
39 #include <netinet/if_ether.h>
41 #include <errno.h>
42 #include <ifaddrs.h>
43 #include <inttypes.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
48 #define ELOOP_QUEUE 7
49 #include "common.h"
50 #include "if.h"
51 #include "dhcpcd.h"
52 #include "dhcp6.h"
53 #include "eloop.h"
54 #include "ipv6.h"
55 #include "ipv6nd.h"
57 #ifdef HAVE_MD5_H
58 # ifndef DEPGEN
59 # include <md5.h>
60 # endif
61 #else
62 # include "md5.h"
63 #endif
65 #ifdef SHA2_H
66 # include SHA2_H
67 #else
68 # include "sha256.h"
69 #endif
71 #ifndef SHA256_DIGEST_LENGTH
72 # define SHA256_DIGEST_LENGTH 32
73 #endif
75 #ifdef IPV6_POLLADDRFLAG
76 # warning kernel does not report IPv6 address flag changes
77 # warning polling tentative address flags periodically
78 #endif
80 #ifdef __linux__
81 /* Match Linux defines to BSD */
82 # define IN6_IFF_TEMPORARY IFA_F_TEMPORARY
83 # ifdef IFA_F_OPTIMISTIC
84 # define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)
85 # else
86 # define IN6_IFF_TENTATIVE (IFA_F_TENTATIVE | 0x04)
87 # endif
88 # ifdef IF_F_DADFAILED
89 # define IN6_IFF_DUPLICATED IFA_F_DADFAILED
90 # else
91 # define IN6_IFF_DUPLICATED 0x08
92 # endif
93 # define IN6_IFF_DETACHED 0
94 #endif
96 #define IN6_IFF_NOTUSEABLE \
97 (IN6_IFF_TENTATIVE | IN6_IFF_DUPLICATED | IN6_IFF_DETACHED)
99 /* Hackery at it's finest. */
100 #ifndef s6_addr32
101 # ifdef __sun
102 # define s6_addr32 _S6_un._S6_u32
103 # else
104 # define s6_addr32 __u6_addr.__u6_addr32
105 # endif
106 #endif
109 #ifdef IPV6_MANAGETEMPADDR
110 static void ipv6_regentempifid(void *);
111 static void ipv6_regentempaddr(void *);
112 #else
113 #define ipv6_regentempifid(a) {}
114 #endif
116 struct ipv6_ctx *
117 ipv6_init(struct dhcpcd_ctx *dhcpcd_ctx)
119 struct ipv6_ctx *ctx;
121 if (dhcpcd_ctx->ipv6)
122 return dhcpcd_ctx->ipv6;
124 ctx = calloc(1, sizeof(*ctx));
125 if (ctx == NULL)
126 return NULL;
128 ctx->routes = malloc(sizeof(*ctx->routes));
129 if (ctx->routes == NULL) {
130 free(ctx);
131 return NULL;
133 TAILQ_INIT(ctx->routes);
135 ctx->ra_routers = malloc(sizeof(*ctx->ra_routers));
136 if (ctx->ra_routers == NULL) {
137 free(ctx->routes);
138 free(ctx);
139 return NULL;
141 TAILQ_INIT(ctx->ra_routers);
143 TAILQ_INIT(&ctx->kroutes);
145 ctx->sndhdr.msg_namelen = sizeof(struct sockaddr_in6);
146 ctx->sndhdr.msg_iov = ctx->sndiov;
147 ctx->sndhdr.msg_iovlen = 1;
148 ctx->sndhdr.msg_control = ctx->sndbuf;
149 ctx->sndhdr.msg_controllen = sizeof(ctx->sndbuf);
150 ctx->rcvhdr.msg_name = &ctx->from;
151 ctx->rcvhdr.msg_namelen = sizeof(ctx->from);
152 ctx->rcvhdr.msg_iov = ctx->rcviov;
153 ctx->rcvhdr.msg_iovlen = 1;
154 ctx->rcvhdr.msg_control = ctx->rcvbuf;
155 // controllen is set at recieve
156 //ctx->rcvhdr.msg_controllen = sizeof(ctx->rcvbuf);
157 ctx->rcviov[0].iov_base = ctx->ansbuf;
158 ctx->rcviov[0].iov_len = sizeof(ctx->ansbuf);
160 ctx->nd_fd = -1;
161 ctx->dhcp_fd = -1;
163 dhcpcd_ctx->ipv6 = ctx;
165 return ctx;
168 ssize_t
169 ipv6_printaddr(char *s, size_t sl, const uint8_t *d, const char *ifname)
171 char buf[INET6_ADDRSTRLEN];
172 const char *p;
173 size_t l;
175 p = inet_ntop(AF_INET6, d, buf, sizeof(buf));
176 if (p == NULL)
177 return -1;
179 l = strlen(p);
180 if (d[0] == 0xfe && (d[1] & 0xc0) == 0x80)
181 l += 1 + strlen(ifname);
183 if (s == NULL)
184 return (ssize_t)l;
186 if (sl < l) {
187 errno = ENOMEM;
188 return -1;
191 s += strlcpy(s, p, sl);
192 if (d[0] == 0xfe && (d[1] & 0xc0) == 0x80) {
193 *s++ = '%';
194 s += strlcpy(s, ifname, sl);
196 *s = '\0';
197 return (ssize_t)l;
200 static ssize_t
201 ipv6_readsecret(struct dhcpcd_ctx *ctx)
203 FILE *fp;
204 char line[1024];
205 unsigned char *p;
206 size_t len;
207 uint32_t r;
208 int x;
210 if ((fp = fopen(SECRET, "r"))) {
211 len = 0;
212 while (fgets(line, sizeof(line), fp)) {
213 len = strlen(line);
214 if (len) {
215 if (line[len - 1] == '\n')
216 line[len - 1] = '\0';
218 len = hwaddr_aton(NULL, line);
219 if (len) {
220 ctx->secret_len = hwaddr_aton(ctx->secret,
221 line);
222 break;
224 len = 0;
226 fclose(fp);
227 if (len)
228 return (ssize_t)len;
229 } else {
230 if (errno != ENOENT)
231 logger(ctx, LOG_ERR,
232 "error reading secret: %s: %m", SECRET);
235 /* Chaining arc4random should be good enough.
236 * RFC7217 section 5.1 states the key SHOULD be at least 128 bits.
237 * To attempt and future proof ourselves, we'll generate a key of
238 * 512 bits (64 bytes). */
239 p = ctx->secret;
240 ctx->secret_len = 0;
241 for (len = 0; len < 512 / NBBY; len += sizeof(r)) {
242 r = arc4random();
243 memcpy(p, &r, sizeof(r));
244 p += sizeof(r);
245 ctx->secret_len += sizeof(r);
249 /* Ensure that only the dhcpcd user can read the secret.
250 * Write permission is also denied as chaning it would remove
251 * it's stability. */
252 if ((fp = fopen(SECRET, "w")) == NULL ||
253 chmod(SECRET, S_IRUSR) == -1)
254 goto eexit;
255 x = fprintf(fp, "%s\n",
256 hwaddr_ntoa(ctx->secret, ctx->secret_len, line, sizeof(line)));
257 if (fclose(fp) == EOF)
258 x = -1;
259 if (x > 0)
260 return (ssize_t)ctx->secret_len;
262 eexit:
263 logger(ctx, LOG_ERR, "error writing secret: %s: %m", SECRET);
264 unlink(SECRET);
265 ctx->secret_len = 0;
266 return -1;
269 /* http://www.iana.org/assignments/ipv6-interface-ids/ipv6-interface-ids.xhtml
270 * RFC5453 */
271 static const struct reslowhigh {
272 const uint8_t high[8];
273 const uint8_t low[8];
274 } reslowhigh[] = {
275 /* RFC4291 + RFC6543 */
276 { { 0x02, 0x00, 0x5e, 0xff, 0xfe, 0x00, 0x00, 0x00 },
277 { 0x02, 0x00, 0x5e, 0xff, 0xfe, 0xff, 0xff, 0xff } },
278 /* RFC2526 */
279 { { 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 },
280 { 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }
283 static int
284 ipv6_reserved(const struct in6_addr *addr)
286 uint64_t id, low, high;
287 size_t i;
288 const struct reslowhigh *r;
290 id = be64dec(addr->s6_addr + sizeof(id));
291 if (id == 0) /* RFC4291 */
292 return 1;
293 for (i = 0; i < sizeof(reslowhigh) / sizeof(reslowhigh[0]); i++) {
294 r = &reslowhigh[i];
295 low = be64dec(r->low);
296 high = be64dec(r->high);
297 if (id >= low && id <= high)
298 return 1;
300 return 0;
303 /* RFC7217 */
304 static int
305 ipv6_makestableprivate1(struct in6_addr *addr,
306 const struct in6_addr *prefix, int prefix_len,
307 const unsigned char *netiface, size_t netiface_len,
308 const unsigned char *netid, size_t netid_len,
309 uint32_t *dad_counter,
310 const unsigned char *secret, size_t secret_len)
312 unsigned char buf[2048], *p, digest[SHA256_DIGEST_LENGTH];
313 size_t len, l;
314 SHA256_CTX ctx;
316 if (prefix_len < 0 || prefix_len > 120) {
317 errno = EINVAL;
318 return -1;
321 l = (size_t)(ROUNDUP8(prefix_len) / NBBY);
322 len = l + netiface_len + netid_len + sizeof(*dad_counter) + secret_len;
323 if (len > sizeof(buf)) {
324 errno = ENOBUFS;
325 return -1;
328 for (;; (*dad_counter)++) {
329 /* Combine all parameters into one buffer */
330 p = buf;
331 memcpy(p, prefix, l);
332 p += l;
333 memcpy(p, netiface, netiface_len);
334 p += netiface_len;
335 memcpy(p, netid, netid_len);
336 p += netid_len;
337 memcpy(p, dad_counter, sizeof(*dad_counter));
338 p += sizeof(*dad_counter);
339 memcpy(p, secret, secret_len);
341 /* Make an address using the digest of the above.
342 * RFC7217 Section 5.1 states that we shouldn't use MD5.
343 * Pity as we use that for HMAC-MD5 which is still deemed OK.
344 * SHA-256 is recommended */
345 SHA256_Init(&ctx);
346 SHA256_Update(&ctx, buf, len);
347 SHA256_Final(digest, &ctx);
349 p = addr->s6_addr;
350 memcpy(p, prefix, l);
351 /* RFC7217 section 5.2 says we need to start taking the id from
352 * the least significant bit */
353 len = sizeof(addr->s6_addr) - l;
354 memcpy(p + l, digest + (sizeof(digest) - len), len);
356 /* Ensure that the Interface ID does not match a reserved one,
357 * if it does then treat it as a DAD failure.
358 * RFC7217 section 5.2 */
359 if (prefix_len != 64)
360 break;
361 if (!ipv6_reserved(addr))
362 break;
365 return 0;
369 ipv6_makestableprivate(struct in6_addr *addr,
370 const struct in6_addr *prefix, int prefix_len,
371 const struct interface *ifp,
372 int *dad_counter)
374 uint32_t dad;
375 int r;
377 dad = (uint32_t)*dad_counter;
379 /* For our implementation, we shall set the hardware address
380 * as the interface identifier */
381 r = ipv6_makestableprivate1(addr, prefix, prefix_len,
382 ifp->hwaddr, ifp->hwlen,
383 ifp->ssid, ifp->ssid_len,
384 &dad,
385 ifp->ctx->secret, ifp->ctx->secret_len);
387 if (r == 0)
388 *dad_counter = (int)dad;
389 return r;
393 ipv6_makeaddr(struct in6_addr *addr, const struct interface *ifp,
394 const struct in6_addr *prefix, int prefix_len)
396 const struct ipv6_addr *ap;
397 int dad;
399 if (prefix_len < 0 || prefix_len > 120) {
400 errno = EINVAL;
401 return -1;
404 if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
405 if (ifp->ctx->secret_len == 0) {
406 if (ipv6_readsecret(ifp->ctx) == -1)
407 return -1;
409 dad = 0;
410 if (ipv6_makestableprivate(addr,
411 prefix, prefix_len, ifp, &dad) == -1)
412 return -1;
413 return dad;
416 if (prefix_len > 64) {
417 errno = EINVAL;
418 return -1;
420 if ((ap = ipv6_linklocal(ifp)) == NULL) {
421 /* We delay a few functions until we get a local-link address
422 * so this should never be hit. */
423 errno = ENOENT;
424 return -1;
427 /* Make the address from the first local-link address */
428 memcpy(addr, prefix, sizeof(*prefix));
429 addr->s6_addr32[2] = ap->addr.s6_addr32[2];
430 addr->s6_addr32[3] = ap->addr.s6_addr32[3];
431 return 0;
435 ipv6_makeprefix(struct in6_addr *prefix, const struct in6_addr *addr, int len)
437 int bytelen, bitlen;
439 if (len < 0 || len > 128) {
440 errno = EINVAL;
441 return -1;
444 bytelen = len / NBBY;
445 bitlen = len % NBBY;
446 memcpy(&prefix->s6_addr, &addr->s6_addr, (size_t)bytelen);
447 if (bitlen != 0)
448 prefix->s6_addr[bytelen] =
449 (uint8_t)(prefix->s6_addr[bytelen] >> (NBBY - bitlen));
450 memset((char *)prefix->s6_addr + bytelen, 0,
451 sizeof(prefix->s6_addr) - (size_t)bytelen);
452 return 0;
456 ipv6_mask(struct in6_addr *mask, int len)
458 static const unsigned char masks[NBBY] =
459 { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
460 int bytes, bits, i;
462 if (len < 0 || len > 128) {
463 errno = EINVAL;
464 return -1;
467 memset(mask, 0, sizeof(*mask));
468 bytes = len / NBBY;
469 bits = len % NBBY;
470 for (i = 0; i < bytes; i++)
471 mask->s6_addr[i] = 0xff;
472 if (bits)
473 mask->s6_addr[bytes] = masks[bits - 1];
474 return 0;
477 uint8_t
478 ipv6_prefixlen(const struct in6_addr *mask)
480 int x = 0, y;
481 const unsigned char *lim, *p;
483 lim = (const unsigned char *)mask + sizeof(*mask);
484 for (p = (const unsigned char *)mask; p < lim; x++, p++) {
485 if (*p != 0xff)
486 break;
488 y = 0;
489 if (p < lim) {
490 for (y = 0; y < NBBY; y++) {
491 if ((*p & (0x80 >> y)) == 0)
492 break;
497 * when the limit pointer is given, do a stricter check on the
498 * remaining bits.
500 if (p < lim) {
501 if (y != 0 && (*p & (0x00ff >> y)) != 0)
502 return 0;
503 for (p = p + 1; p < lim; p++)
504 if (*p != 0)
505 return 0;
508 return (uint8_t)(x * NBBY + y);
511 static void
512 in6_to_h64(uint64_t *vhigh, uint64_t *vlow, const struct in6_addr *addr)
515 *vhigh = be64dec(addr->s6_addr);
516 *vlow = be64dec(addr->s6_addr + 8);
519 static void
520 h64_to_in6(struct in6_addr *addr, uint64_t vhigh, uint64_t vlow)
523 be64enc(addr->s6_addr, vhigh);
524 be64enc(addr->s6_addr + 8, vlow);
528 ipv6_userprefix(
529 const struct in6_addr *prefix, // prefix from router
530 short prefix_len, // length of prefix received
531 uint64_t user_number, // "random" number from user
532 struct in6_addr *result, // resultant prefix
533 short result_len) // desired prefix length
535 uint64_t vh, vl, user_low, user_high;
537 if (prefix_len < 0 || prefix_len > 120 ||
538 result_len < 0 || result_len > 120)
540 errno = EINVAL;
541 return -1;
544 /* Check that the user_number fits inside result_len less prefix_len */
545 if (result_len < prefix_len || user_number > INT_MAX ||
546 ffs((int)user_number) > result_len - prefix_len)
548 errno = ERANGE;
549 return -1;
552 /* virtually shift user number by dest_len, then split at 64 */
553 if (result_len >= 64) {
554 user_high = user_number << (result_len - 64);
555 user_low = 0;
556 } else {
557 user_high = user_number >> (64 - result_len);
558 user_low = user_number << result_len;
561 /* convert to two 64bit host order values */
562 in6_to_h64(&vh, &vl, prefix);
564 vh |= user_high;
565 vl |= user_low;
567 /* copy back result */
568 h64_to_in6(result, vh, vl);
570 return 0;
573 #ifdef IPV6_POLLADDRFLAG
574 void
575 ipv6_checkaddrflags(void *arg)
577 struct ipv6_addr *ap;
578 int ifa_flags;
580 ap = arg;
581 ifa_flags = if_addrflags6(&ap->addr, ap->iface);
582 if (ifa_flags == -1)
583 logger(ap->iface->ctx, LOG_ERR,
584 "%s: if_addrflags6: %m", ap->iface->name);
585 else if (!(ifa_flags & IN6_IFF_TENTATIVE)) {
586 ipv6_handleifa(ap->iface->ctx, RTM_NEWADDR,
587 ap->iface->ctx->ifaces, ap->iface->name,
588 &ap->addr, ap->prefix_len, ifa_flags);
589 } else {
590 struct timespec tv;
592 ms_to_ts(&tv, RETRANS_TIMER / 2);
593 eloop_timeout_add_tv(ap->iface->ctx->eloop, &tv,
594 ipv6_checkaddrflags, ap);
597 #endif
600 static void
601 ipv6_deleteaddr(struct ipv6_addr *ia)
603 struct ipv6_state *state;
604 struct ipv6_addr *ap;
606 logger(ia->iface->ctx, LOG_INFO, "%s: deleting address %s",
607 ia->iface->name, ia->saddr);
608 if (if_deladdress6(ia) == -1 &&
609 errno != EADDRNOTAVAIL && errno != ENXIO && errno != ENODEV)
610 logger(ia->iface->ctx, LOG_ERR, "if_deladdress6: :%m");
612 state = IPV6_STATE(ia->iface);
613 TAILQ_FOREACH(ap, &state->addrs, next) {
614 if (IN6_ARE_ADDR_EQUAL(&ap->addr, &ia->addr)) {
615 TAILQ_REMOVE(&state->addrs, ap, next);
616 ipv6_freeaddr(ap);
617 break;
623 ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
625 struct interface *ifp;
626 struct ipv6_state *state;
627 struct ipv6_addr *nap;
628 uint32_t pltime, vltime;
630 /* Ensure no other interface has this address */
631 TAILQ_FOREACH(ifp, ap->iface->ctx->ifaces, next) {
632 if (ifp == ap->iface)
633 continue;
634 state = IPV6_STATE(ifp);
635 if (state == NULL)
636 continue;
637 TAILQ_FOREACH(nap, &state->addrs, next) {
638 if (IN6_ARE_ADDR_EQUAL(&nap->addr, &ap->addr)) {
639 ipv6_deleteaddr(nap);
640 break;
645 if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
646 ipv6_iffindaddr(ap->iface, &ap->addr))
647 ap->flags |= IPV6_AF_DADCOMPLETED;
649 logger(ap->iface->ctx, ap->flags & IPV6_AF_NEW ? LOG_INFO : LOG_DEBUG,
650 "%s: adding %saddress %s", ap->iface->name,
651 #ifdef IPV6_AF_TEMPORARY
652 ap->flags & IPV6_AF_TEMPORARY ? "temporary " : "",
653 #else
655 #endif
656 ap->saddr);
657 if (ap->prefix_pltime == ND6_INFINITE_LIFETIME &&
658 ap->prefix_vltime == ND6_INFINITE_LIFETIME)
659 logger(ap->iface->ctx, LOG_DEBUG,
660 "%s: pltime infinity, vltime infinity",
661 ap->iface->name);
662 else if (ap->prefix_pltime == ND6_INFINITE_LIFETIME)
663 logger(ap->iface->ctx, LOG_DEBUG,
664 "%s: pltime infinity, vltime %"PRIu32" seconds",
665 ap->iface->name, ap->prefix_vltime);
666 else if (ap->prefix_vltime == ND6_INFINITE_LIFETIME)
667 logger(ap->iface->ctx, LOG_DEBUG,
668 "%s: pltime %"PRIu32"seconds, vltime infinity",
669 ap->iface->name, ap->prefix_pltime);
670 else
671 logger(ap->iface->ctx, LOG_DEBUG,
672 "%s: pltime %"PRIu32" seconds, vltime %"PRIu32" seconds",
673 ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
675 /* Adjust plftime and vltime based on acquired time */
676 pltime = ap->prefix_pltime;
677 vltime = ap->prefix_vltime;
678 if (timespecisset(&ap->acquired) &&
679 (ap->prefix_pltime != ND6_INFINITE_LIFETIME ||
680 ap->prefix_vltime != ND6_INFINITE_LIFETIME))
682 struct timespec n;
684 if (now == NULL) {
685 clock_gettime(CLOCK_MONOTONIC, &n);
686 now = &n;
688 timespecsub(now, &ap->acquired, &n);
689 if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) {
690 ap->prefix_pltime -= (uint32_t)n.tv_sec;
691 /* This can happen when confirming a
692 * deprecated but still valid lease. */
693 if (ap->prefix_pltime > pltime)
694 ap->prefix_pltime = 0;
696 if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
697 ap->prefix_vltime -= (uint32_t)n.tv_sec;
699 #if 0
700 logger(ap->iface->ctx, LOG_DEBUG,
701 "%s: acquired %lld.%.9ld, now %lld.%.9ld, diff %lld.%.9ld",
702 ap->iface->name,
703 (long long)ap->acquired.tv_sec, ap->acquired.tv_nsec,
704 (long long)now->tv_sec, now->tv_nsec,
705 (long long)n.tv_sec, n.tv_nsec);
706 logger(ap->iface->ctx, LOG_DEBUG,
707 "%s: adj pltime %"PRIu32" seconds, "
708 "vltime %"PRIu32" seconds",
709 ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
710 #endif
713 if (if_addaddress6(ap) == -1) {
714 logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
715 /* Restore real pltime and vltime */
716 ap->prefix_pltime = pltime;
717 ap->prefix_vltime = vltime;
718 return -1;
721 #ifdef IPV6_MANAGETEMPADDR
722 /* RFC4941 Section 3.4 */
723 if (ap->flags & IPV6_AF_TEMPORARY &&
724 ap->prefix_pltime &&
725 ap->prefix_vltime &&
726 ap->iface->options->options & DHCPCD_IPV6RA_OWN &&
727 ip6_use_tempaddr(ap->iface->name))
728 eloop_timeout_add_sec(ap->iface->ctx->eloop,
729 (time_t)ap->prefix_pltime - REGEN_ADVANCE,
730 ipv6_regentempaddr, ap);
731 #endif
733 /* Restore real pltime and vltime */
734 ap->prefix_pltime = pltime;
735 ap->prefix_vltime = vltime;
737 ap->flags &= ~IPV6_AF_NEW;
738 ap->flags |= IPV6_AF_ADDED;
739 if (ap->delegating_iface)
740 ap->flags |= IPV6_AF_DELEGATED;
742 #ifdef IPV6_POLLADDRFLAG
743 eloop_timeout_delete(ap->iface->ctx->eloop,
744 ipv6_checkaddrflags, ap);
745 if (!(ap->flags & IPV6_AF_DADCOMPLETED)) {
746 struct timespec tv;
748 ms_to_ts(&tv, RETRANS_TIMER / 2);
749 eloop_timeout_add_tv(ap->iface->ctx->eloop,
750 &tv, ipv6_checkaddrflags, ap);
752 #endif
754 return 0;
758 ipv6_publicaddr(const struct ipv6_addr *ia)
760 return (ia->prefix_pltime &&
761 (ia->addr.s6_addr[0] & 0xfe) != 0xfc &&
762 !(ia->addr_flags & IN6_IFF_NOTUSEABLE));
766 ipv6_findaddrmatch(const struct ipv6_addr *addr, const struct in6_addr *match,
767 short flags)
770 if (match == NULL) {
771 if ((addr->flags &
772 (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
773 (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
774 return 1;
775 } else if (addr->prefix_vltime &&
776 IN6_ARE_ADDR_EQUAL(&addr->addr, match) &&
777 (!flags || addr->flags & flags))
778 return 1;
780 return 0;
783 struct ipv6_addr *
784 ipv6_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr, short flags)
786 struct ipv6_addr *dap, *nap;
788 dap = dhcp6_findaddr(ctx, addr, flags);
789 nap = ipv6nd_findaddr(ctx, addr, flags);
790 if (!dap && !nap)
791 return NULL;
792 if (dap && !nap)
793 return dap;
794 if (nap && !dap)
795 return nap;
796 if (nap->iface->metric < dap->iface->metric)
797 return nap;
798 return dap;
801 ssize_t
802 ipv6_addaddrs(struct ipv6_addrhead *addrs)
804 struct ipv6_addr *ap, *apn, *apf;
805 ssize_t i;
806 struct timespec now;
808 i = 0;
809 timespecclear(&now);
810 TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
811 if (ap->prefix_vltime == 0) {
812 if (ap->flags & IPV6_AF_ADDED) {
813 ipv6_deleteaddr(ap);
814 i++;
816 eloop_q_timeout_delete(ap->iface->ctx->eloop,
817 0, NULL, ap);
818 if (ap->flags & IPV6_AF_REQUEST) {
819 ap->flags &= ~IPV6_AF_ADDED;
820 } else {
821 TAILQ_REMOVE(addrs, ap, next);
822 ipv6_freeaddr(ap);
824 } else if (!(ap->flags & IPV6_AF_STALE) &&
825 !IN6_IS_ADDR_UNSPECIFIED(&ap->addr))
827 apf = ipv6_findaddr(ap->iface->ctx,
828 &ap->addr, IPV6_AF_ADDED);
829 if (apf && apf->iface != ap->iface) {
830 if (apf->iface->metric <= ap->iface->metric) {
831 logger(apf->iface->ctx, LOG_INFO,
832 "%s: preferring %s on %s",
833 ap->iface->name,
834 ap->saddr,
835 apf->iface->name);
836 continue;
838 logger(apf->iface->ctx, LOG_INFO,
839 "%s: preferring %s on %s",
840 apf->iface->name,
841 ap->saddr,
842 ap->iface->name);
843 if (if_deladdress6(apf) == -1 &&
844 errno != EADDRNOTAVAIL && errno != ENXIO)
845 logger(apf->iface->ctx, LOG_ERR,
846 "if_deladdress6: %m");
847 apf->flags &=
848 ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
849 } else if (apf)
850 apf->flags &= ~IPV6_AF_ADDED;
851 if (ap->flags & IPV6_AF_NEW)
852 i++;
853 if (!timespecisset(&now))
854 clock_gettime(CLOCK_MONOTONIC, &now);
855 ipv6_addaddr(ap, &now);
859 return i;
862 void
863 ipv6_freeaddr(struct ipv6_addr *ap)
866 eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap);
867 free(ap);
870 void
871 ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
872 const struct interface *ifd)
874 struct ipv6_addr *ap, *apn, *apf;
875 struct timespec now;
877 timespecclear(&now);
878 TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
879 if (ifd && ap->delegating_iface != ifd)
880 continue;
881 if (drop != 2)
882 TAILQ_REMOVE(addrs, ap, next);
883 if (drop && ap->flags & IPV6_AF_ADDED &&
884 (ap->iface->options->options &
885 (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
886 (DHCPCD_EXITING | DHCPCD_PERSISTENT))
888 if (drop == 2)
889 TAILQ_REMOVE(addrs, ap, next);
890 /* Don't drop link-local addresses. */
891 if (!IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
892 /* Find the same address somewhere else */
893 apf = ipv6_findaddr(ap->iface->ctx, &ap->addr,
895 if ((apf == NULL ||
896 (apf->iface != ap->iface)))
897 ipv6_deleteaddr(ap);
898 if (!(ap->iface->options->options &
899 DHCPCD_EXITING) && apf)
901 if (!timespecisset(&now))
902 clock_gettime(CLOCK_MONOTONIC,
903 &now);
904 ipv6_addaddr(apf, &now);
907 if (drop == 2)
908 ipv6_freeaddr(ap);
910 if (drop != 2)
911 ipv6_freeaddr(ap);
915 static struct ipv6_state *
916 ipv6_getstate(struct interface *ifp)
918 struct ipv6_state *state;
920 state = IPV6_STATE(ifp);
921 if (state == NULL) {
922 ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state));
923 state = IPV6_STATE(ifp);
924 if (state == NULL) {
925 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
926 return NULL;
928 TAILQ_INIT(&state->addrs);
929 TAILQ_INIT(&state->ll_callbacks);
931 /* Regenerate new ids */
932 if (ifp->options &&
933 ifp->options->options & DHCPCD_IPV6RA_OWN &&
934 ip6_use_tempaddr(ifp->name))
935 ipv6_regentempifid(ifp);
937 return state;
940 void
941 ipv6_handleifa(struct dhcpcd_ctx *ctx,
942 int cmd, struct if_head *ifs, const char *ifname,
943 const struct in6_addr *addr, uint8_t prefix_len, int flags)
945 struct interface *ifp;
946 struct ipv6_state *state;
947 struct ipv6_addr *ap;
948 struct ll_callback *cb;
950 #if 0
951 char buf[INET6_ADDRSTRLEN];
952 inet_ntop(AF_INET6, &addr->s6_addr,
953 buf, INET6_ADDRSTRLEN);
954 logger(ctx, LOG_DEBUG, "%s: cmd %d addr %s flags %d",
955 ifname, cmd, buf, flags);
956 #endif
958 if (ifs == NULL)
959 ifs = ctx->ifaces;
960 if (ifs == NULL) {
961 errno = ESRCH;
962 return;
964 if ((ifp = if_find(ifs, ifname)) == NULL)
965 return;
966 if ((state = ipv6_getstate(ifp)) == NULL)
967 return;
969 if (!IN6_IS_ADDR_LINKLOCAL(addr)) {
970 ipv6nd_handleifa(ctx, cmd, ifname, addr, flags);
971 dhcp6_handleifa(ctx, cmd, ifname, addr, flags);
974 TAILQ_FOREACH(ap, &state->addrs, next) {
975 if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr))
976 break;
979 switch (cmd) {
980 case RTM_DELADDR:
981 if (ap) {
982 TAILQ_REMOVE(&state->addrs, ap, next);
983 ipv6_freeaddr(ap);
985 break;
986 case RTM_NEWADDR:
987 if (ap == NULL) {
988 char buf[INET6_ADDRSTRLEN];
989 const char *cbp;
991 ap = calloc(1, sizeof(*ap));
992 ap->iface = ifp;
993 ap->addr = *addr;
994 ap->prefix_len = prefix_len;
995 ipv6_makeprefix(&ap->prefix, &ap->addr,
996 ap->prefix_len);
997 cbp = inet_ntop(AF_INET6, &addr->s6_addr,
998 buf, sizeof(buf));
999 if (cbp)
1000 snprintf(ap->saddr, sizeof(ap->saddr),
1001 "%s/%d", cbp, prefix_len);
1002 if (if_getlifetime6(ap) == -1) {
1003 /* No support or address vanished.
1004 * Either way, just set a deprecated
1005 * infinite time lifetime and continue.
1006 * This is fine because we only want
1007 * to know this when trying to extend
1008 * temporary addresses.
1009 * As we can't extend infinite, we'll
1010 * create a new temporary address. */
1011 ap->prefix_pltime = 0;
1012 ap->prefix_vltime =
1013 ND6_INFINITE_LIFETIME;
1015 /* This is a minor regression against RFC 4941
1016 * because the kernel only knows when the
1017 * lifetimes were last updated, not when the
1018 * address was initially created.
1019 * Provided dhcpcd is not restarted, this
1020 * won't be a problem.
1021 * If we don't like it, we can always
1022 * pretend lifetimes are infinite and always
1023 * generate a new temporary address on
1024 * restart. */
1025 ap->acquired = ap->created;
1026 TAILQ_INSERT_TAIL(&state->addrs,
1027 ap, next);
1029 ap->addr_flags = flags;
1030 #ifdef IPV6_MANAGETEMPADDR
1031 if (ap->addr_flags & IN6_IFF_TEMPORARY)
1032 ap->flags |= IPV6_AF_TEMPORARY;
1033 #endif
1034 if (IN6_IS_ADDR_LINKLOCAL(&ap->addr)) {
1035 #ifdef IPV6_POLLADDRFLAG
1036 if (ap->addr_flags & IN6_IFF_TENTATIVE) {
1037 struct timespec tv;
1039 ms_to_ts(&tv, RETRANS_TIMER / 2);
1040 eloop_timeout_add_tv(
1041 ap->iface->ctx->eloop,
1042 &tv, ipv6_checkaddrflags, ap);
1043 break;
1045 #endif
1047 if (!(ap->addr_flags & IN6_IFF_NOTUSEABLE)) {
1048 /* Now run any callbacks.
1049 * Typically IPv6RS or DHCPv6 */
1050 while ((cb =
1051 TAILQ_FIRST(&state->ll_callbacks)))
1053 TAILQ_REMOVE(
1054 &state->ll_callbacks,
1055 cb, next);
1056 cb->callback(cb->arg);
1057 free(cb);
1061 break;
1066 ipv6_hasaddr(const struct interface *ifp)
1069 if (ipv6nd_iffindaddr(ifp, NULL, 0) != NULL)
1070 return 1;
1071 if (dhcp6_iffindaddr(ifp, NULL, 0) != NULL)
1072 return 1;
1073 return 0;
1076 const struct ipv6_addr *
1077 ipv6_iffindaddr(const struct interface *ifp, const struct in6_addr *addr)
1079 const struct ipv6_state *state;
1080 const struct ipv6_addr *ap;
1082 state = IPV6_CSTATE(ifp);
1083 if (state) {
1084 TAILQ_FOREACH(ap, &state->addrs, next) {
1085 if (addr == NULL) {
1086 if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
1087 !(ap->addr_flags & IN6_IFF_NOTUSEABLE))
1088 return ap;
1089 } else {
1090 if (IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
1091 !(ap->addr_flags & IN6_IFF_TENTATIVE))
1092 return ap;
1096 return NULL;
1100 ipv6_addlinklocalcallback(struct interface *ifp,
1101 void (*callback)(void *), void *arg)
1103 struct ipv6_state *state;
1104 struct ll_callback *cb;
1106 state = ipv6_getstate(ifp);
1107 TAILQ_FOREACH(cb, &state->ll_callbacks, next) {
1108 if (cb->callback == callback && cb->arg == arg)
1109 break;
1111 if (cb == NULL) {
1112 cb = malloc(sizeof(*cb));
1113 if (cb == NULL) {
1114 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1115 return -1;
1117 cb->callback = callback;
1118 cb->arg = arg;
1119 TAILQ_INSERT_TAIL(&state->ll_callbacks, cb, next);
1121 return 0;
1124 static struct ipv6_addr *
1125 ipv6_newlinklocal(struct interface *ifp)
1127 struct ipv6_addr *ap;
1129 ap = calloc(1, sizeof(*ap));
1130 if (ap != NULL) {
1131 ap->iface = ifp;
1132 ap->prefix.s6_addr32[0] = htonl(0xfe800000);
1133 ap->prefix.s6_addr32[1] = 0;
1134 ap->prefix_len = 64;
1135 ap->dadcounter = 0;
1136 ap->prefix_pltime = ND6_INFINITE_LIFETIME;
1137 ap->prefix_vltime = ND6_INFINITE_LIFETIME;
1138 ap->flags = IPV6_AF_NEW;
1139 ap->addr_flags = IN6_IFF_TENTATIVE;
1141 return ap;
1144 static const uint8_t allzero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1145 static const uint8_t allone[8] =
1146 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1148 static int
1149 ipv6_addlinklocal(struct interface *ifp)
1151 struct ipv6_state *state;
1152 struct ipv6_addr *ap, *ap2;
1153 int dadcounter;
1155 /* Check sanity before malloc */
1156 if (!(ifp->options->options & DHCPCD_SLAACPRIVATE)) {
1157 switch (ifp->family) {
1158 case ARPHRD_ETHER:
1159 /* Check for a valid hardware address */
1160 if (ifp->hwlen != 6 && ifp->hwlen != 8) {
1161 errno = ENOTSUP;
1162 return -1;
1164 if (memcmp(ifp->hwaddr, allzero, ifp->hwlen) == 0 ||
1165 memcmp(ifp->hwaddr, allone, ifp->hwlen) == 0)
1167 errno = EINVAL;
1168 return -1;
1170 break;
1171 default:
1172 errno = ENOTSUP;
1173 return -1;
1177 state = ipv6_getstate(ifp);
1178 if (state == NULL)
1179 return -1;
1181 ap = ipv6_newlinklocal(ifp);
1182 if (ap == NULL)
1183 return -1;
1185 if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
1186 dadcounter = 0;
1187 nextslaacprivate:
1188 if (ipv6_makestableprivate(&ap->addr,
1189 &ap->prefix, ap->prefix_len, ifp, &dadcounter) == -1)
1191 free(ap);
1192 return -1;
1194 ap->dadcounter = dadcounter;
1195 } else {
1196 memcpy(ap->addr.s6_addr, ap->prefix.s6_addr, 8);
1197 switch (ifp->family) {
1198 case ARPHRD_ETHER:
1199 if (ifp->hwlen == 6) {
1200 ap->addr.s6_addr[ 8] = ifp->hwaddr[0];
1201 ap->addr.s6_addr[ 9] = ifp->hwaddr[1];
1202 ap->addr.s6_addr[10] = ifp->hwaddr[2];
1203 ap->addr.s6_addr[11] = 0xff;
1204 ap->addr.s6_addr[12] = 0xfe;
1205 ap->addr.s6_addr[13] = ifp->hwaddr[3];
1206 ap->addr.s6_addr[14] = ifp->hwaddr[4];
1207 ap->addr.s6_addr[15] = ifp->hwaddr[5];
1208 } else if (ifp->hwlen == 8)
1209 memcpy(&ap->addr.s6_addr[8], ifp->hwaddr, 8);
1210 else {
1211 free(ap);
1212 errno = ENOTSUP;
1213 return -1;
1215 break;
1218 /* Sanity check: g bit must not indciate "group" */
1219 if (EUI64_GROUP(&ap->addr)) {
1220 free(ap);
1221 errno = EINVAL;
1222 return -1;
1224 EUI64_TO_IFID(&ap->addr);
1227 /* Do we already have this address? */
1228 TAILQ_FOREACH(ap2, &state->addrs, next) {
1229 if (IN6_ARE_ADDR_EQUAL(&ap->addr, &ap2->addr)) {
1230 if (ap2->addr_flags & IN6_IFF_DUPLICATED) {
1231 if (ifp->options->options &
1232 DHCPCD_SLAACPRIVATE)
1234 dadcounter++;
1235 goto nextslaacprivate;
1237 free(ap);
1238 errno = EADDRNOTAVAIL;
1239 return -1;
1242 logger(ap2->iface->ctx, LOG_WARNING,
1243 "%s: waiting for %s to complete",
1244 ap2->iface->name, ap2->saddr);
1245 free(ap);
1246 errno = EEXIST;
1247 return 0;
1251 inet_ntop(AF_INET6, &ap->addr, ap->saddr, sizeof(ap->saddr));
1252 TAILQ_INSERT_TAIL(&state->addrs, ap, next);
1253 ipv6_addaddr(ap, NULL);
1254 return 1;
1257 /* Ensure the interface has a link-local address */
1259 ipv6_start(struct interface *ifp)
1261 const struct ipv6_state *state;
1262 const struct ipv6_addr *ap;
1264 /* We can't assign a link-locak address to this,
1265 * the ppp process has to. */
1266 if (ifp->flags & IFF_POINTOPOINT)
1267 return 0;
1269 state = IPV6_CSTATE(ifp);
1270 if (state) {
1271 TAILQ_FOREACH(ap, &state->addrs, next) {
1272 if (IN6_IS_ADDR_LINKLOCAL(&ap->addr) &&
1273 !(ap->addr_flags & IN6_IFF_DUPLICATED))
1274 break;
1276 /* Regenerate new ids */
1277 if (ifp->options->options & DHCPCD_IPV6RA_OWN &&
1278 ip6_use_tempaddr(ifp->name))
1279 ipv6_regentempifid(ifp);
1280 } else
1281 ap = NULL;
1283 if (ap == NULL && ipv6_addlinklocal(ifp) == -1)
1284 return -1;
1286 /* Load existing routes */
1287 if_initrt6(ifp);
1288 return 0;
1291 void
1292 ipv6_freedrop(struct interface *ifp, int drop)
1294 struct ipv6_state *state;
1295 struct ll_callback *cb;
1297 if (ifp == NULL)
1298 return;
1300 if ((state = IPV6_STATE(ifp)) == NULL)
1301 return;
1303 ipv6_freedrop_addrs(&state->addrs, drop ? 2 : 0, NULL);
1305 /* Becuase we need to cache the addresses we don't control,
1306 * we only free the state on when NOT dropping addresses. */
1307 if (drop == 0) {
1308 while ((cb = TAILQ_FIRST(&state->ll_callbacks))) {
1309 TAILQ_REMOVE(&state->ll_callbacks, cb, next);
1310 free(cb);
1312 free(state);
1313 ifp->if_data[IF_DATA_IPV6] = NULL;
1314 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1318 void
1319 ipv6_ctxfree(struct dhcpcd_ctx *ctx)
1322 if (ctx->ipv6 == NULL)
1323 return;
1325 ipv6_freerts(ctx->ipv6->routes);
1326 free(ctx->ipv6->routes);
1327 free(ctx->ipv6->ra_routers);
1328 ipv6_freerts(&ctx->ipv6->kroutes);
1329 free(ctx->ipv6);
1333 ipv6_handleifa_addrs(int cmd,
1334 struct ipv6_addrhead *addrs, const struct in6_addr *addr, int flags)
1336 struct ipv6_addr *ap, *apn;
1337 uint8_t found, alldadcompleted;
1339 alldadcompleted = 1;
1340 found = 0;
1341 TAILQ_FOREACH_SAFE(ap, addrs, next, apn) {
1342 if (!IN6_ARE_ADDR_EQUAL(addr, &ap->addr)) {
1343 if (ap->flags & IPV6_AF_ADDED &&
1344 !(ap->flags & IPV6_AF_DADCOMPLETED))
1345 alldadcompleted = 0;
1346 continue;
1348 switch (cmd) {
1349 case RTM_DELADDR:
1350 if (ap->flags & IPV6_AF_ADDED) {
1351 logger(ap->iface->ctx, LOG_INFO,
1352 "%s: deleted address %s",
1353 ap->iface->name, ap->saddr);
1354 ap->flags &= ~IPV6_AF_ADDED;
1356 break;
1357 case RTM_NEWADDR:
1358 /* Safety - ignore tentative announcements */
1359 if (flags & (IN6_IFF_DETACHED |IN6_IFF_TENTATIVE))
1360 break;
1361 if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
1362 found++;
1363 if (flags & IN6_IFF_DUPLICATED)
1364 ap->flags |= IPV6_AF_DUPLICATED;
1365 else
1366 ap->flags &= ~IPV6_AF_DUPLICATED;
1367 if (ap->dadcallback)
1368 ap->dadcallback(ap);
1369 /* We need to set this here in-case the
1370 * dadcallback function checks it */
1371 ap->flags |= IPV6_AF_DADCOMPLETED;
1373 break;
1377 return alldadcompleted ? found : 0;
1380 #ifdef IPV6_MANAGETEMPADDR
1381 static const struct ipv6_addr *
1382 ipv6_findaddrid(struct dhcpcd_ctx *ctx, uint8_t *addr)
1384 const struct interface *ifp;
1385 const struct ipv6_state *state;
1386 const struct ipv6_addr *ia;
1388 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1389 if ((state = IPV6_CSTATE(ifp))) {
1390 TAILQ_FOREACH(ia, &state->addrs, next) {
1391 if (memcmp(&ia->addr.s6_addr[8], addr, 8) == 0)
1392 return ia;
1396 return NULL;
1399 static const uint8_t nullid[8];
1400 static const uint8_t anycastid[8] = {
1401 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 };
1402 static const uint8_t isatapid[4] = { 0x00, 0x00, 0x5e, 0xfe };
1404 static void
1405 ipv6_regen_desync(struct interface *ifp, int force)
1407 struct ipv6_state *state;
1408 time_t max;
1410 state = IPV6_STATE(ifp);
1412 /* RFC4941 Section 5 states that DESYNC_FACTOR must never be
1413 * greater than TEMP_VALID_LIFETIME - REGEN_ADVANCE.
1414 * I believe this is an error and it should be never be greateter than
1415 * TEMP_PREFERRED_LIFETIME - REGEN_ADVANCE. */
1416 max = ip6_temp_preferred_lifetime(ifp->name) - REGEN_ADVANCE;
1417 if (state->desync_factor && !force && state->desync_factor < max)
1418 return;
1419 if (state->desync_factor == 0)
1420 state->desync_factor =
1421 (time_t)arc4random_uniform(MIN(MAX_DESYNC_FACTOR,
1422 (uint32_t)max));
1423 max = ip6_temp_preferred_lifetime(ifp->name) -
1424 state->desync_factor - REGEN_ADVANCE;
1425 eloop_timeout_add_sec(ifp->ctx->eloop, max, ipv6_regentempifid, ifp);
1428 void
1429 ipv6_gentempifid(struct interface *ifp)
1431 struct ipv6_state *state;
1432 MD5_CTX md5;
1433 uint8_t seed[16], digest[16];
1434 int retry;
1436 if ((state = IPV6_STATE(ifp)) == NULL)
1437 return;
1439 retry = 0;
1440 if (memcmp(nullid, state->randomseed0, sizeof(nullid)) == 0) {
1441 uint32_t r;
1443 r = arc4random();
1444 memcpy(seed, &r, sizeof(r));
1445 r = arc4random();
1446 memcpy(seed + sizeof(r), &r, sizeof(r));
1447 } else
1448 memcpy(seed, state->randomseed0, sizeof(state->randomseed0));
1450 memcpy(seed + sizeof(state->randomseed0),
1451 state->randomseed1, sizeof(state->randomseed1));
1453 again:
1454 /* RFC4941 Section 3.2.1.1
1455 * Take the left-most 64bits and set bit 6 to zero */
1456 MD5Init(&md5);
1457 MD5Update(&md5, seed, sizeof(seed));
1458 MD5Final(digest, &md5);
1460 /* RFC4941 Section 3.2.1.1
1461 * Take the left-most 64bits and set bit 6 to zero */
1462 memcpy(state->randomid, digest, sizeof(state->randomid));
1463 state->randomid[0] = (uint8_t)(state->randomid[0] & ~EUI64_UBIT);
1465 /* RFC4941 Section 3.2.1.4
1466 * Reject reserved or existing id's */
1467 if (memcmp(nullid, state->randomid, sizeof(nullid)) == 0 ||
1468 (memcmp(anycastid, state->randomid, 7) == 0 &&
1469 (anycastid[7] & state->randomid[7]) == anycastid[7]) ||
1470 memcmp(isatapid, state->randomid, sizeof(isatapid)) == 0 ||
1471 ipv6_findaddrid(ifp->ctx, state->randomid))
1473 if (++retry < GEN_TEMPID_RETRY_MAX) {
1474 memcpy(seed, digest + 8, 8);
1475 goto again;
1477 memset(state->randomid, 0, sizeof(state->randomid));
1480 /* RFC4941 Section 3.2.1.6
1481 * Save the right-most 64bits of the digest */
1482 memcpy(state->randomseed0, digest + 8,
1483 sizeof(state->randomseed0));
1486 /* RFC4941 Section 3.3.7 */
1487 static void
1488 ipv6_tempdadcallback(void *arg)
1490 struct ipv6_addr *ia = arg;
1492 if (ia->flags & IPV6_AF_DUPLICATED) {
1493 struct ipv6_addr *ia1;
1494 struct timespec tv;
1496 if (++ia->dadcounter == TEMP_IDGEN_RETRIES) {
1497 logger(ia->iface->ctx, LOG_ERR,
1498 "%s: too many duplicate temporary addresses",
1499 ia->iface->name);
1500 return;
1502 clock_gettime(CLOCK_MONOTONIC, &tv);
1503 if ((ia1 = ipv6_createtempaddr(ia, &tv)) == NULL)
1504 logger(ia->iface->ctx, LOG_ERR,
1505 "ipv6_createtempaddr: %m");
1506 else
1507 ia1->dadcounter = ia->dadcounter;
1508 ipv6_deleteaddr(ia);
1509 if (ia1)
1510 ipv6_addaddr(ia1, &ia1->acquired);
1514 struct ipv6_addr *
1515 ipv6_createtempaddr(struct ipv6_addr *ia0, const struct timespec *now)
1517 struct ipv6_state *state;
1518 const struct ipv6_state *cstate;
1519 int genid;
1520 struct in6_addr addr, mask;
1521 uint32_t randid[2];
1522 const struct interface *ifp;
1523 const struct ipv6_addr *ap;
1524 struct ipv6_addr *ia;
1525 uint32_t i, trylimit;
1526 char buf[INET6_ADDRSTRLEN];
1527 const char *cbp;
1529 trylimit = TEMP_IDGEN_RETRIES;
1530 state = IPV6_STATE(ia0->iface);
1531 genid = 0;
1533 addr = ia0->addr;
1534 ipv6_mask(&mask, ia0->prefix_len);
1535 /* clear the old ifid */
1536 for (i = 0; i < 4; i++)
1537 addr.s6_addr32[i] &= mask.s6_addr32[i];
1539 again:
1540 if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0)
1541 genid = 1;
1542 if (genid) {
1543 memcpy(state->randomseed1, &ia0->addr.s6_addr[8],
1544 sizeof(state->randomseed1));
1545 ipv6_gentempifid(ia0->iface);
1546 if (memcmp(state->randomid, nullid, sizeof(nullid)) == 0) {
1547 errno = EFAULT;
1548 return NULL;
1551 memcpy(&randid[0], state->randomid, sizeof(randid[0]));
1552 memcpy(&randid[1], state->randomid + sizeof(randid[1]),
1553 sizeof(randid[2]));
1554 addr.s6_addr32[2] |= randid[0] & ~mask.s6_addr32[2];
1555 addr.s6_addr32[3] |= randid[1] & ~mask.s6_addr32[3];
1557 /* Ensure we don't already have it */
1558 TAILQ_FOREACH(ifp, ia0->iface->ctx->ifaces, next) {
1559 cstate = IPV6_CSTATE(ifp);
1560 if (cstate) {
1561 TAILQ_FOREACH(ap, &cstate->addrs, next) {
1562 if (IN6_ARE_ADDR_EQUAL(&ap->addr, &addr)) {
1563 if (--trylimit == 0) {
1564 errno = EEXIST;
1565 return NULL;
1567 genid = 1;
1568 goto again;
1574 if ((ia = calloc(1, sizeof(*ia))) == NULL)
1575 return NULL;
1577 ia->iface = ia0->iface;
1578 ia->addr = addr;
1579 /* Must be made tentative, for our DaD to work */
1580 ia->addr_flags = IN6_IFF_TENTATIVE;
1581 ia->dadcallback = ipv6_tempdadcallback;
1582 ia->flags = IPV6_AF_NEW | IPV6_AF_AUTOCONF | IPV6_AF_TEMPORARY;
1583 ia->prefix = ia0->prefix;
1584 ia->prefix_len = ia0->prefix_len;
1585 ia->created = ia->acquired = now ? *now : ia0->acquired;
1587 /* Ensure desync is still valid */
1588 ipv6_regen_desync(ia->iface, 0);
1590 /* RFC4941 Section 3.3.4 */
1591 i = (uint32_t)(ip6_temp_preferred_lifetime(ia0->iface->name) -
1592 state->desync_factor);
1593 ia->prefix_pltime = MIN(ia0->prefix_pltime, i);
1594 i = (uint32_t)ip6_temp_valid_lifetime(ia0->iface->name);
1595 ia->prefix_vltime = MIN(ia0->prefix_vltime, i);
1596 if (ia->prefix_pltime <= REGEN_ADVANCE ||
1597 ia->prefix_pltime > ia0->prefix_vltime)
1599 errno = EINVAL;
1600 free(ia);
1601 return NULL;
1604 cbp = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf));
1605 if (cbp)
1606 snprintf(ia->saddr, sizeof(ia->saddr), "%s/%d",
1607 cbp, ia->prefix_len); else ia->saddr[0] = '\0';
1609 TAILQ_INSERT_TAIL(&state->addrs, ia, next);
1610 return ia;
1613 void
1614 ipv6_settempstale(struct interface *ifp)
1616 struct ipv6_state *state;
1617 struct ipv6_addr *ia;
1619 state = IPV6_STATE(ifp);
1620 TAILQ_FOREACH(ia, &state->addrs, next) {
1621 if (ia->flags & IPV6_AF_TEMPORARY)
1622 ia->flags |= IPV6_AF_STALE;
1626 struct ipv6_addr *
1627 ipv6_settemptime(struct ipv6_addr *ia, int flags)
1629 struct ipv6_state *state;
1630 struct ipv6_addr *ap, *first;
1632 state = IPV6_STATE(ia->iface);
1633 first = NULL;
1634 TAILQ_FOREACH_REVERSE(ap, &state->addrs, ipv6_addrhead, next) {
1635 if (ap->flags & IPV6_AF_TEMPORARY &&
1636 ap->prefix_pltime &&
1637 IN6_ARE_ADDR_EQUAL(&ia->prefix, &ap->prefix))
1639 time_t max, ext;
1641 if (flags == 0) {
1642 if (ap->prefix_pltime -
1643 (uint32_t)(ia->acquired.tv_sec -
1644 ap->acquired.tv_sec)
1645 < REGEN_ADVANCE)
1646 continue;
1648 return ap;
1651 if (!(ap->flags & IPV6_AF_ADDED))
1652 ap->flags |= IPV6_AF_NEW | IPV6_AF_AUTOCONF;
1653 ap->flags &= ~IPV6_AF_STALE;
1655 /* RFC4941 Section 3.4
1656 * Deprecated prefix, deprecate the temporary address */
1657 if (ia->prefix_pltime == 0) {
1658 ap->prefix_pltime = 0;
1659 goto valid;
1662 /* Ensure desync is still valid */
1663 ipv6_regen_desync(ap->iface, 0);
1665 /* RFC4941 Section 3.3.2
1666 * Extend temporary times, but ensure that they
1667 * never last beyond the system limit. */
1668 ext = ia->acquired.tv_sec + (time_t)ia->prefix_pltime;
1669 max = ap->created.tv_sec +
1670 ip6_temp_preferred_lifetime(ap->iface->name) -
1671 state->desync_factor;
1672 if (ext < max)
1673 ap->prefix_pltime = ia->prefix_pltime;
1674 else
1675 ap->prefix_pltime =
1676 (uint32_t)(max - ia->acquired.tv_sec);
1678 valid:
1679 ext = ia->acquired.tv_sec + (time_t)ia->prefix_vltime;
1680 max = ap->created.tv_sec +
1681 ip6_temp_valid_lifetime(ap->iface->name);
1682 if (ext < max)
1683 ap->prefix_vltime = ia->prefix_vltime;
1684 else
1685 ap->prefix_vltime =
1686 (uint32_t)(max - ia->acquired.tv_sec);
1688 /* Just extend the latest matching prefix */
1689 ap->acquired = ia->acquired;
1691 /* If extending return the last match as
1692 * it's the most current.
1693 * If deprecating, deprecate any other addresses we
1694 * may have, although this should not be needed */
1695 if (ia->prefix_pltime)
1696 return ap;
1697 if (first == NULL)
1698 first = ap;
1701 return first;
1704 void
1705 ipv6_addtempaddrs(struct interface *ifp, const struct timespec *now)
1707 struct ipv6_state *state;
1708 struct ipv6_addr *ia;
1710 state = IPV6_STATE(ifp);
1711 TAILQ_FOREACH(ia, &state->addrs, next) {
1712 if (ia->flags & IPV6_AF_TEMPORARY &&
1713 !(ia->flags & IPV6_AF_STALE))
1714 ipv6_addaddr(ia, now);
1718 static void
1719 ipv6_regentempaddr(void *arg)
1721 struct ipv6_addr *ia = arg, *ia1;
1722 struct timespec tv;
1724 logger(ia->iface->ctx, LOG_DEBUG, "%s: regen temp addr %s",
1725 ia->iface->name, ia->saddr);
1726 clock_gettime(CLOCK_MONOTONIC, &tv);
1727 ia1 = ipv6_createtempaddr(ia, &tv);
1728 if (ia1)
1729 ipv6_addaddr(ia1, &tv);
1730 else
1731 logger(ia->iface->ctx, LOG_ERR, "ipv6_createtempaddr: %m");
1734 static void
1735 ipv6_regentempifid(void *arg)
1737 struct interface *ifp = arg;
1738 struct ipv6_state *state;
1740 state = IPV6_STATE(ifp);
1741 if (memcmp(state->randomid, nullid, sizeof(state->randomid)))
1742 ipv6_gentempifid(ifp);
1744 ipv6_regen_desync(ifp, 1);
1746 #endif /* IPV6_MANAGETEMPADDR */
1748 static struct rt6 *
1749 find_route6(struct rt6_head *rts, const struct rt6 *r)
1751 struct rt6 *rt;
1753 TAILQ_FOREACH(rt, rts, next) {
1754 if (IN6_ARE_ADDR_EQUAL(&rt->dest, &r->dest) &&
1755 #ifdef HAVE_ROUTE_METRIC
1756 (r->iface == NULL || rt->iface == NULL ||
1757 rt->iface->metric == r->iface->metric) &&
1758 #endif
1759 IN6_ARE_ADDR_EQUAL(&rt->net, &r->net))
1760 return rt;
1762 return NULL;
1765 static void
1766 desc_route(const char *cmd, const struct rt6 *rt)
1768 char destbuf[INET6_ADDRSTRLEN];
1769 char gatebuf[INET6_ADDRSTRLEN];
1770 const char *ifname, *dest, *gate;
1771 struct dhcpcd_ctx *ctx;
1773 ctx = rt->iface ? rt->iface->ctx : NULL;
1774 ifname = rt->iface ? rt->iface->name : "(no iface)";
1775 dest = inet_ntop(AF_INET6, &rt->dest, destbuf, INET6_ADDRSTRLEN);
1776 gate = inet_ntop(AF_INET6, &rt->gate, gatebuf, INET6_ADDRSTRLEN);
1777 if (IN6_ARE_ADDR_EQUAL(&rt->gate, &in6addr_any))
1778 logger(ctx, LOG_INFO, "%s: %s route to %s/%d",
1779 ifname, cmd, dest, ipv6_prefixlen(&rt->net));
1780 else if (IN6_ARE_ADDR_EQUAL(&rt->dest, &in6addr_any) &&
1781 IN6_ARE_ADDR_EQUAL(&rt->net, &in6addr_any))
1782 logger(ctx, LOG_INFO, "%s: %s default route via %s",
1783 ifname, cmd, gate);
1784 else
1785 logger(ctx, LOG_INFO, "%s: %s%s route to %s/%d via %s",
1786 ifname, cmd,
1787 rt->flags & RTF_REJECT ? " reject" : "",
1788 dest, ipv6_prefixlen(&rt->net), gate);
1791 static struct rt6*
1792 ipv6_findrt(struct dhcpcd_ctx *ctx, const struct rt6 *rt, int flags)
1794 struct rt6 *r;
1796 TAILQ_FOREACH(r, &ctx->ipv6->kroutes, next) {
1797 if (IN6_ARE_ADDR_EQUAL(&rt->dest, &r->dest) &&
1798 #ifdef HAVE_ROUTE_METRIC
1799 (rt->iface == r->iface ||
1800 (rt->flags & RTF_REJECT && r->flags & RTF_REJECT)) &&
1801 (!flags || rt->metric == r->metric) &&
1802 #else
1803 (!flags || rt->iface == r->iface ||
1804 (rt->flags & RTF_REJECT && r->flags & RTF_REJECT)) &&
1805 #endif
1806 IN6_ARE_ADDR_EQUAL(&rt->net, &r->net))
1807 return r;
1809 return NULL;
1812 void
1813 ipv6_freerts(struct rt6_head *routes)
1815 struct rt6 *rt;
1817 while ((rt = TAILQ_FIRST(routes))) {
1818 TAILQ_REMOVE(routes, rt, next);
1819 free(rt);
1823 /* If something other than dhcpcd removes a route,
1824 * we need to remove it from our internal table. */
1826 ipv6_handlert(struct dhcpcd_ctx *ctx, int cmd, struct rt6 *rt)
1828 struct rt6 *f;
1830 if (ctx->ipv6 == NULL)
1831 return 0;
1833 f = ipv6_findrt(ctx, rt, 1);
1834 switch(cmd) {
1835 case RTM_ADD:
1836 if (f == NULL) {
1837 if ((f = malloc(sizeof(*f))) == NULL)
1838 return -1;
1839 *f = *rt;
1840 TAILQ_INSERT_TAIL(&ctx->ipv6->kroutes, f, next);
1842 break;
1843 case RTM_DELETE:
1844 if (f) {
1845 TAILQ_REMOVE(&ctx->ipv6->kroutes, f, next);
1846 free(f);
1848 /* If we manage the route, remove it */
1849 if ((f = find_route6(ctx->ipv6->routes, rt))) {
1850 desc_route("removing", f);
1851 TAILQ_REMOVE(ctx->ipv6->routes, f, next);
1852 free(f);
1854 break;
1856 return 0;
1859 #define n_route(a) nc_route(NULL, a)
1860 #define c_route(a, b) nc_route(a, b)
1861 static int
1862 nc_route(struct rt6 *ort, struct rt6 *nrt)
1864 int change;
1866 /* Don't set default routes if not asked to */
1867 if (IN6_IS_ADDR_UNSPECIFIED(&nrt->dest) &&
1868 IN6_IS_ADDR_UNSPECIFIED(&nrt->net) &&
1869 !(nrt->iface->options->options & DHCPCD_GATEWAY))
1870 return -1;
1872 desc_route(ort == NULL ? "adding" : "changing", nrt);
1874 change = 0;
1875 if (ort == NULL) {
1876 ort = ipv6_findrt(nrt->iface->ctx, nrt, 0);
1877 if (ort &&
1878 ((ort->flags & RTF_REJECT && nrt->flags & RTF_REJECT) ||
1879 (ort->iface == nrt->iface &&
1880 #ifdef HAVE_ROUTE_METRIC
1881 ort->metric == nrt->metric &&
1882 #endif
1883 IN6_ARE_ADDR_EQUAL(&ort->gate, &nrt->gate))))
1885 if (ort->mtu == nrt->mtu)
1886 return 0;
1887 change = 1;
1891 #ifdef RTF_CLONING
1892 /* BSD can set routes to be cloning routes.
1893 * Cloned routes inherit the parent flags.
1894 * As such, we need to delete and re-add the route to flush children
1895 * to correct the flags. */
1896 if (change && ort != NULL && ort->flags & RTF_CLONING)
1897 change = 0;
1898 #endif
1900 if (change) {
1901 if (if_route6(RTM_CHANGE, nrt) == 0)
1902 return 0;
1903 if (errno != ESRCH)
1904 logger(nrt->iface->ctx, LOG_ERR, "if_route6 (CHG): %m");
1907 #ifdef HAVE_ROUTE_METRIC
1908 /* With route metrics, we can safely add the new route before
1909 * deleting the old route. */
1910 if (if_route6(RTM_ADD, nrt) == 0) {
1911 if (ort && if_route6(RTM_DELETE, ort) == -1 &&
1912 errno != ESRCH)
1913 logger(nrt->iface->ctx, LOG_ERR, "if_route6 (DEL): %m");
1914 return 0;
1917 /* If the kernel claims the route exists we need to rip out the
1918 * old one first. */
1919 if (errno != EEXIST || ort == NULL)
1920 goto logerr;
1921 #endif
1923 /* No route metrics, we need to delete the old route before
1924 * adding the new one. */
1925 if (ort && if_route6(RTM_DELETE, ort) == -1 && errno != ESRCH)
1926 logger(nrt->iface->ctx, LOG_ERR, "if_route6: %m");
1927 if (if_route6(RTM_ADD, nrt) == 0)
1928 return 0;
1929 #ifdef HAVE_ROUTE_METRIC
1930 logerr:
1931 #endif
1932 logger(nrt->iface->ctx, LOG_ERR, "if_route6 (ADD): %m");
1933 return -1;
1936 static int
1937 d_route(struct rt6 *rt)
1939 int retval;
1941 desc_route("deleting", rt);
1942 retval = if_route6(RTM_DELETE, rt);
1943 if (retval != 0 && errno != ENOENT && errno != ESRCH)
1944 logger(rt->iface->ctx, LOG_ERR,
1945 "%s: if_delroute6: %m", rt->iface->name);
1946 return retval;
1949 static struct rt6 *
1950 make_route(const struct interface *ifp, const struct ra *rap)
1952 struct rt6 *r;
1954 r = calloc(1, sizeof(*r));
1955 if (r == NULL) {
1956 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1957 return NULL;
1959 r->iface = ifp;
1960 #ifdef HAVE_ROUTE_METRIC
1961 r->metric = ifp->metric;
1962 #endif
1963 if (rap)
1964 r->mtu = rap->mtu;
1965 else
1966 r->mtu = 0;
1967 return r;
1970 static struct rt6 *
1971 make_prefix(const struct interface *ifp, const struct ra *rap,
1972 const struct ipv6_addr *addr)
1974 struct rt6 *r;
1976 if (addr == NULL || addr->prefix_len > 128) {
1977 errno = EINVAL;
1978 return NULL;
1981 /* There is no point in trying to manage a /128 prefix,
1982 * ones without a lifetime or ones not on link or delegated */
1983 if (addr->prefix_len == 128 ||
1984 addr->prefix_vltime == 0 ||
1985 !(addr->flags & (IPV6_AF_ONLINK | IPV6_AF_DELEGATEDPFX)))
1986 return NULL;
1988 /* Don't install a blackhole route when not creating bigger prefixes */
1989 if (addr->flags & IPV6_AF_DELEGATEDZERO)
1990 return NULL;
1992 r = make_route(ifp, rap);
1993 if (r == NULL)
1994 return NULL;
1995 r->dest = addr->prefix;
1996 ipv6_mask(&r->net, addr->prefix_len);
1997 if (addr->flags & IPV6_AF_DELEGATEDPFX) {
1998 r->flags |= RTF_REJECT;
1999 r->gate = in6addr_loopback;
2000 } else
2001 r->gate = in6addr_any;
2002 return r;
2005 static struct rt6 *
2006 make_router(const struct ra *rap)
2008 struct rt6 *r;
2010 r = make_route(rap->iface, rap);
2011 if (r == NULL)
2012 return NULL;
2013 r->dest = in6addr_any;
2014 r->net = in6addr_any;
2015 r->gate = rap->from;
2016 return r;
2019 #define RT_IS_DEFAULT(rtp) \
2020 (IN6_ARE_ADDR_EQUAL(&((rtp)->dest), &in6addr_any) && \
2021 IN6_ARE_ADDR_EQUAL(&((rtp)->net), &in6addr_any))
2023 static void
2024 ipv6_build_ra_routes(struct ipv6_ctx *ctx, struct rt6_head *dnr, int expired)
2026 struct rt6 *rt;
2027 struct ra *rap;
2028 const struct ipv6_addr *addr;
2030 TAILQ_FOREACH(rap, ctx->ra_routers, next) {
2031 if (rap->expired != expired)
2032 continue;
2033 if (rap->iface->options->options & DHCPCD_IPV6RA_OWN) {
2034 TAILQ_FOREACH(addr, &rap->addrs, next) {
2035 rt = make_prefix(rap->iface, rap, addr);
2036 if (rt)
2037 TAILQ_INSERT_TAIL(dnr, rt, next);
2040 if (rap->lifetime && rap->iface->options->options &
2041 (DHCPCD_IPV6RA_OWN | DHCPCD_IPV6RA_OWN_DEFAULT) &&
2042 !rap->no_public_warned)
2044 rt = make_router(rap);
2045 if (rt)
2046 TAILQ_INSERT_TAIL(dnr, rt, next);
2051 static void
2052 ipv6_build_dhcp_routes(struct dhcpcd_ctx *ctx,
2053 struct rt6_head *dnr, enum DH6S dstate)
2055 const struct interface *ifp;
2056 const struct dhcp6_state *d6_state;
2057 const struct ipv6_addr *addr;
2058 struct rt6 *rt;
2060 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
2061 d6_state = D6_CSTATE(ifp);
2062 if (d6_state && d6_state->state == dstate) {
2063 TAILQ_FOREACH(addr, &d6_state->addrs, next) {
2064 rt = make_prefix(ifp, NULL, addr);
2065 if (rt)
2066 TAILQ_INSERT_TAIL(dnr, rt, next);
2072 void
2073 ipv6_buildroutes(struct dhcpcd_ctx *ctx)
2075 struct rt6_head dnr, *nrs;
2076 struct rt6 *rt, *rtn, *or;
2077 uint8_t have_default;
2078 unsigned long long o;
2080 /* We need to have the interfaces in the correct order to ensure
2081 * our routes are managed correctly. */
2082 if_sortinterfaces(ctx);
2084 TAILQ_INIT(&dnr);
2086 /* First add reachable routers and their prefixes */
2087 ipv6_build_ra_routes(ctx->ipv6, &dnr, 0);
2088 #ifdef HAVE_ROUTE_METRIC
2089 have_default = (TAILQ_FIRST(&dnr) != NULL);
2090 #endif
2092 /* We have no way of knowing if prefixes added by DHCP are reachable
2093 * or not, so we have to assume they are.
2094 * Add bound before delegated so we can prefer interfaces better */
2095 ipv6_build_dhcp_routes(ctx, &dnr, DH6S_BOUND);
2096 ipv6_build_dhcp_routes(ctx, &dnr, DH6S_DELEGATED);
2098 #ifdef HAVE_ROUTE_METRIC
2099 /* If we have an unreachable router, we really do need to remove the
2100 * route to it beause it could be a lower metric than a reachable
2101 * router. Of course, we should at least have some routers if all
2102 * are unreachable. */
2103 if (!have_default)
2104 #endif
2105 /* Add our non-reachable routers and prefixes
2106 * Unsure if this is needed, but it's a close match to kernel
2107 * behaviour */
2108 ipv6_build_ra_routes(ctx->ipv6, &dnr, 1);
2110 nrs = malloc(sizeof(*nrs));
2111 if (nrs == NULL) {
2112 logger(ctx, LOG_ERR, "%s: %m", __func__);
2113 return;
2115 TAILQ_INIT(nrs);
2116 have_default = 0;
2118 TAILQ_FOREACH_SAFE(rt, &dnr, next, rtn) {
2119 /* Is this route already in our table? */
2120 if (find_route6(nrs, rt) != NULL)
2121 continue;
2122 //rt->src.s_addr = ifp->addr.s_addr;
2123 /* Do we already manage it? */
2124 if ((or = find_route6(ctx->ipv6->routes, rt))) {
2125 if (or->iface != rt->iface ||
2126 #ifdef HAVE_ROUTE_METRIC
2127 rt->metric != or->metric ||
2128 #endif
2129 // or->src.s_addr != ifp->addr.s_addr ||
2130 !IN6_ARE_ADDR_EQUAL(&rt->gate, &or->gate))
2132 if (c_route(or, rt) != 0)
2133 continue;
2135 TAILQ_REMOVE(ctx->ipv6->routes, or, next);
2136 free(or);
2137 } else {
2138 if (n_route(rt) != 0)
2139 continue;
2141 if (RT_IS_DEFAULT(rt))
2142 have_default = 1;
2143 TAILQ_REMOVE(&dnr, rt, next);
2144 TAILQ_INSERT_TAIL(nrs, rt, next);
2147 /* Free any routes we failed to add/change */
2148 while ((rt = TAILQ_FIRST(&dnr))) {
2149 TAILQ_REMOVE(&dnr, rt, next);
2150 free(rt);
2153 /* Remove old routes we used to manage
2154 * If we own the default route, but not RA management itself
2155 * then we need to preserve the last best default route we had */
2156 while ((rt = TAILQ_LAST(ctx->ipv6->routes, rt6_head))) {
2157 TAILQ_REMOVE(ctx->ipv6->routes, rt, next);
2158 if (find_route6(nrs, rt) == NULL) {
2159 o = rt->iface->options->options;
2160 if (!have_default &&
2161 (o & DHCPCD_IPV6RA_OWN_DEFAULT) &&
2162 !(o & DHCPCD_IPV6RA_OWN) &&
2163 RT_IS_DEFAULT(rt))
2164 have_default = 1;
2165 /* no need to add it back to our routing table
2166 * as we delete an exiting route when we add
2167 * a new one */
2168 else if ((rt->iface->options->options &
2169 (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
2170 (DHCPCD_EXITING | DHCPCD_PERSISTENT))
2171 d_route(rt);
2173 free(rt);
2176 free(ctx->ipv6->routes);
2177 ctx->ipv6->routes = nrs;