xref: /dragonfly/contrib/dhcpcd/src/ipv6nd.c (revision 3c7e5806)
1 /*
2  * dhcpcd - IPv6 ND handling
3  * Copyright (c) 2006-2018 Roy Marples <roy@marples.name>
4  * All rights reserved
5 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/ioctl.h>
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <net/if.h>
32 #include <net/route.h>
33 #include <netinet/in.h>
34 #include <netinet/ip6.h>
35 #include <netinet/icmp6.h>
36 
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <stddef.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #define ELOOP_QUEUE 3
45 #include "common.h"
46 #include "dhcpcd.h"
47 #include "dhcp6.h"
48 #include "eloop.h"
49 #include "if.h"
50 #include "ipv6.h"
51 #include "ipv6nd.h"
52 #include "logerr.h"
53 #include "route.h"
54 #include "script.h"
55 
56 /* Debugging Router Solicitations is a lot of spam, so disable it */
57 //#define DEBUG_RS
58 
59 #ifndef ND_OPT_RDNSS
60 #define ND_OPT_RDNSS			25
61 struct nd_opt_rdnss {           /* RDNSS option RFC 6106 */
62 	uint8_t		nd_opt_rdnss_type;
63 	uint8_t		nd_opt_rdnss_len;
64 	uint16_t	nd_opt_rdnss_reserved;
65 	uint32_t	nd_opt_rdnss_lifetime;
66         /* followed by list of IP prefixes */
67 };
68 __CTASSERT(sizeof(struct nd_opt_rdnss) == 8);
69 #endif
70 
71 #ifndef ND_OPT_DNSSL
72 #define ND_OPT_DNSSL			31
73 struct nd_opt_dnssl {		/* DNSSL option RFC 6106 */
74 	uint8_t		nd_opt_dnssl_type;
75 	uint8_t		nd_opt_dnssl_len;
76 	uint16_t	nd_opt_dnssl_reserved;
77 	uint32_t	nd_opt_dnssl_lifetime;
78 	/* followed by list of DNS servers */
79 };
80 __CTASSERT(sizeof(struct nd_opt_rdnss) == 8);
81 #endif
82 
83 /* Impossible options, so we can easily add extras */
84 #define _ND_OPT_PREFIX_ADDR	255 + 1
85 
86 /* Minimal IPv6 MTU */
87 #ifndef IPV6_MMTU
88 #define IPV6_MMTU 1280
89 #endif
90 
91 #ifndef ND_RA_FLAG_RTPREF_HIGH
92 #define ND_RA_FLAG_RTPREF_MASK		0x18
93 #define ND_RA_FLAG_RTPREF_HIGH		0x08
94 #define ND_RA_FLAG_RTPREF_MEDIUM	0x00
95 #define ND_RA_FLAG_RTPREF_LOW		0x18
96 #define ND_RA_FLAG_RTPREF_RSV		0x10
97 #endif
98 
99 /* RTPREF_MEDIUM has to be 0! */
100 #define RTPREF_HIGH	1
101 #define RTPREF_MEDIUM	0
102 #define RTPREF_LOW	(-1)
103 #define RTPREF_RESERVED	(-2)
104 #define RTPREF_INVALID	(-3)	/* internal */
105 
106 #define MIN_RANDOM_FACTOR	500				/* millisecs */
107 #define MAX_RANDOM_FACTOR	1500				/* millisecs */
108 #define MIN_RANDOM_FACTOR_U	MIN_RANDOM_FACTOR * 1000	/* usecs */
109 #define MAX_RANDOM_FACTOR_U	MAX_RANDOM_FACTOR * 1000	/* usecs */
110 
111 #if BYTE_ORDER == BIG_ENDIAN
112 #define IPV6_ADDR_INT32_ONE     1
113 #define IPV6_ADDR_INT16_MLL     0xff02
114 #elif BYTE_ORDER == LITTLE_ENDIAN
115 #define IPV6_ADDR_INT32_ONE     0x01000000
116 #define IPV6_ADDR_INT16_MLL     0x02ff
117 #endif
118 
119 /* Debugging Neighbor Solicitations is a lot of spam, so disable it */
120 //#define DEBUG_NS
121 //
122 
123 static void ipv6nd_handledata(void *);
124 
125 /*
126  * Android ships buggy ICMP6 filter headers.
127  * Supply our own until they fix their shit.
128  * References:
129  *     https://android-review.googlesource.com/#/c/58438/
130  *     http://code.google.com/p/android/issues/original?id=32621&seq=24
131  */
132 #ifdef __ANDROID__
133 #undef ICMP6_FILTER_WILLPASS
134 #undef ICMP6_FILTER_WILLBLOCK
135 #undef ICMP6_FILTER_SETPASS
136 #undef ICMP6_FILTER_SETBLOCK
137 #undef ICMP6_FILTER_SETPASSALL
138 #undef ICMP6_FILTER_SETBLOCKALL
139 #define ICMP6_FILTER_WILLPASS(type, filterp) \
140 	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
141 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \
142 	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
143 #define ICMP6_FILTER_SETPASS(type, filterp) \
144 	((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
145 #define ICMP6_FILTER_SETBLOCK(type, filterp) \
146 	((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
147 #define ICMP6_FILTER_SETPASSALL(filterp) \
148 	memset(filterp, 0, sizeof(struct icmp6_filter));
149 #define ICMP6_FILTER_SETBLOCKALL(filterp) \
150 	memset(filterp, 0xff, sizeof(struct icmp6_filter));
151 #endif
152 
153 /* Support older systems with different defines */
154 #if !defined(IPV6_RECVHOPLIMIT) && defined(IPV6_HOPLIMIT)
155 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
156 #endif
157 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO)
158 #define IPV6_RECVPKTINFO IPV6_PKTINFO
159 #endif
160 
161 /* Handy defines */
162 #define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra),  0)
163 #define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra),  1)
164 
165 void
166 ipv6nd_printoptions(const struct dhcpcd_ctx *ctx,
167     const struct dhcp_opt *opts, size_t opts_len)
168 {
169 	size_t i, j;
170 	const struct dhcp_opt *opt, *opt2;
171 	int cols;
172 
173 	for (i = 0, opt = ctx->nd_opts;
174 	    i < ctx->nd_opts_len; i++, opt++)
175 	{
176 		for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
177 			if (opt2->option == opt->option)
178 				break;
179 		if (j == opts_len) {
180 			cols = printf("%03d %s", opt->option, opt->var);
181 			dhcp_print_option_encoding(opt, cols);
182 		}
183 	}
184 	for (i = 0, opt = opts; i < opts_len; i++, opt++) {
185 		cols = printf("%03d %s", opt->option, opt->var);
186 		dhcp_print_option_encoding(opt, cols);
187 	}
188 }
189 
190 static int
191 ipv6nd_open(struct dhcpcd_ctx *ctx)
192 {
193 	int on;
194 	struct icmp6_filter filt;
195 
196 	if (ctx->nd_fd != -1)
197 		return ctx->nd_fd;
198 #define SOCK_FLAGS	SOCK_CLOEXEC | SOCK_NONBLOCK
199 	ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW | SOCK_FLAGS, IPPROTO_ICMPV6);
200 #undef SOCK_FLAGS
201 	if (ctx->nd_fd == -1)
202 		return -1;
203 
204 	/* RFC4861 4.1 */
205 	on = 255;
206 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
207 	    &on, sizeof(on)) == -1)
208 		goto eexit;
209 
210 	on = 1;
211 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
212 	    &on, sizeof(on)) == -1)
213 		goto eexit;
214 
215 	on = 1;
216 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
217 	    &on, sizeof(on)) == -1)
218 		goto eexit;
219 
220 	ICMP6_FILTER_SETBLOCKALL(&filt);
221 	ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt);
222 	ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
223 	if (setsockopt(ctx->nd_fd, IPPROTO_ICMPV6, ICMP6_FILTER,
224 	    &filt, sizeof(filt)) == -1)
225 		goto eexit;
226 
227 	eloop_event_add(ctx->eloop, ctx->nd_fd,  ipv6nd_handledata, ctx);
228 	return ctx->nd_fd;
229 
230 eexit:
231 	if (ctx->nd_fd != -1) {
232 		eloop_event_delete(ctx->eloop, ctx->nd_fd);
233 		close(ctx->nd_fd);
234 		ctx->nd_fd = -1;
235 	}
236 	return -1;
237 }
238 
239 static int
240 ipv6nd_makersprobe(struct interface *ifp)
241 {
242 	struct rs_state *state;
243 	struct nd_router_solicit *rs;
244 
245 	state = RS_STATE(ifp);
246 	free(state->rs);
247 	state->rslen = sizeof(*rs);
248 	if (ifp->hwlen != 0)
249 		state->rslen += (size_t)ROUNDUP8(ifp->hwlen + 2);
250 	state->rs = calloc(1, state->rslen);
251 	if (state->rs == NULL)
252 		return -1;
253 	rs = state->rs;
254 	rs->nd_rs_type = ND_ROUTER_SOLICIT;
255 	//rs->nd_rs_code = 0;
256 	//rs->nd_rs_cksum = 0;
257 	//rs->nd_rs_reserved = 0;
258 
259 	if (ifp->hwlen != 0) {
260 		struct nd_opt_hdr *nd;
261 
262 		nd = (struct nd_opt_hdr *)(state->rs + 1);
263 		nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
264 		nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3);
265 		memcpy(nd + 1, ifp->hwaddr, ifp->hwlen);
266 	}
267 	return 0;
268 }
269 
270 static void
271 ipv6nd_sendrsprobe(void *arg)
272 {
273 	struct interface *ifp = arg;
274 	struct dhcpcd_ctx *ctx;
275 	struct rs_state *state;
276 	struct sockaddr_in6 dst;
277 	struct cmsghdr *cm;
278 	struct in6_pktinfo pi;
279 
280 	if (ipv6_linklocal(ifp) == NULL) {
281 		logdebugx("%s: delaying Router Solicitation for LL address",
282 		    ifp->name);
283 		ipv6_addlinklocalcallback(ifp, ipv6nd_sendrsprobe, ifp);
284 		return;
285 	}
286 
287 	memset(&dst, 0, sizeof(dst));
288 	dst.sin6_family = AF_INET6;
289 #ifdef HAVE_SA_LEN
290 	dst.sin6_len = sizeof(dst);
291 #endif
292 	dst.sin6_scope_id = ifp->index;
293 	if (inet_pton(AF_INET6, ALLROUTERS, &dst.sin6_addr) != 1) {
294 		logerr(__func__);
295 		return;
296 	}
297 
298 	state = RS_STATE(ifp);
299 	ctx = ifp->ctx;
300 	ctx->sndhdr.msg_name = (void *)&dst;
301 	ctx->sndhdr.msg_iov[0].iov_base = state->rs;
302 	ctx->sndhdr.msg_iov[0].iov_len = state->rslen;
303 
304 	/* Set the outbound interface */
305 	cm = CMSG_FIRSTHDR(&ctx->sndhdr);
306 	if (cm == NULL) /* unlikely */
307 		return;
308 	cm->cmsg_level = IPPROTO_IPV6;
309 	cm->cmsg_type = IPV6_PKTINFO;
310 	cm->cmsg_len = CMSG_LEN(sizeof(pi));
311 	memset(&pi, 0, sizeof(pi));
312 	pi.ipi6_ifindex = ifp->index;
313 	memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
314 
315 	logdebugx("%s: sending Router Solicitation", ifp->name);
316 	if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) {
317 		logerr(__func__);
318 		/* Allow IPv6ND to continue .... at most a few errors
319 		 * would be logged.
320 		 * Generally the error is ENOBUFS when struggling to
321 		 * associate with an access point. */
322 	}
323 
324 	if (state->rsprobes++ < MAX_RTR_SOLICITATIONS)
325 		eloop_timeout_add_sec(ifp->ctx->eloop,
326 		    RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
327 	else {
328 		logwarnx("%s: no IPv6 Routers available", ifp->name);
329 		ipv6nd_drop(ifp);
330 		dhcp6_dropnondelegates(ifp);
331 	}
332 }
333 
334 void
335 ipv6nd_expire(struct interface *ifp, uint32_t seconds)
336 {
337 	struct ra *rap;
338 	struct timespec now;
339 	uint32_t vltime = seconds;
340 	uint32_t pltime = seconds / 2;
341 
342 	if (ifp->ctx->ra_routers == NULL)
343 		return;
344 
345 	clock_gettime(CLOCK_MONOTONIC, &now);
346 
347 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
348 		if (rap->iface == ifp) {
349 			rap->acquired = now;
350 			rap->expired = seconds ? 0 : 1;
351 			if (seconds) {
352 				struct ipv6_addr *ia;
353 
354 				rap->lifetime = seconds;
355 				TAILQ_FOREACH(ia, &rap->addrs, next) {
356 					if (ia->prefix_pltime > pltime ||
357 					    ia->prefix_vltime > vltime)
358 					{
359 						ia->acquired = now;
360 						if (ia->prefix_pltime != 0)
361 							ia->prefix_pltime =
362 							    pltime;
363 						ia->prefix_vltime = vltime;
364 					}
365 				}
366 				ipv6_addaddrs(&rap->addrs);
367 			}
368 		}
369 	}
370 	if (seconds)
371 		ipv6nd_expirera(ifp);
372 	else
373 		rt_build(ifp->ctx, AF_INET6);
374 }
375 
376 static void
377 ipv6nd_reachable(struct ra *rap, int flags)
378 {
379 
380 	if (rap->lifetime == 0)
381 		return;
382 
383 	if (flags & IPV6ND_REACHABLE) {
384 		if (rap->expired == 0)
385 			return;
386 		loginfox("%s: %s is reachable again",
387 		    rap->iface->name, rap->sfrom);
388 		rap->expired = 0;
389 	} else {
390 		if (rap->expired != 0)
391 			return;
392 		logwarnx("%s: %s is unreachable, expiring it",
393 		    rap->iface->name, rap->sfrom);
394 		rap->expired = 1;
395 	}
396 
397 	rt_build(rap->iface->ctx, AF_INET6);
398 	/* XXX Not really an RA */
399 	script_runreason(rap->iface, "ROUTERADVERT");
400 }
401 
402 void
403 ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags)
404 {
405 	struct ra *rap;
406 
407 	if (ctx->ra_routers) {
408 	        TAILQ_FOREACH(rap, ctx->ra_routers, next) {
409 			if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) {
410 				ipv6nd_reachable(rap, flags);
411 				break;
412 			}
413 		}
414 	}
415 }
416 
417 const struct ipv6_addr *
418 ipv6nd_iffindaddr(const struct interface *ifp, const struct in6_addr *addr,
419     unsigned int flags)
420 {
421 	struct ra *rap;
422 	struct ipv6_addr *ap;
423 
424 	if (ifp->ctx->ra_routers == NULL)
425 		return NULL;
426 
427 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
428 		if (rap->iface != ifp)
429 			continue;
430 		TAILQ_FOREACH(ap, &rap->addrs, next) {
431 			if (ipv6_findaddrmatch(ap, addr, flags))
432 				return ap;
433 		}
434 	}
435 	return NULL;
436 }
437 
438 struct ipv6_addr *
439 ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
440     unsigned int flags)
441 {
442 	struct ra *rap;
443 	struct ipv6_addr *ap;
444 
445 	if (ctx->ra_routers == NULL)
446 		return NULL;
447 
448 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
449 		TAILQ_FOREACH(ap, &rap->addrs, next) {
450 			if (ipv6_findaddrmatch(ap, addr, flags))
451 				return ap;
452 		}
453 	}
454 	return NULL;
455 }
456 
457 static void
458 ipv6nd_removefreedrop_ra(struct ra *rap, int remove_ra, int drop_ra)
459 {
460 
461 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface);
462 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
463 	if (remove_ra)
464 		TAILQ_REMOVE(rap->iface->ctx->ra_routers, rap, next);
465 	ipv6_freedrop_addrs(&rap->addrs, drop_ra, NULL);
466 	free(rap->data);
467 	free(rap);
468 }
469 
470 static void
471 ipv6nd_freedrop_ra(struct ra *rap, int drop)
472 {
473 
474 	ipv6nd_removefreedrop_ra(rap, 1, drop);
475 }
476 
477 ssize_t
478 ipv6nd_free(struct interface *ifp)
479 {
480 	struct rs_state *state;
481 	struct ra *rap, *ran;
482 	struct dhcpcd_ctx *ctx;
483 	ssize_t n;
484 
485 	state = RS_STATE(ifp);
486 	if (state == NULL)
487 		return 0;
488 
489 	free(state->rs);
490 	free(state);
491 	ifp->if_data[IF_DATA_IPV6ND] = NULL;
492 	n = 0;
493 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
494 		if (rap->iface == ifp) {
495 			ipv6nd_free_ra(rap);
496 			n++;
497 		}
498 	}
499 
500 	/* If we don't have any more IPv6 enabled interfaces,
501 	 * close the global socket and release resources */
502 	ctx = ifp->ctx;
503 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
504 		if (RS_STATE(ifp))
505 			break;
506 	}
507 	if (ifp == NULL) {
508 		if (ctx->nd_fd != -1) {
509 			eloop_event_delete(ctx->eloop, ctx->nd_fd);
510 			close(ctx->nd_fd);
511 			ctx->nd_fd = -1;
512 		}
513 	}
514 
515 	return n;
516 }
517 
518 static int
519 rtpref(struct ra *rap)
520 {
521 
522 	switch (rap->flags & ND_RA_FLAG_RTPREF_MASK) {
523 	case ND_RA_FLAG_RTPREF_HIGH:
524 		return (RTPREF_HIGH);
525 	case ND_RA_FLAG_RTPREF_MEDIUM:
526 	case ND_RA_FLAG_RTPREF_RSV:
527 		return (RTPREF_MEDIUM);
528 	case ND_RA_FLAG_RTPREF_LOW:
529 		return (RTPREF_LOW);
530 	default:
531 		logerrx("rtpref: impossible RA flag %x", rap->flags);
532 		return (RTPREF_INVALID);
533 	}
534 	/* NOTREACHED */
535 }
536 
537 static void
538 add_router(struct dhcpcd_ctx *ctx, struct ra *router)
539 {
540 	struct ra *rap;
541 
542 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
543 		if (router->iface->metric < rap->iface->metric ||
544 		    (router->iface->metric == rap->iface->metric &&
545 		    rtpref(router) > rtpref(rap)))
546 		{
547 			TAILQ_INSERT_BEFORE(rap, router, next);
548 			return;
549 		}
550 	}
551 	TAILQ_INSERT_TAIL(ctx->ra_routers, router, next);
552 }
553 
554 static int
555 ipv6nd_scriptrun(struct ra *rap)
556 {
557 	int hasdns, hasaddress, pid;
558 	struct ipv6_addr *ap;
559 
560 	hasaddress = 0;
561 	/* If all addresses have completed DAD run the script */
562 	TAILQ_FOREACH(ap, &rap->addrs, next) {
563 		if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) ==
564 		    (IPV6_AF_AUTOCONF | IPV6_AF_ADDED))
565 		{
566 			hasaddress = 1;
567 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
568 			    ipv6_iffindaddr(ap->iface, &ap->addr,
569 			    IN6_IFF_TENTATIVE))
570 				ap->flags |= IPV6_AF_DADCOMPLETED;
571 			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
572 				logdebugx("%s: waiting for Router Advertisement"
573 				    " DAD to complete",
574 				    rap->iface->name);
575 				return 0;
576 			}
577 		}
578 	}
579 
580 	/* If we don't require RDNSS then set hasdns = 1 so we fork */
581 	if (!(rap->iface->options->options & DHCPCD_IPV6RA_REQRDNSS))
582 		hasdns = 1;
583 	else {
584 		hasdns = rap->hasdns;
585 	}
586 
587 	script_runreason(rap->iface, "ROUTERADVERT");
588 	pid = 0;
589 	if (hasdns && (hasaddress ||
590 	    !(rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))))
591 		pid = dhcpcd_daemonise(rap->iface->ctx);
592 #if 0
593 	else if (options & DHCPCD_DAEMONISE &&
594 	    !(options & DHCPCD_DAEMONISED) && new_data)
595 		logwarnx("%s: did not fork due to an absent"
596 		    " RDNSS option in the RA",
597 		    ifp->name);
598 }
599 #endif
600 	return pid;
601 }
602 
603 static void
604 ipv6nd_addaddr(void *arg)
605 {
606 	struct ipv6_addr *ap = arg;
607 
608 	ipv6_addaddr(ap, NULL);
609 }
610 
611 int
612 ipv6nd_dadcompleted(const struct interface *ifp)
613 {
614 	const struct ra *rap;
615 	const struct ipv6_addr *ap;
616 
617 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
618 		if (rap->iface != ifp)
619 			continue;
620 		TAILQ_FOREACH(ap, &rap->addrs, next) {
621 			if (ap->flags & IPV6_AF_AUTOCONF &&
622 			    ap->flags & IPV6_AF_ADDED &&
623 			    !(ap->flags & IPV6_AF_DADCOMPLETED))
624 				return 0;
625 		}
626 	}
627 	return 1;
628 }
629 
630 static void
631 ipv6nd_dadcallback(void *arg)
632 {
633 	struct ipv6_addr *ia = arg, *rapap;
634 	struct interface *ifp;
635 	struct ra *rap;
636 	int wascompleted, found;
637 	struct timespec tv;
638 	char buf[INET6_ADDRSTRLEN];
639 	const char *p;
640 	int dadcounter;
641 
642 	ifp = ia->iface;
643 	wascompleted = (ia->flags & IPV6_AF_DADCOMPLETED);
644 	ia->flags |= IPV6_AF_DADCOMPLETED;
645 	if (ia->flags & IPV6_AF_DUPLICATED) {
646 		ia->dadcounter++;
647 		logwarnx("%s: DAD detected %s", ifp->name, ia->saddr);
648 
649 		/* Try and make another stable private address.
650 		 * Because ap->dadcounter is always increamented,
651 		 * a different address is generated. */
652 		/* XXX Cache DAD counter per prefix/id/ssid? */
653 		if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
654 			if (ia->dadcounter >= IDGEN_RETRIES) {
655 				logerrx("%s: unable to obtain a"
656 				    " stable private address",
657 				    ifp->name);
658 				goto try_script;
659 			}
660 			loginfox("%s: deleting address %s",
661 			    ifp->name, ia->saddr);
662 			if (if_address6(RTM_DELADDR, ia) == -1 &&
663 			    errno != EADDRNOTAVAIL && errno != ENXIO)
664 				logerr(__func__);
665 			dadcounter = ia->dadcounter;
666 			if (ipv6_makestableprivate(&ia->addr,
667 			    &ia->prefix, ia->prefix_len,
668 			    ifp, &dadcounter) == -1)
669 			{
670 				logerr("ipv6_makestableprivate");
671 				return;
672 			}
673 			ia->dadcounter = dadcounter;
674 			ia->flags &= ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
675 			ia->flags |= IPV6_AF_NEW;
676 			p = inet_ntop(AF_INET6, &ia->addr, buf, sizeof(buf));
677 			if (p)
678 				snprintf(ia->saddr,
679 				    sizeof(ia->saddr),
680 				    "%s/%d",
681 				    p, ia->prefix_len);
682 			else
683 				ia->saddr[0] = '\0';
684 			tv.tv_sec = 0;
685 			tv.tv_nsec = (suseconds_t)
686 			    arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC);
687 			timespecnorm(&tv);
688 			eloop_timeout_add_tv(ifp->ctx->eloop, &tv,
689 			    ipv6nd_addaddr, ia);
690 			return;
691 		}
692 	}
693 
694 try_script:
695 	if (!wascompleted) {
696 		TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
697 			if (rap->iface != ifp)
698 				continue;
699 			wascompleted = 1;
700 			found = 0;
701 			TAILQ_FOREACH(rapap, &rap->addrs, next) {
702 				if (rapap->flags & IPV6_AF_AUTOCONF &&
703 				    rapap->flags & IPV6_AF_ADDED &&
704 				    (rapap->flags & IPV6_AF_DADCOMPLETED) == 0)
705 				{
706 					wascompleted = 0;
707 					break;
708 				}
709 				if (rapap == ia)
710 					found = 1;
711 			}
712 
713 			if (wascompleted && found) {
714 				logdebugx("%s: Router Advertisement DAD "
715 				    "completed",
716 				    rap->iface->name);
717 				if (ipv6nd_scriptrun(rap))
718 					return;
719 			}
720 		}
721 	}
722 }
723 
724 #ifndef DHCP6
725 /* If DHCPv6 is compiled out, supply a shim to provide an error message
726  * if IPv6RA requests DHCPv6. */
727 #undef dhcp6_start
728 static int
729 dhcp6_start(__unused struct interface *ifp, __unused enum DH6S init_state)
730 {
731 
732 	errno = ENOTSUP;
733 	return -1;
734 }
735 #endif
736 
737 static void
738 ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
739     struct icmp6_hdr *icp, size_t len, int hoplimit)
740 {
741 	size_t i, olen;
742 	struct nd_router_advert *nd_ra;
743 	struct nd_opt_hdr ndo;
744 	struct nd_opt_prefix_info pi;
745 	struct nd_opt_mtu mtu;
746 	struct nd_opt_rdnss rdnss;
747 	uint8_t *p;
748 	struct ra *rap;
749 	struct in6_addr pi_prefix;
750 	struct ipv6_addr *ap;
751 	struct dhcp_opt *dho;
752 	bool new_rap, new_data;
753 	uint32_t old_lifetime;
754 	__printflike(1, 2) void (*logfunc)(const char *, ...);
755 #ifdef IPV6_MANAGETEMPADDR
756 	uint8_t new_ap;
757 #endif
758 
759 	if (ifp == NULL) {
760 #ifdef DEBUG_RS
761 		logdebugx("RA for unexpected interface from %s",
762 		    ctx->sfrom);
763 #endif
764 		return;
765 	}
766 
767 	if (len < sizeof(struct nd_router_advert)) {
768 		logerrx("IPv6 RA packet too short from %s", ctx->sfrom);
769 		return;
770 	}
771 
772 	/* RFC 4861 7.1.2 */
773 	if (hoplimit != 255) {
774 		logerrx("invalid hoplimit(%d) in RA from %s",
775 		    hoplimit, ctx->sfrom);
776 		return;
777 	}
778 
779 	if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
780 		logerrx("RA from non local address %s", ctx->sfrom);
781 		return;
782 	}
783 
784 	if (!(ifp->options->options & DHCPCD_IPV6RS)) {
785 #ifdef DEBUG_RS
786 		logerrx("%s: unexpected RA from %s",
787 		    ifp->name, ctx->sfrom);
788 #endif
789 		return;
790 	}
791 
792 	/* We could receive a RA before we sent a RS*/
793 	if (ipv6_linklocal(ifp) == NULL) {
794 #ifdef DEBUG_RS
795 		logdebugx("%s: received RA from %s (no link-local)",
796 		    ifp->name, ctx->sfrom);
797 #endif
798 		return;
799 	}
800 
801 	if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr, IN6_IFF_TENTATIVE)) {
802 		logdebugx("%s: ignoring RA from ourself %s",
803 		    ifp->name, ctx->sfrom);
804 		return;
805 	}
806 
807 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
808 		if (ifp == rap->iface &&
809 		    IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr))
810 			break;
811 	}
812 
813 	nd_ra = (struct nd_router_advert *)icp;
814 
815 	/* We don't want to spam the log with the fact we got an RA every
816 	 * 30 seconds or so, so only spam the log if it's different. */
817 	if (rap == NULL || (rap->data_len != len ||
818 	     memcmp(rap->data, (unsigned char *)icp, rap->data_len) != 0))
819 	{
820 		if (rap) {
821 			free(rap->data);
822 			rap->data_len = 0;
823 		}
824 		new_data = true;
825 	} else
826 		new_data = false;
827 	if (rap == NULL) {
828 		rap = calloc(1, sizeof(*rap));
829 		if (rap == NULL) {
830 			logerr(__func__);
831 			return;
832 		}
833 		rap->iface = ifp;
834 		rap->from = ctx->from.sin6_addr;
835 		strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
836 		TAILQ_INIT(&rap->addrs);
837 		new_rap = true;
838 	} else
839 		new_rap = false;
840 	if (rap->data_len == 0) {
841 		rap->data = malloc(len);
842 		if (rap->data == NULL) {
843 			logerr(__func__);
844 			if (new_rap)
845 				free(rap);
846 			return;
847 		}
848 		memcpy(rap->data, icp, len);
849 		rap->data_len = len;
850 	}
851 
852 	/* We could change the debug level based on new_data, but some
853 	 * routers like to decrease the advertised valid and preferred times
854 	 * in accordance with the own prefix times which would result in too
855 	 * much needless log spam. */
856 	logfunc = new_rap ? loginfox : logdebugx,
857 	logfunc("%s: Router Advertisement from %s",
858 	    ifp->name, ctx->sfrom);
859 
860 	clock_gettime(CLOCK_MONOTONIC, &rap->acquired);
861 	rap->flags = nd_ra->nd_ra_flags_reserved;
862 	old_lifetime = rap->lifetime;
863 	rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
864 	if (!new_rap && rap->lifetime == 0 && old_lifetime != 0)
865 		logwarnx("%s: %s: no longer a default router",
866 		    ifp->name, rap->sfrom);
867 	if (nd_ra->nd_ra_reachable) {
868 		rap->reachable = ntohl(nd_ra->nd_ra_reachable);
869 		if (rap->reachable > MAX_REACHABLE_TIME)
870 			rap->reachable = 0;
871 	}
872 	if (nd_ra->nd_ra_retransmit)
873 		rap->retrans = ntohl(nd_ra->nd_ra_retransmit);
874 	if (rap->lifetime)
875 		rap->expired = 0;
876 	rap->hasdns = 0;
877 
878 #ifdef IPV6_AF_TEMPORARY
879 	ipv6_markaddrsstale(ifp, IPV6_AF_TEMPORARY);
880 #endif
881 	TAILQ_FOREACH(ap, &rap->addrs, next) {
882 		ap->flags |= IPV6_AF_STALE;
883 	}
884 
885 	len -= sizeof(struct nd_router_advert);
886 	p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
887 	for (; len > 0; p += olen, len -= olen) {
888 		if (len < sizeof(ndo)) {
889 			logerrx("%s: short option", ifp->name);
890 			break;
891 		}
892 		memcpy(&ndo, p, sizeof(ndo));
893 		olen = (size_t)ndo.nd_opt_len * 8;
894 		if (olen == 0) {
895 			logerrx("%s: zero length option", ifp->name);
896 			break;
897 		}
898 		if (olen > len) {
899 			logerrx("%s: option length exceeds message",
900 			    ifp->name);
901 			break;
902 		}
903 
904 		if (has_option_mask(ifp->options->rejectmasknd,
905 		    ndo.nd_opt_type))
906 		{
907 			for (i = 0, dho = ctx->nd_opts;
908 			    i < ctx->nd_opts_len;
909 			    i++, dho++)
910 			{
911 				if (dho->option == ndo.nd_opt_type)
912 					break;
913 			}
914 			if (dho != NULL)
915 				logwarnx("%s: reject RA (option %s) from %s",
916 				    ifp->name, dho->var, ctx->sfrom);
917 			else
918 				logwarnx("%s: reject RA (option %d) from %s",
919 				    ifp->name, ndo.nd_opt_type, ctx->sfrom);
920 			if (new_rap)
921 				ipv6nd_removefreedrop_ra(rap, 0, 0);
922 			else
923 				ipv6nd_free_ra(rap);
924 			return;
925 		}
926 
927 		if (has_option_mask(ifp->options->nomasknd, ndo.nd_opt_type))
928 			continue;
929 
930 		switch (ndo.nd_opt_type) {
931 		case ND_OPT_PREFIX_INFORMATION:
932 			logfunc = new_data ? logerrx : logdebugx;
933 			if (ndo.nd_opt_len != 4) {
934 				logfunc("%s: invalid option len for prefix",
935 				    ifp->name);
936 				continue;
937 			}
938 			memcpy(&pi, p, sizeof(pi));
939 			if (pi.nd_opt_pi_prefix_len > 128) {
940 				logfunc("%s: invalid prefix len", ifp->name);
941 				continue;
942 			}
943 			/* nd_opt_pi_prefix is not aligned. */
944 			memcpy(&pi_prefix, &pi.nd_opt_pi_prefix,
945 			    sizeof(pi_prefix));
946 			if (IN6_IS_ADDR_MULTICAST(&pi_prefix) ||
947 			    IN6_IS_ADDR_LINKLOCAL(&pi_prefix))
948 			{
949 				logfunc("%s: invalid prefix in RA", ifp->name);
950 				continue;
951 			}
952 			if (ntohl(pi.nd_opt_pi_preferred_time) >
953 			    ntohl(pi.nd_opt_pi_valid_time))
954 			{
955 				logfunc("%s: pltime > vltime", ifp->name);
956 				continue;
957 			}
958 			TAILQ_FOREACH(ap, &rap->addrs, next)
959 				if (ap->prefix_len ==pi.nd_opt_pi_prefix_len &&
960 				    IN6_ARE_ADDR_EQUAL(&ap->prefix, &pi_prefix))
961 					break;
962 			if (ap == NULL) {
963 				unsigned int flags;
964 
965 				if (!(pi.nd_opt_pi_flags_reserved &
966 				    ND_OPT_PI_FLAG_AUTO) &&
967 				    !(pi.nd_opt_pi_flags_reserved &
968 				    ND_OPT_PI_FLAG_ONLINK))
969 					continue;
970 
971 				flags = IPV6_AF_RAPFX;
972 				if (pi.nd_opt_pi_flags_reserved &
973 				    ND_OPT_PI_FLAG_AUTO &&
974 				    rap->iface->options->options &
975 				    DHCPCD_IPV6RA_AUTOCONF)
976 					flags |= IPV6_AF_AUTOCONF;
977 
978 				ap = ipv6_newaddr(rap->iface,
979 				    &pi_prefix, pi.nd_opt_pi_prefix_len, flags);
980 				if (ap == NULL)
981 					break;
982 				ap->prefix = pi_prefix;
983 				ap->dadcallback = ipv6nd_dadcallback;
984 				ap->created = ap->acquired = rap->acquired;
985 				TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
986 
987 #ifdef IPV6_MANAGETEMPADDR
988 				/* New address to dhcpcd RA handling.
989 				 * If the address already exists and a valid
990 				 * temporary address also exists then
991 				 * extend the existing one rather than
992 				 * create a new one */
993 				if (ipv6_iffindaddr(ifp, &ap->addr,
994 				    IN6_IFF_NOTUSEABLE) &&
995 				    ipv6_settemptime(ap, 0))
996 					new_ap = 0;
997 				else
998 					new_ap = 1;
999 #endif
1000 			} else {
1001 #ifdef IPV6_MANAGETEMPADDR
1002 				new_ap = 0;
1003 #endif
1004 				ap->flags &= ~IPV6_AF_STALE;
1005 				ap->acquired = rap->acquired;
1006 			}
1007 			if (pi.nd_opt_pi_flags_reserved &
1008 			    ND_OPT_PI_FLAG_ONLINK)
1009 				ap->flags |= IPV6_AF_ONLINK;
1010 			ap->prefix_vltime =
1011 			    ntohl(pi.nd_opt_pi_valid_time);
1012 			ap->prefix_pltime =
1013 			    ntohl(pi.nd_opt_pi_preferred_time);
1014 
1015 #ifdef IPV6_MANAGETEMPADDR
1016 			/* RFC4941 Section 3.3.3 */
1017 			if (ap->flags & IPV6_AF_AUTOCONF &&
1018 			    ip6_use_tempaddr(ap->iface->name))
1019 			{
1020 				if (!new_ap) {
1021 					if (ipv6_settemptime(ap, 1) == NULL)
1022 						new_ap = 1;
1023 				}
1024 				if (new_ap && ap->prefix_pltime) {
1025 					if (ipv6_createtempaddr(ap,
1026 					    &ap->acquired) == NULL)
1027 						logerr("ipv6_createtempaddr");
1028 				}
1029 			}
1030 #endif
1031 			break;
1032 
1033 		case ND_OPT_MTU:
1034 			memcpy(&mtu, p, sizeof(mtu));
1035 			mtu.nd_opt_mtu_mtu = ntohl(mtu.nd_opt_mtu_mtu);
1036 			if (mtu.nd_opt_mtu_mtu < IPV6_MMTU) {
1037 				logerrx("%s: invalid MTU %d",
1038 				    ifp->name, mtu.nd_opt_mtu_mtu);
1039 				break;
1040 			}
1041 			rap->mtu = mtu.nd_opt_mtu_mtu;
1042 			break;
1043 
1044 		case ND_OPT_RDNSS:
1045 			memcpy(&rdnss, p, sizeof(rdnss));
1046 			if (rdnss.nd_opt_rdnss_lifetime &&
1047 			    rdnss.nd_opt_rdnss_len > 1)
1048 				rap->hasdns = 1;
1049 			break;
1050 		default:
1051 			continue;
1052 		}
1053 	}
1054 
1055 	for (i = 0, dho = ctx->nd_opts;
1056 	    i < ctx->nd_opts_len;
1057 	    i++, dho++)
1058 	{
1059 		if (has_option_mask(ifp->options->requiremasknd,
1060 		    dho->option))
1061 		{
1062 			logwarnx("%s: reject RA (no option %s) from %s",
1063 			    ifp->name, dho->var, ctx->sfrom);
1064 			if (new_rap)
1065 				ipv6nd_removefreedrop_ra(rap, 0, 0);
1066 			else
1067 				ipv6nd_free_ra(rap);
1068 			return;
1069 		}
1070 	}
1071 
1072 	if (new_rap)
1073 		add_router(ifp->ctx, rap);
1074 
1075 	if (ifp->ctx->options & DHCPCD_TEST) {
1076 		script_runreason(ifp, "TEST");
1077 		goto handle_flag;
1078 	}
1079 	ipv6_addaddrs(&rap->addrs);
1080 #ifdef IPV6_MANAGETEMPADDR
1081 	ipv6_addtempaddrs(ifp, &rap->acquired);
1082 #endif
1083 
1084 	/* Find any freshly added routes, such as the subnet route.
1085 	 * We do this because we cannot rely on recieving the kernel
1086 	 * notification right now via our link socket. */
1087 	if_initrt(ifp->ctx, AF_INET6);
1088 
1089 	rt_build(ifp->ctx, AF_INET6);
1090 	if (ipv6nd_scriptrun(rap))
1091 		return;
1092 
1093 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1094 	eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */
1095 
1096 handle_flag:
1097 	if (!(ifp->options->options & DHCPCD_DHCP6))
1098 		goto nodhcp6;
1099 /* Only log a DHCPv6 start error if compiled in or debugging is enabled. */
1100 #ifdef DHCP6
1101 #define LOG_DHCP6	logerr
1102 #else
1103 #define LOG_DHCP6	logdebug
1104 #endif
1105 	if (rap->flags & ND_RA_FLAG_MANAGED) {
1106 		if (new_data && dhcp6_start(ifp, DH6S_REQUEST) == -1)
1107 			LOG_DHCP6("dhcp6_start: %s", ifp->name);
1108 	} else if (rap->flags & ND_RA_FLAG_OTHER) {
1109 		if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)
1110 			LOG_DHCP6("dhcp6_start: %s", ifp->name);
1111 	} else {
1112 		if (new_data)
1113 			logdebugx("%s: No DHCPv6 instruction in RA", ifp->name);
1114 nodhcp6:
1115 		if (ifp->ctx->options & DHCPCD_TEST) {
1116 			eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
1117 			return;
1118 		}
1119 	}
1120 
1121 	/* Expire should be called last as the rap object could be destroyed */
1122 	ipv6nd_expirera(ifp);
1123 }
1124 
1125 int
1126 ipv6nd_hasra(const struct interface *ifp)
1127 {
1128 	const struct ra *rap;
1129 
1130 	if (ifp->ctx->ra_routers) {
1131 		TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next)
1132 			if (rap->iface == ifp && !rap->expired)
1133 				return 1;
1134 	}
1135 	return 0;
1136 }
1137 
1138 int
1139 ipv6nd_hasradhcp(const struct interface *ifp)
1140 {
1141 	const struct ra *rap;
1142 
1143 	if (ifp->ctx->ra_routers) {
1144 		TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
1145 			if (rap->iface == ifp &&
1146 			    !rap->expired &&
1147 			    (rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)))
1148 				return 1;
1149 		}
1150 	}
1151 	return 0;
1152 }
1153 
1154 static const uint8_t *
1155 ipv6nd_getoption(struct dhcpcd_ctx *ctx,
1156     size_t *os, unsigned int *code, size_t *len,
1157     const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
1158 {
1159 	struct nd_opt_hdr ndo;
1160 	size_t i;
1161 	struct dhcp_opt *opt;
1162 
1163 	if (od) {
1164 		*os = sizeof(ndo);
1165 		if (ol < *os) {
1166 			errno = EINVAL;
1167 			return NULL;
1168 		}
1169 		memcpy(&ndo, od, sizeof(ndo));
1170 		i = (size_t)(ndo.nd_opt_len * 8);
1171 		if (i > ol) {
1172 			errno = EINVAL;
1173 			return NULL;
1174 		}
1175 		*len = i;
1176 		*code = ndo.nd_opt_type;
1177 	}
1178 
1179 	for (i = 0, opt = ctx->nd_opts;
1180 	    i < ctx->nd_opts_len; i++, opt++)
1181 	{
1182 		if (opt->option == *code) {
1183 			*oopt = opt;
1184 			break;
1185 		}
1186 	}
1187 
1188 	if (od)
1189 		return od + sizeof(ndo);
1190 	return NULL;
1191 }
1192 
1193 ssize_t
1194 ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
1195 {
1196 	size_t i, j, n, len, olen;
1197 	struct ra *rap;
1198 	char ndprefix[32], abuf[24];
1199 	struct dhcp_opt *opt;
1200 	uint8_t *p;
1201 	struct nd_opt_hdr ndo;
1202 	struct ipv6_addr *ia;
1203 	struct timespec now;
1204 
1205 	clock_gettime(CLOCK_MONOTONIC, &now);
1206 	i = n = 0;
1207 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
1208 		if (rap->iface != ifp)
1209 			continue;
1210 		i++;
1211 		if (prefix != NULL)
1212 			snprintf(ndprefix, sizeof(ndprefix),
1213 			    "%s_nd%zu", prefix, i);
1214 		else
1215 			snprintf(ndprefix, sizeof(ndprefix),
1216 			    "nd%zu", i);
1217 		if (env)
1218 			setvar(&env[n], ndprefix, "from", rap->sfrom);
1219 		n++;
1220 		if (env)
1221 			setvard(&env[n], ndprefix, "acquired",
1222 			    (size_t)rap->acquired.tv_sec);
1223 		n++;
1224 		if (env)
1225 			setvard(&env[n], ndprefix, "now", (size_t)now.tv_sec);
1226 		n++;
1227 
1228 		/* Zero our indexes */
1229 		if (env) {
1230 			for (j = 0, opt = rap->iface->ctx->nd_opts;
1231 			    j < rap->iface->ctx->nd_opts_len;
1232 			    j++, opt++)
1233 				dhcp_zero_index(opt);
1234 			for (j = 0, opt = rap->iface->options->nd_override;
1235 			    j < rap->iface->options->nd_override_len;
1236 			    j++, opt++)
1237 				dhcp_zero_index(opt);
1238 		}
1239 
1240 		/* Unlike DHCP, ND6 options *may* occur more than once.
1241 		 * There is also no provision for option concatenation
1242 		 * unlike DHCP. */
1243 		len = rap->data_len - sizeof(struct nd_router_advert);
1244 		for (p = rap->data + sizeof(struct nd_router_advert);
1245 		    len >= sizeof(ndo);
1246 		    p += olen, len -= olen)
1247 		{
1248 			memcpy(&ndo, p, sizeof(ndo));
1249 			olen = (size_t)(ndo.nd_opt_len * 8);
1250 			if (olen > len) {
1251 				errno =	EINVAL;
1252 				break;
1253 			}
1254 			if (has_option_mask(rap->iface->options->nomasknd,
1255 			    ndo.nd_opt_type))
1256 				continue;
1257 			for (j = 0, opt = rap->iface->options->nd_override;
1258 			    j < rap->iface->options->nd_override_len;
1259 			    j++, opt++)
1260 				if (opt->option == ndo.nd_opt_type)
1261 					break;
1262 			if (j == rap->iface->options->nd_override_len) {
1263 				for (j = 0, opt = rap->iface->ctx->nd_opts;
1264 				    j < rap->iface->ctx->nd_opts_len;
1265 				    j++, opt++)
1266 					if (opt->option == ndo.nd_opt_type)
1267 						break;
1268 				if (j == rap->iface->ctx->nd_opts_len)
1269 					opt = NULL;
1270 			}
1271 			if (opt) {
1272 				n += dhcp_envoption(rap->iface->ctx,
1273 				    env == NULL ? NULL : &env[n],
1274 				    ndprefix, rap->iface->name,
1275 				    opt, ipv6nd_getoption,
1276 				    p + sizeof(ndo), olen - sizeof(ndo));
1277 			}
1278 		}
1279 
1280 		/* We need to output the addresses we actually made
1281 		 * from the prefix information options as well. */
1282 		j = 0;
1283 		TAILQ_FOREACH(ia, &rap->addrs, next) {
1284 			if (!(ia->flags & IPV6_AF_AUTOCONF)
1285 #ifdef IPV6_AF_TEMPORARY
1286 			    || ia->flags & IPV6_AF_TEMPORARY
1287 #endif
1288 			    )
1289 				continue;
1290 			j++;
1291 			if (env) {
1292 				snprintf(abuf, sizeof(abuf), "addr%zu", j);
1293 				setvar(&env[n], ndprefix, abuf, ia->saddr);
1294 			}
1295 			n++;
1296 		}
1297 	}
1298 	return (ssize_t)n;
1299 }
1300 
1301 void
1302 ipv6nd_handleifa(int cmd, struct ipv6_addr *addr, pid_t pid)
1303 {
1304 	struct ra *rap;
1305 
1306 	/* IPv6 init may not have happened yet if we are learning
1307 	 * existing addresses when dhcpcd starts. */
1308 	if (addr->iface->ctx->ra_routers == NULL)
1309 		return;
1310 
1311 	TAILQ_FOREACH(rap, addr->iface->ctx->ra_routers, next) {
1312 		if (rap->iface != addr->iface)
1313 			continue;
1314 		ipv6_handleifa_addrs(cmd, &rap->addrs, addr, pid);
1315 	}
1316 }
1317 
1318 void
1319 ipv6nd_expirera(void *arg)
1320 {
1321 	struct interface *ifp;
1322 	struct ra *rap, *ran;
1323 	struct timespec now, lt, expire, next;
1324 	uint8_t expired, anyvalid, valid, validone;
1325 	struct ipv6_addr *ia;
1326 
1327 	ifp = arg;
1328 	clock_gettime(CLOCK_MONOTONIC, &now);
1329 	expired = 0;
1330 	timespecclear(&next);
1331 
1332 	anyvalid = 0;
1333 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
1334 		if (rap->iface != ifp)
1335 			continue;
1336 		valid = validone = 0;
1337 		if (rap->lifetime) {
1338 			lt.tv_sec = (time_t)rap->lifetime;
1339 			lt.tv_nsec = 0;
1340 			timespecadd(&rap->acquired, &lt, &expire);
1341 			if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
1342 			{
1343 				if (!rap->expired) {
1344 					logwarnx("%s: %s: router expired",
1345 					    ifp->name, rap->sfrom);
1346 					rap->expired = expired = 1;
1347 					rap->lifetime = 0;
1348 				}
1349 			} else {
1350 				valid = 1;
1351 				timespecsub(&expire, &now, &lt);
1352 				if (!timespecisset(&next) ||
1353 				    timespeccmp(&next, &lt, >))
1354 					next = lt;
1355 			}
1356 		}
1357 
1358 		/* Not every prefix is tied to an address which
1359 		 * the kernel can expire, so we need to handle it ourself.
1360 		 * Also, some OS don't support address lifetimes (Solaris). */
1361 		TAILQ_FOREACH(ia, &rap->addrs, next) {
1362 			if (ia->prefix_vltime == 0)
1363 				continue;
1364 			if (ia->prefix_vltime == ND6_INFINITE_LIFETIME) {
1365 				validone = 1;
1366 				continue;
1367 			}
1368 			lt.tv_sec = (time_t)ia->prefix_vltime;
1369 			lt.tv_nsec = 0;
1370 			timespecadd(&ia->acquired, &lt, &expire);
1371 			if (timespeccmp(&now, &expire, >)) {
1372 				if (ia->flags & IPV6_AF_ADDED) {
1373 					logwarnx("%s: expired address %s",
1374 					    ia->iface->name, ia->saddr);
1375 					if (if_address6(RTM_DELADDR, ia)== -1 &&
1376 					    errno != EADDRNOTAVAIL &&
1377 					    errno != ENXIO)
1378 						logerr(__func__);
1379 				}
1380 				ia->prefix_vltime = ia->prefix_pltime = 0;
1381 				ia->flags &=
1382 				    ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
1383 				expired = 1;
1384 			} else {
1385 				timespecsub(&expire, &now, &lt);
1386 				if (!timespecisset(&next) ||
1387 				    timespeccmp(&next, &lt, >))
1388 					next = lt;
1389 				validone = 1;
1390 			}
1391 		}
1392 
1393 		/* XXX FixMe!
1394 		 * We need to extract the lifetime from each option and check
1395 		 * if that has expired or not.
1396 		 * If it has, zero the option out in the returned data. */
1397 
1398 		/* No valid lifetimes are left on the RA, so we might
1399 		 * as well punt it. */
1400 		if (!valid && !validone)
1401 			ipv6nd_free_ra(rap);
1402 		else
1403 			anyvalid = 1;
1404 	}
1405 
1406 	if (timespecisset(&next))
1407 		eloop_timeout_add_tv(ifp->ctx->eloop,
1408 		    &next, ipv6nd_expirera, ifp);
1409 	if (expired) {
1410 		rt_build(ifp->ctx, AF_INET6);
1411 		script_runreason(ifp, "ROUTERADVERT");
1412 	}
1413 
1414 	/* No valid routers? Kill any DHCPv6. */
1415 	if (!anyvalid)
1416 		dhcp6_dropnondelegates(ifp);
1417 }
1418 
1419 void
1420 ipv6nd_drop(struct interface *ifp)
1421 {
1422 	struct ra *rap, *ran;
1423 	uint8_t expired = 0;
1424 
1425 	if (ifp->ctx->ra_routers == NULL)
1426 		return;
1427 
1428 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1429 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
1430 		if (rap->iface == ifp) {
1431 			rap->expired = expired = 1;
1432 			ipv6nd_drop_ra(rap);
1433 		}
1434 	}
1435 	if (expired) {
1436 		rt_build(ifp->ctx, AF_INET6);
1437 		if ((ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP)
1438 			script_runreason(ifp, "ROUTERADVERT");
1439 	}
1440 }
1441 
1442 static void
1443 ipv6nd_handlena(struct dhcpcd_ctx *ctx, struct interface *ifp,
1444     struct icmp6_hdr *icp, size_t len, int hoplimit)
1445 {
1446 	struct nd_neighbor_advert *nd_na;
1447 	struct in6_addr nd_na_target;
1448 	struct ra *rap;
1449 	uint32_t is_router, is_solicited;
1450 	char buf[INET6_ADDRSTRLEN];
1451 	const char *taddr;
1452 
1453 	if (ifp == NULL) {
1454 #ifdef DEBUG_NS
1455 		logdebugx("NA for unexpected interface from %s",
1456 		    ctx->sfrom);
1457 #endif
1458 		return;
1459 	}
1460 
1461 	if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
1462 		logerrx("%s: IPv6 NA too short from %s",
1463 		    ifp->name, ctx->sfrom);
1464 		return;
1465 	}
1466 
1467 	/* RFC 4861 7.1.2 */
1468 	if (hoplimit != 255) {
1469 		logerrx("invalid hoplimit(%d) in NA from %s",
1470 		    hoplimit, ctx->sfrom);
1471 		return;
1472 	}
1473 
1474 	nd_na = (struct nd_neighbor_advert *)icp;
1475 	is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER;
1476 	is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED;
1477 	taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target,
1478 	    buf, INET6_ADDRSTRLEN);
1479 
1480 	/* nd_na->nd_na_target is not aligned. */
1481 	memcpy(&nd_na_target, &nd_na->nd_na_target, sizeof(nd_na_target));
1482 	if (IN6_IS_ADDR_MULTICAST(&nd_na_target)) {
1483 		logerrx("%s: NA multicast address %s (%s)",
1484 		    ifp->name, taddr, ctx->sfrom);
1485 		return;
1486 	}
1487 
1488 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
1489 		if (rap->iface == ifp &&
1490 		    IN6_ARE_ADDR_EQUAL(&rap->from, &nd_na_target))
1491 			break;
1492 	}
1493 	if (rap == NULL) {
1494 #ifdef DEBUG_NS
1495 		logdebugx("%s: unexpected NA from %s for %s",
1496 		    ifp->name, ctx->sfrom, taddr);
1497 #endif
1498 		return;
1499 	}
1500 
1501 #ifdef DEBUG_NS
1502 	logdebugx("%s: %sNA for %s from %s",
1503 	    ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom);
1504 #endif
1505 
1506 	/* Node is no longer a router, so remove it from consideration */
1507 	if (!is_router && !rap->expired) {
1508 		loginfox("%s: %s not a router (%s)",
1509 		    ifp->name, taddr, ctx->sfrom);
1510 		rap->expired = 1;
1511 		rt_build(ifp->ctx,  AF_INET6);
1512 		script_runreason(ifp, "ROUTERADVERT");
1513 		return;
1514 	}
1515 
1516 	if (is_solicited && is_router && rap->lifetime)
1517 		ipv6nd_reachable(rap, IPV6ND_REACHABLE);
1518 }
1519 
1520 static void
1521 ipv6nd_handledata(void *arg)
1522 {
1523 	struct dhcpcd_ctx *ctx;
1524 	ssize_t len;
1525 	struct cmsghdr *cm;
1526 	int hoplimit;
1527 	struct in6_pktinfo pkt;
1528 	struct icmp6_hdr *icp;
1529 	struct interface *ifp;
1530 
1531 	ctx = arg;
1532 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1533 	    CMSG_SPACE(sizeof(int));
1534 	len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0);
1535 	if (len == -1) {
1536 		logerr(__func__);
1537 		return;
1538 	}
1539 	ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
1540 	    ctx->ntopbuf, INET6_ADDRSTRLEN);
1541 	if ((size_t)len < sizeof(struct icmp6_hdr)) {
1542 		logerrx("IPv6 ICMP packet too short from %s", ctx->sfrom);
1543 		return;
1544 	}
1545 
1546 	pkt.ipi6_ifindex = 0;
1547 	hoplimit = 0;
1548 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&ctx->rcvhdr);
1549 	     cm;
1550 	     cm = (struct cmsghdr *)CMSG_NXTHDR(&ctx->rcvhdr, cm))
1551 	{
1552 		if (cm->cmsg_level != IPPROTO_IPV6)
1553 			continue;
1554 		switch(cm->cmsg_type) {
1555 		case IPV6_PKTINFO:
1556 			if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
1557 				memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
1558 			break;
1559 		case IPV6_HOPLIMIT:
1560 			if (cm->cmsg_len == CMSG_LEN(sizeof(int)))
1561 				memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int));
1562 			break;
1563 		}
1564 	}
1565 
1566 	if (pkt.ipi6_ifindex == 0) {
1567 		logerrx("IPv6 RA/NA did not contain index from %s", ctx->sfrom);
1568 		return;
1569 	}
1570 
1571 	/* Find the receiving interface */
1572 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1573 		if (ifp->index == (unsigned int)pkt.ipi6_ifindex)
1574 			break;
1575 	}
1576 
1577 	/* Don't do anything if the user hasn't configured it. */
1578 	if (ifp != NULL &&
1579 	    (ifp->active != IF_ACTIVE_USER ||
1580 	    !(ifp->options->options & DHCPCD_IPV6)))
1581 		return;
1582 
1583 	icp = (struct icmp6_hdr *)ctx->rcvhdr.msg_iov[0].iov_base;
1584 	if (icp->icmp6_code == 0) {
1585 		switch(icp->icmp6_type) {
1586 			case ND_NEIGHBOR_ADVERT:
1587 				ipv6nd_handlena(ctx, ifp, icp, (size_t)len,
1588 				   hoplimit);
1589 				return;
1590 			case ND_ROUTER_ADVERT:
1591 				ipv6nd_handlera(ctx, ifp, icp, (size_t)len,
1592 				   hoplimit);
1593 				return;
1594 		}
1595 	}
1596 
1597 	logerrx("invalid IPv6 type %d or code %d from %s",
1598 	    icp->icmp6_type, icp->icmp6_code, ctx->sfrom);
1599 }
1600 
1601 static void
1602 ipv6nd_startrs1(void *arg)
1603 {
1604 	struct interface *ifp = arg;
1605 	struct rs_state *state;
1606 
1607 	loginfox("%s: soliciting an IPv6 router", ifp->name);
1608 	if (ipv6nd_open(ifp->ctx) == -1) {
1609 		logerr(__func__);
1610 		return;
1611 	}
1612 
1613 	state = RS_STATE(ifp);
1614 	if (state == NULL) {
1615 		ifp->if_data[IF_DATA_IPV6ND] = calloc(1, sizeof(*state));
1616 		state = RS_STATE(ifp);
1617 		if (state == NULL) {
1618 			logerr(__func__);
1619 			return;
1620 		}
1621 	}
1622 
1623 	/* Always make a new probe as the underlying hardware
1624 	 * address could have changed. */
1625 	ipv6nd_makersprobe(ifp);
1626 	if (state->rs == NULL) {
1627 		logerr(__func__);
1628 		return;
1629 	}
1630 
1631 	state->rsprobes = 0;
1632 	ipv6nd_sendrsprobe(ifp);
1633 }
1634 
1635 void
1636 ipv6nd_startrs(struct interface *ifp)
1637 {
1638 	struct timespec tv;
1639 
1640 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1641 	if (!(ifp->options->options & DHCPCD_INITIAL_DELAY)) {
1642 		ipv6nd_startrs1(ifp);
1643 		return;
1644 	}
1645 
1646 	tv.tv_sec = 0;
1647 	tv.tv_nsec = (suseconds_t)arc4random_uniform(
1648 	    MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
1649 	timespecnorm(&tv);
1650 	logdebugx("%s: delaying IPv6 router solicitation for %0.1f seconds",
1651 	    ifp->name, timespec_to_double(&tv));
1652 	eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
1653 	return;
1654 }
1655