xref: /netbsd-src/external/bsd/dhcpcd/dist/src/ipv6nd.c (revision 7c192b2a5e1093666e67801684f930ef49b3b363)
1 /*
2  * dhcpcd - IPv6 ND handling
3  * Copyright (c) 2006-2017 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 void
162 ipv6nd_printoptions(const struct dhcpcd_ctx *ctx,
163     const struct dhcp_opt *opts, size_t opts_len)
164 {
165 	size_t i, j;
166 	const struct dhcp_opt *opt, *opt2;
167 	int cols;
168 
169 	for (i = 0, opt = ctx->nd_opts;
170 	    i < ctx->nd_opts_len; i++, opt++)
171 	{
172 		for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
173 			if (opt2->option == opt->option)
174 				break;
175 		if (j == opts_len) {
176 			cols = printf("%03d %s", opt->option, opt->var);
177 			dhcp_print_option_encoding(opt, cols);
178 		}
179 	}
180 	for (i = 0, opt = opts; i < opts_len; i++, opt++) {
181 		cols = printf("%03d %s", opt->option, opt->var);
182 		dhcp_print_option_encoding(opt, cols);
183 	}
184 }
185 
186 static int
187 ipv6nd_open(struct dhcpcd_ctx *ctx)
188 {
189 	int on;
190 	struct icmp6_filter filt;
191 
192 	if (ctx->nd_fd != -1)
193 		return ctx->nd_fd;
194 #define SOCK_FLAGS	SOCK_CLOEXEC | SOCK_NONBLOCK
195 	ctx->nd_fd = xsocket(PF_INET6, SOCK_RAW | SOCK_FLAGS, IPPROTO_ICMPV6);
196 #undef SOCK_FLAGS
197 	if (ctx->nd_fd == -1)
198 		return -1;
199 
200 	/* RFC4861 4.1 */
201 	on = 255;
202 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
203 	    &on, sizeof(on)) == -1)
204 		goto eexit;
205 
206 	on = 1;
207 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
208 	    &on, sizeof(on)) == -1)
209 		goto eexit;
210 
211 	on = 1;
212 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
213 	    &on, sizeof(on)) == -1)
214 		goto eexit;
215 
216 	ICMP6_FILTER_SETBLOCKALL(&filt);
217 	ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt);
218 	ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
219 	if (setsockopt(ctx->nd_fd, IPPROTO_ICMPV6, ICMP6_FILTER,
220 	    &filt, sizeof(filt)) == -1)
221 		goto eexit;
222 
223 	eloop_event_add(ctx->eloop, ctx->nd_fd,  ipv6nd_handledata, ctx);
224 	return ctx->nd_fd;
225 
226 eexit:
227 	if (ctx->nd_fd != -1) {
228 		eloop_event_delete(ctx->eloop, ctx->nd_fd);
229 		close(ctx->nd_fd);
230 		ctx->nd_fd = -1;
231 	}
232 	return -1;
233 }
234 
235 static int
236 ipv6nd_makersprobe(struct interface *ifp)
237 {
238 	struct rs_state *state;
239 	struct nd_router_solicit *rs;
240 	struct nd_opt_hdr *nd;
241 
242 	state = RS_STATE(ifp);
243 	free(state->rs);
244 	state->rslen = sizeof(*rs) + (size_t)ROUNDUP8(ifp->hwlen + 2);
245 	state->rs = calloc(1, state->rslen);
246 	if (state->rs == NULL)
247 		return -1;
248 	rs = (void *)state->rs;
249 	rs->nd_rs_type = ND_ROUTER_SOLICIT;
250 	rs->nd_rs_code = 0;
251 	rs->nd_rs_cksum = 0;
252 	rs->nd_rs_reserved = 0;
253 	nd = (struct nd_opt_hdr *)(state->rs + sizeof(*rs));
254 	nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
255 	nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3);
256 	memcpy(nd + 1, ifp->hwaddr, ifp->hwlen);
257 	return 0;
258 }
259 
260 static void
261 ipv6nd_sendrsprobe(void *arg)
262 {
263 	struct interface *ifp = arg;
264 	struct dhcpcd_ctx *ctx;
265 	struct rs_state *state;
266 	struct sockaddr_in6 dst;
267 	struct cmsghdr *cm;
268 	struct in6_pktinfo pi;
269 
270 	if (ipv6_linklocal(ifp) == NULL) {
271 		logdebugx("%s: delaying Router Solicitation for LL address",
272 		    ifp->name);
273 		ipv6_addlinklocalcallback(ifp, ipv6nd_sendrsprobe, ifp);
274 		return;
275 	}
276 
277 	memset(&dst, 0, sizeof(dst));
278 	dst.sin6_family = AF_INET6;
279 #ifdef SIN6_LEN
280 	dst.sin6_len = sizeof(dst);
281 #endif
282 	dst.sin6_scope_id = ifp->index;
283 	if (inet_pton(AF_INET6, ALLROUTERS, &dst.sin6_addr) != 1) {
284 		logerr(__func__);
285 		return;
286 	}
287 
288 	state = RS_STATE(ifp);
289 	ctx = ifp->ctx;
290 	ctx->sndhdr.msg_name = (void *)&dst;
291 	ctx->sndhdr.msg_iov[0].iov_base = state->rs;
292 	ctx->sndhdr.msg_iov[0].iov_len = state->rslen;
293 
294 	/* Set the outbound interface */
295 	cm = CMSG_FIRSTHDR(&ctx->sndhdr);
296 	if (cm == NULL) /* unlikely */
297 		return;
298 	cm->cmsg_level = IPPROTO_IPV6;
299 	cm->cmsg_type = IPV6_PKTINFO;
300 	cm->cmsg_len = CMSG_LEN(sizeof(pi));
301 	memset(&pi, 0, sizeof(pi));
302 	pi.ipi6_ifindex = ifp->index;
303 	memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
304 
305 	logdebugx("%s: sending Router Solicitation", ifp->name);
306 	if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) {
307 		logerr(__func__);
308 		/* Allow IPv6ND to continue .... at most a few errors
309 		 * would be logged.
310 		 * Generally the error is ENOBUFS when struggling to
311 		 * associate with an access point. */
312 	}
313 
314 	if (state->rsprobes++ < MAX_RTR_SOLICITATIONS)
315 		eloop_timeout_add_sec(ifp->ctx->eloop,
316 		    RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
317 	else {
318 		logwarnx("%s: no IPv6 Routers available", ifp->name);
319 		ipv6nd_drop(ifp);
320 		dhcp6_dropnondelegates(ifp);
321 	}
322 }
323 
324 void
325 ipv6nd_expire(struct interface *ifp, uint32_t seconds)
326 {
327 	struct ra *rap;
328 	struct timespec now;
329 
330 	if (ifp->ctx->ra_routers == NULL)
331 		return;
332 
333 	clock_gettime(CLOCK_MONOTONIC, &now);
334 
335 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
336 		if (rap->iface == ifp) {
337 			rap->acquired = now;
338 			rap->expired = seconds ? 0 : 1;
339 			if (seconds) {
340 				struct ipv6_addr *ap;
341 
342 				rap->lifetime = seconds;
343 				TAILQ_FOREACH(ap, &rap->addrs, next) {
344 					if (ap->prefix_vltime) {
345 						ap->prefix_vltime = seconds;
346 						ap->prefix_pltime = seconds / 2;
347 					}
348 				}
349 				ipv6_addaddrs(&rap->addrs);
350 			}
351 		}
352 	}
353 	if (seconds)
354 		ipv6nd_expirera(ifp);
355 	else
356 		rt_build(ifp->ctx, AF_INET6);
357 }
358 
359 static void
360 ipv6nd_reachable(struct ra *rap, int flags)
361 {
362 
363 	if (flags & IPV6ND_REACHABLE) {
364 		if (rap->lifetime && rap->expired) {
365 			loginfox("%s: %s is reachable again",
366 			    rap->iface->name, rap->sfrom);
367 			rap->expired = 0;
368 			rt_build(rap->iface->ctx, AF_INET6);
369 			/* XXX Not really an RA */
370 			script_runreason(rap->iface, "ROUTERADVERT");
371 		}
372 	} else {
373 		if (rap->lifetime && !rap->expired) {
374 			logwarnx("%s: %s is unreachable, expiring it",
375 			    rap->iface->name, rap->sfrom);
376 			rap->expired = 1;
377 			rt_build(rap->iface->ctx, AF_INET6);
378 			/* XXX Not really an RA */
379 			script_runreason(rap->iface, "ROUTERADVERT");
380 		}
381 	}
382 }
383 
384 void
385 ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags)
386 {
387 	struct ra *rap;
388 
389 	if (ctx->ra_routers) {
390 	        TAILQ_FOREACH(rap, ctx->ra_routers, next) {
391 			if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) {
392 				ipv6nd_reachable(rap, flags);
393 				break;
394 			}
395 		}
396 	}
397 }
398 
399 const struct ipv6_addr *
400 ipv6nd_iffindaddr(const struct interface *ifp, const struct in6_addr *addr,
401     short flags)
402 {
403 	struct ra *rap;
404 	struct ipv6_addr *ap;
405 
406 	if (ifp->ctx->ra_routers == NULL)
407 		return NULL;
408 
409 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
410 		if (rap->iface != ifp)
411 			continue;
412 		TAILQ_FOREACH(ap, &rap->addrs, next) {
413 			if (ipv6_findaddrmatch(ap, addr, flags))
414 				return ap;
415 		}
416 	}
417 	return NULL;
418 }
419 
420 struct ipv6_addr *
421 ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
422     short flags)
423 {
424 	struct ra *rap;
425 	struct ipv6_addr *ap;
426 
427 	if (ctx->ra_routers == NULL)
428 		return NULL;
429 
430 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
431 		TAILQ_FOREACH(ap, &rap->addrs, next) {
432 			if (ipv6_findaddrmatch(ap, addr, flags))
433 				return ap;
434 		}
435 	}
436 	return NULL;
437 }
438 
439 static void
440 ipv6nd_removefreedrop_ra(struct ra *rap, int remove_ra, int drop_ra)
441 {
442 
443 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface);
444 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
445 	if (remove_ra && !drop_ra)
446 		TAILQ_REMOVE(rap->iface->ctx->ra_routers, rap, next);
447 	ipv6_freedrop_addrs(&rap->addrs, drop_ra, NULL);
448 	free(rap->data);
449 	free(rap);
450 }
451 
452 void
453 ipv6nd_freedrop_ra(struct ra *rap, int drop)
454 {
455 
456 	ipv6nd_removefreedrop_ra(rap, 1, drop);
457 }
458 
459 ssize_t
460 ipv6nd_free(struct interface *ifp)
461 {
462 	struct rs_state *state;
463 	struct ra *rap, *ran;
464 	struct dhcpcd_ctx *ctx;
465 	ssize_t n;
466 
467 	state = RS_STATE(ifp);
468 	if (state == NULL)
469 		return 0;
470 
471 	free(state->rs);
472 	free(state);
473 	ifp->if_data[IF_DATA_IPV6ND] = NULL;
474 	n = 0;
475 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
476 		if (rap->iface == ifp) {
477 			ipv6nd_free_ra(rap);
478 			n++;
479 		}
480 	}
481 
482 	/* If we don't have any more IPv6 enabled interfaces,
483 	 * close the global socket and release resources */
484 	ctx = ifp->ctx;
485 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
486 		if (RS_STATE(ifp))
487 			break;
488 	}
489 	if (ifp == NULL) {
490 		if (ctx->nd_fd != -1) {
491 			eloop_event_delete(ctx->eloop, ctx->nd_fd);
492 			close(ctx->nd_fd);
493 			ctx->nd_fd = -1;
494 		}
495 	}
496 
497 	return n;
498 }
499 
500 static int
501 rtpref(struct ra *rap)
502 {
503 
504 	switch (rap->flags & ND_RA_FLAG_RTPREF_MASK) {
505 	case ND_RA_FLAG_RTPREF_HIGH:
506 		return (RTPREF_HIGH);
507 	case ND_RA_FLAG_RTPREF_MEDIUM:
508 	case ND_RA_FLAG_RTPREF_RSV:
509 		return (RTPREF_MEDIUM);
510 	case ND_RA_FLAG_RTPREF_LOW:
511 		return (RTPREF_LOW);
512 	default:
513 		logerrx("rtpref: impossible RA flag %x", rap->flags);
514 		return (RTPREF_INVALID);
515 	}
516 	/* NOTREACHED */
517 }
518 
519 static void
520 add_router(struct dhcpcd_ctx *ctx, struct ra *router)
521 {
522 	struct ra *rap;
523 
524 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
525 		if (router->iface->metric < rap->iface->metric ||
526 		    (router->iface->metric == rap->iface->metric &&
527 		    rtpref(router) > rtpref(rap)))
528 		{
529 			TAILQ_INSERT_BEFORE(rap, router, next);
530 			return;
531 		}
532 	}
533 	TAILQ_INSERT_TAIL(ctx->ra_routers, router, next);
534 }
535 
536 static int
537 ipv6nd_scriptrun(struct ra *rap)
538 {
539 	int hasdns, hasaddress, pid;
540 	struct ipv6_addr *ap;
541 
542 	hasaddress = 0;
543 	/* If all addresses have completed DAD run the script */
544 	TAILQ_FOREACH(ap, &rap->addrs, next) {
545 		if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) ==
546 		    (IPV6_AF_AUTOCONF | IPV6_AF_ADDED))
547 		{
548 			hasaddress = 1;
549 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
550 			    ipv6_iffindaddr(ap->iface, &ap->addr,
551 			    IN6_IFF_TENTATIVE))
552 				ap->flags |= IPV6_AF_DADCOMPLETED;
553 			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
554 				logdebugx("%s: waiting for Router Advertisement"
555 				    " DAD to complete",
556 				    rap->iface->name);
557 				return 0;
558 			}
559 		}
560 	}
561 
562 	/* If we don't require RDNSS then set hasdns = 1 so we fork */
563 	if (!(rap->iface->options->options & DHCPCD_IPV6RA_REQRDNSS))
564 		hasdns = 1;
565 	else {
566 		hasdns = rap->hasdns;
567 	}
568 
569 	script_runreason(rap->iface, "ROUTERADVERT");
570 	pid = 0;
571 	if (hasdns && (hasaddress ||
572 	    !(rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))))
573 		pid = dhcpcd_daemonise(rap->iface->ctx);
574 #if 0
575 	else if (options & DHCPCD_DAEMONISE &&
576 	    !(options & DHCPCD_DAEMONISED) && new_data)
577 		logwarnx("%s: did not fork due to an absent"
578 		    " RDNSS option in the RA",
579 		    ifp->name);
580 }
581 #endif
582 	return pid;
583 }
584 
585 static void
586 ipv6nd_addaddr(void *arg)
587 {
588 	struct ipv6_addr *ap = arg;
589 
590 	ipv6_addaddr(ap, NULL);
591 }
592 
593 int
594 ipv6nd_dadcompleted(const struct interface *ifp)
595 {
596 	const struct ra *rap;
597 	const struct ipv6_addr *ap;
598 
599 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
600 		if (rap->iface != ifp)
601 			continue;
602 		TAILQ_FOREACH(ap, &rap->addrs, next) {
603 			if (ap->flags & IPV6_AF_AUTOCONF &&
604 			    ap->flags & IPV6_AF_ADDED &&
605 			    !(ap->flags & IPV6_AF_DADCOMPLETED))
606 				return 0;
607 		}
608 	}
609 	return 1;
610 }
611 
612 static void
613 ipv6nd_dadcallback(void *arg)
614 {
615 	struct ipv6_addr *ap = arg, *rapap;
616 	struct interface *ifp;
617 	struct ra *rap;
618 	int wascompleted, found;
619 	struct timespec tv;
620 	char buf[INET6_ADDRSTRLEN];
621 	const char *p;
622 	int dadcounter;
623 
624 	ifp = ap->iface;
625 	wascompleted = (ap->flags & IPV6_AF_DADCOMPLETED);
626 	ap->flags |= IPV6_AF_DADCOMPLETED;
627 	if (ap->flags & IPV6_AF_DUPLICATED) {
628 		ap->dadcounter++;
629 		logwarnx("%s: DAD detected %s", ifp->name, ap->saddr);
630 
631 		/* Try and make another stable private address.
632 		 * Because ap->dadcounter is always increamented,
633 		 * a different address is generated. */
634 		/* XXX Cache DAD counter per prefix/id/ssid? */
635 		if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
636 			if (ap->dadcounter >= IDGEN_RETRIES) {
637 				logerrx("%s: unable to obtain a"
638 				    " stable private address",
639 				    ifp->name);
640 				goto try_script;
641 			}
642 			loginfox("%s: deleting address %s",
643 			    ifp->name, ap->saddr);
644 			if (if_address6(RTM_DELADDR, ap) == -1 &&
645 			    errno != EADDRNOTAVAIL && errno != ENXIO)
646 				logerr(__func__);
647 			dadcounter = ap->dadcounter;
648 			if (ipv6_makestableprivate(&ap->addr,
649 			    &ap->prefix, ap->prefix_len,
650 			    ifp, &dadcounter) == -1)
651 			{
652 				logerr("ipv6_makestableprivate");
653 				return;
654 			}
655 			ap->dadcounter = dadcounter;
656 			ap->flags &= ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
657 			ap->flags |= IPV6_AF_NEW;
658 			p = inet_ntop(AF_INET6, &ap->addr, buf, sizeof(buf));
659 			if (p)
660 				snprintf(ap->saddr,
661 				    sizeof(ap->saddr),
662 				    "%s/%d",
663 				    p, ap->prefix_len);
664 			else
665 				ap->saddr[0] = '\0';
666 			tv.tv_sec = 0;
667 			tv.tv_nsec = (suseconds_t)
668 			    arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC);
669 			timespecnorm(&tv);
670 			eloop_timeout_add_tv(ifp->ctx->eloop, &tv,
671 			    ipv6nd_addaddr, ap);
672 			return;
673 		}
674 	}
675 
676 try_script:
677 	if (!wascompleted) {
678 		TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
679 			if (rap->iface != ifp)
680 				continue;
681 			wascompleted = 1;
682 			found = 0;
683 			TAILQ_FOREACH(rapap, &rap->addrs, next) {
684 				if (rapap->flags & IPV6_AF_AUTOCONF &&
685 				    rapap->flags & IPV6_AF_ADDED &&
686 				    (rapap->flags & IPV6_AF_DADCOMPLETED) == 0)
687 				{
688 					wascompleted = 0;
689 					break;
690 				}
691 				if (rapap == ap)
692 					found = 1;
693 			}
694 
695 			if (wascompleted && found) {
696 				logdebugx("%s: Router Advertisement DAD "
697 				    "completed",
698 				    rap->iface->name);
699 				if (ipv6nd_scriptrun(rap))
700 					return;
701 			}
702 		}
703 	}
704 }
705 
706 #ifndef DHCP6
707 /* If DHCPv6 is compiled out, supply a shim to provide an error message
708  * if IPv6RA requests DHCPv6. */
709 #undef dhcp6_start
710 static int
711 dhcp6_start(__unused struct interface *ifp, __unused enum DH6S init_state)
712 {
713 
714 	errno = ENOTSUP;
715 	return -1;
716 }
717 #endif
718 
719 static void
720 ipv6nd_handlera(struct dhcpcd_ctx *ctx, struct interface *ifp,
721     struct icmp6_hdr *icp, size_t len, int hoplimit)
722 {
723 	size_t i, olen;
724 	struct nd_router_advert *nd_ra;
725 	struct nd_opt_hdr ndo;
726 	struct nd_opt_prefix_info pi;
727 	struct nd_opt_mtu mtu;
728 	struct nd_opt_rdnss rdnss;
729 	uint8_t *p;
730 	char buf[INET6_ADDRSTRLEN];
731 	const char *cbp;
732 	struct ra *rap;
733 	struct in6_addr pi_prefix;
734 	struct ipv6_addr *ap;
735 	struct dhcp_opt *dho;
736 	uint8_t new_rap, new_data;
737 	__printflike(1, 2) void (*logfunc)(const char *, ...);
738 #ifdef IPV6_MANAGETEMPADDR
739 	uint8_t new_ap;
740 #endif
741 
742 	if (ifp == NULL) {
743 #ifdef DEBUG_RS
744 		logdebugx("RA for unexpected interface from %s",
745 		    ctx->sfrom);
746 #endif
747 		return;
748 	}
749 
750 	if (len < sizeof(struct nd_router_advert)) {
751 		logerr("IPv6 RA packet too short from %s", ctx->sfrom);
752 		return;
753 	}
754 
755 	/* RFC 4861 7.1.2 */
756 	if (hoplimit != 255) {
757 		logerr("invalid hoplimit(%d) in RA from %s",
758 		    hoplimit, ctx->sfrom);
759 		return;
760 	}
761 
762 	if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
763 		logerr("RA from non local address %s", ctx->sfrom);
764 		return;
765 	}
766 
767 	if (!(ifp->options->options & DHCPCD_IPV6RS)) {
768 #ifdef DEBUG_RS
769 		logerr("%s: unexpected RA from %s",
770 		    ifp->name, ctx->sfrom);
771 #endif
772 		return;
773 	}
774 
775 	/* We could receive a RA before we sent a RS*/
776 	if (ipv6_linklocal(ifp) == NULL) {
777 #ifdef DEBUG_RS
778 		logdebugx("%s: received RA from %s (no link-local)",
779 		    ifp->name, ctx->sfrom);
780 #endif
781 		return;
782 	}
783 
784 	if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr, IN6_IFF_TENTATIVE)) {
785 		logdebugx("%s: ignoring RA from ourself %s",
786 		    ifp->name, ctx->sfrom);
787 		return;
788 	}
789 
790 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
791 		if (ifp == rap->iface &&
792 		    IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr))
793 			break;
794 	}
795 
796 	nd_ra = (struct nd_router_advert *)icp;
797 
798 	/* We don't want to spam the log with the fact we got an RA every
799 	 * 30 seconds or so, so only spam the log if it's different. */
800 	if (rap == NULL || (rap->data_len != len ||
801 	     memcmp(rap->data, (unsigned char *)icp, rap->data_len) != 0))
802 	{
803 		if (rap) {
804 			free(rap->data);
805 			rap->data_len = 0;
806 		}
807 		new_data = 1;
808 	} else
809 		new_data = 0;
810 	if (rap == NULL) {
811 		rap = calloc(1, sizeof(*rap));
812 		if (rap == NULL) {
813 			logerr(__func__);
814 			return;
815 		}
816 		rap->iface = ifp;
817 		rap->from = ctx->from.sin6_addr;
818 		strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
819 		TAILQ_INIT(&rap->addrs);
820 		new_rap = 1;
821 	} else
822 		new_rap = 0;
823 	if (rap->data_len == 0) {
824 		rap->data = malloc(len);
825 		if (rap->data == NULL) {
826 			logerr(__func__);
827 			if (new_rap)
828 				free(rap);
829 			return;
830 		}
831 		memcpy(rap->data, icp, len);
832 		rap->data_len = len;
833 	}
834 
835 	/* We could change the debug level based on new_data, but some
836 	 * routers like to decrease the advertised valid and preferred times
837 	 * in accordance with the own prefix times which would result in too
838 	 * much needless log spam. */
839 	logfunc = new_rap ? loginfox : logdebugx,
840 	logfunc("%s: Router Advertisement from %s",
841 	    ifp->name, ctx->sfrom);
842 
843 	clock_gettime(CLOCK_MONOTONIC, &rap->acquired);
844 	rap->flags = nd_ra->nd_ra_flags_reserved;
845 	rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
846 	if (nd_ra->nd_ra_reachable) {
847 		rap->reachable = ntohl(nd_ra->nd_ra_reachable);
848 		if (rap->reachable > MAX_REACHABLE_TIME)
849 			rap->reachable = 0;
850 	}
851 	if (nd_ra->nd_ra_retransmit)
852 		rap->retrans = ntohl(nd_ra->nd_ra_retransmit);
853 	if (rap->lifetime)
854 		rap->expired = 0;
855 	rap->hasdns = 0;
856 
857 	ipv6_settempstale(ifp);
858 	TAILQ_FOREACH(ap, &rap->addrs, next) {
859 		ap->flags |= IPV6_AF_STALE;
860 	}
861 
862 	len -= sizeof(struct nd_router_advert);
863 	p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
864 	for (; len > 0; p += olen, len -= olen) {
865 		if (len < sizeof(ndo)) {
866 			logerrx("%s: short option", ifp->name);
867 			break;
868 		}
869 		memcpy(&ndo, p, sizeof(ndo));
870 		olen = (size_t)ndo.nd_opt_len * 8;
871 		if (olen == 0) {
872 			logerrx("%s: zero length option", ifp->name);
873 			break;
874 		}
875 		if (olen > len) {
876 			logerrx("%s: option length exceeds message",
877 			    ifp->name);
878 			break;
879 		}
880 
881 		if (has_option_mask(ifp->options->rejectmasknd,
882 		    ndo.nd_opt_type))
883 		{
884 			for (i = 0, dho = ctx->nd_opts;
885 			    i < ctx->nd_opts_len;
886 			    i++, dho++)
887 			{
888 				if (dho->option == ndo.nd_opt_type)
889 					break;
890 			}
891 			if (dho != NULL)
892 				logwarnx("%s: reject RA (option %s) from %s",
893 				    ifp->name, dho->var, ctx->sfrom);
894 			else
895 				logwarnx("%s: reject RA (option %d) from %s",
896 				    ifp->name, ndo.nd_opt_type, ctx->sfrom);
897 			if (new_rap)
898 				ipv6nd_removefreedrop_ra(rap, 0, 0);
899 			else
900 				ipv6nd_free_ra(rap);
901 			return;
902 		}
903 
904 		if (has_option_mask(ifp->options->nomasknd, ndo.nd_opt_type))
905 			continue;
906 
907 		switch (ndo.nd_opt_type) {
908 		case ND_OPT_PREFIX_INFORMATION:
909 			logfunc = new_data ? logerrx : logdebugx;
910 			if (ndo.nd_opt_len != 4) {
911 				logfunc("%s: invalid option len for prefix",
912 				    ifp->name);
913 				continue;
914 			}
915 			memcpy(&pi, p, sizeof(pi));
916 			if (pi.nd_opt_pi_prefix_len > 128) {
917 				logfunc("%s: invalid prefix len", ifp->name);
918 				continue;
919 			}
920 			/* nd_opt_pi_prefix is not aligned. */
921 			memcpy(&pi_prefix, &pi.nd_opt_pi_prefix,
922 			    sizeof(pi_prefix));
923 			if (IN6_IS_ADDR_MULTICAST(&pi_prefix) ||
924 			    IN6_IS_ADDR_LINKLOCAL(&pi_prefix))
925 			{
926 				logfunc("%s: invalid prefix in RA", ifp->name);
927 				continue;
928 			}
929 			if (ntohl(pi.nd_opt_pi_preferred_time) >
930 			    ntohl(pi.nd_opt_pi_valid_time))
931 			{
932 				logfunc("%s: pltime > vltime", ifp->name);
933 				continue;
934 			}
935 			TAILQ_FOREACH(ap, &rap->addrs, next)
936 				if (ap->prefix_len ==pi.nd_opt_pi_prefix_len &&
937 				    IN6_ARE_ADDR_EQUAL(&ap->prefix, &pi_prefix))
938 					break;
939 			if (ap == NULL) {
940 				if (!(pi.nd_opt_pi_flags_reserved &
941 				    ND_OPT_PI_FLAG_AUTO) &&
942 				    !(pi.nd_opt_pi_flags_reserved &
943 				    ND_OPT_PI_FLAG_ONLINK))
944 					continue;
945 				ap = calloc(1, sizeof(*ap));
946 				if (ap == NULL) {
947 					logerr(__func__);
948 					break;
949 				}
950 				ap->iface = rap->iface;
951 				ap->flags = IPV6_AF_NEW;
952 				ap->prefix_len = pi.nd_opt_pi_prefix_len;
953 				ap->prefix = pi_prefix;
954 				if (pi.nd_opt_pi_flags_reserved &
955 				    ND_OPT_PI_FLAG_AUTO &&
956 				    ap->iface->options->options &
957 				    DHCPCD_IPV6RA_AUTOCONF)
958 				{
959 					ap->flags |= IPV6_AF_AUTOCONF;
960 					ap->dadcounter =
961 					    ipv6_makeaddr(&ap->addr, ifp,
962 					    &ap->prefix,
963 					    pi.nd_opt_pi_prefix_len);
964 					if (ap->dadcounter == -1) {
965 						free(ap);
966 						break;
967 					}
968 					cbp = inet_ntop(AF_INET6,
969 					    &ap->addr,
970 					    buf, sizeof(buf));
971 					if (cbp)
972 						snprintf(ap->saddr,
973 						    sizeof(ap->saddr),
974 						    "%s/%d",
975 						    cbp, ap->prefix_len);
976 					else
977 						ap->saddr[0] = '\0';
978 				} else {
979 					memset(&ap->addr, 0, sizeof(ap->addr));
980 					ap->saddr[0] = '\0';
981 				}
982 				ap->dadcallback = ipv6nd_dadcallback;
983 				ap->created = ap->acquired = rap->acquired;
984 				TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
985 
986 #ifdef IPV6_MANAGETEMPADDR
987 				/* New address to dhcpcd RA handling.
988 				 * If the address already exists and a valid
989 				 * temporary address also exists then
990 				 * extend the existing one rather than
991 				 * create a new one */
992 				if (ipv6_iffindaddr(ifp, &ap->addr,
993 				    IN6_IFF_NOTUSEABLE) &&
994 				    ipv6_settemptime(ap, 0))
995 					new_ap = 0;
996 				else
997 					new_ap = 1;
998 #endif
999 			} else {
1000 #ifdef IPV6_MANAGETEMPADDR
1001 				new_ap = 0;
1002 #endif
1003 				ap->flags &= ~IPV6_AF_STALE;
1004 				ap->acquired = rap->acquired;
1005 			}
1006 			if (pi.nd_opt_pi_flags_reserved &
1007 			    ND_OPT_PI_FLAG_ONLINK)
1008 				ap->flags |= IPV6_AF_ONLINK;
1009 			ap->prefix_vltime =
1010 			    ntohl(pi.nd_opt_pi_valid_time);
1011 			ap->prefix_pltime =
1012 			    ntohl(pi.nd_opt_pi_preferred_time);
1013 			ap->nsprobes = 0;
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_INIT) == -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)
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);
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, 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 	validone = 0;
1333 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ra_routers, next, ran) {
1334 		if (rap->iface != ifp)
1335 			continue;
1336 		valid = 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 == ND6_INFINITE_LIFETIME ||
1363 			    ia->prefix_vltime == 0)
1364 				continue;
1365 			lt.tv_sec = (time_t)ia->prefix_vltime;
1366 			lt.tv_nsec = 0;
1367 			timespecadd(&ia->acquired, &lt, &expire);
1368 			if (timespeccmp(&now, &expire, >)) {
1369 				if (ia->flags & IPV6_AF_ADDED) {
1370 					logwarnx("%s: expired address %s",
1371 					    ia->iface->name, ia->saddr);
1372 					if (if_address6(RTM_DELADDR, ia)== -1 &&
1373 					    errno != EADDRNOTAVAIL &&
1374 					    errno != ENXIO)
1375 						logerr(__func__);
1376 				}
1377 				ia->prefix_vltime = ia->prefix_pltime = 0;
1378 				ia->flags &=
1379 				    ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
1380 				expired = 1;
1381 			} else {
1382 				timespecsub(&expire, &now, &lt);
1383 				if (!timespecisset(&next) ||
1384 				    timespeccmp(&next, &lt, >))
1385 					next = lt;
1386 			}
1387 		}
1388 
1389 		/* XXX FixMe!
1390 		 * We need to extract the lifetime from each option and check
1391 		 * if that has expired or not.
1392 		 * If it has, zero the option out in the returned data. */
1393 
1394 		/* No valid lifetimes are left on the RA, so we might
1395 		 * as well punt it. */
1396 		if (!valid && TAILQ_FIRST(&rap->addrs) == NULL)
1397 			ipv6nd_free_ra(rap);
1398 		else
1399 			validone = 1;
1400 	}
1401 
1402 	if (timespecisset(&next))
1403 		eloop_timeout_add_tv(ifp->ctx->eloop,
1404 		    &next, ipv6nd_expirera, ifp);
1405 	if (expired) {
1406 		rt_build(ifp->ctx, AF_INET6);
1407 		script_runreason(ifp, "ROUTERADVERT");
1408 	}
1409 
1410 	/* No valid routers? Kill any DHCPv6. */
1411 	if (!validone)
1412 		dhcp6_dropnondelegates(ifp);
1413 }
1414 
1415 void
1416 ipv6nd_drop(struct interface *ifp)
1417 {
1418 	struct ra *rap;
1419 	uint8_t expired = 0;
1420 	TAILQ_HEAD(rahead, ra) rtrs;
1421 
1422 	if (ifp->ctx->ra_routers == NULL)
1423 		return;
1424 
1425 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1426 	TAILQ_INIT(&rtrs);
1427 	TAILQ_FOREACH(rap, ifp->ctx->ra_routers, next) {
1428 		if (rap->iface == ifp) {
1429 			rap->expired = expired = 1;
1430 			TAILQ_REMOVE(ifp->ctx->ra_routers, rap, next);
1431 			TAILQ_INSERT_TAIL(&rtrs, rap, next);
1432 		}
1433 	}
1434 	if (expired) {
1435 		while ((rap = TAILQ_FIRST(&rtrs))) {
1436 			TAILQ_REMOVE(&rtrs, rap, next);
1437 			ipv6nd_drop_ra(rap);
1438 		}
1439 		rt_build(ifp->ctx, AF_INET6);
1440 		if ((ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP)
1441 			script_runreason(ifp, "ROUTERADVERT");
1442 	}
1443 }
1444 
1445 static void
1446 ipv6nd_handlena(struct dhcpcd_ctx *ctx, struct interface *ifp,
1447     struct icmp6_hdr *icp, size_t len, int hoplimit)
1448 {
1449 	struct nd_neighbor_advert *nd_na;
1450 	struct in6_addr nd_na_target;
1451 	struct ra *rap;
1452 	uint32_t is_router, is_solicited;
1453 	char buf[INET6_ADDRSTRLEN];
1454 	const char *taddr;
1455 
1456 	if (ifp == NULL) {
1457 #ifdef DEBUG_NS
1458 		logdebugx("NA for unexpected interface from %s",
1459 		    ctx->sfrom);
1460 #endif
1461 		return;
1462 	}
1463 
1464 	if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
1465 		logerrx("%s: IPv6 NA too short from %s",
1466 		    ifp->name, ctx->sfrom);
1467 		return;
1468 	}
1469 
1470 	/* RFC 4861 7.1.2 */
1471 	if (hoplimit != 255) {
1472 		logerrx("invalid hoplimit(%d) in NA from %s",
1473 		    hoplimit, ctx->sfrom);
1474 		return;
1475 	}
1476 
1477 	nd_na = (struct nd_neighbor_advert *)icp;
1478 	is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER;
1479 	is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED;
1480 	taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target,
1481 	    buf, INET6_ADDRSTRLEN);
1482 
1483 	/* nd_na->nd_na_target is not aligned. */
1484 	memcpy(&nd_na_target, &nd_na->nd_na_target, sizeof(nd_na_target));
1485 	if (IN6_IS_ADDR_MULTICAST(&nd_na_target)) {
1486 		logerrx("%s: NA multicast address %s (%s)",
1487 		    ifp->name, taddr, ctx->sfrom);
1488 		return;
1489 	}
1490 
1491 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
1492 		if (rap->iface == ifp &&
1493 		    IN6_ARE_ADDR_EQUAL(&rap->from, &nd_na_target))
1494 			break;
1495 	}
1496 	if (rap == NULL) {
1497 #ifdef DEBUG_NS
1498 		logdebugx("%s: unexpected NA from %s for %s",
1499 		    ifp->name, ctx->sfrom, taddr);
1500 #endif
1501 		return;
1502 	}
1503 
1504 #ifdef DEBUG_NS
1505 	logdebugx("%s: %sNA for %s from %s",
1506 	    ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom);
1507 #endif
1508 
1509 	/* Node is no longer a router, so remove it from consideration */
1510 	if (!is_router && !rap->expired) {
1511 		loginfox("%s: %s not a router (%s)",
1512 		    ifp->name, taddr, ctx->sfrom);
1513 		rap->expired = 1;
1514 		rt_build(ifp->ctx,  AF_INET6);
1515 		script_runreason(ifp, "ROUTERADVERT");
1516 		return;
1517 	}
1518 
1519 	if (is_solicited && is_router && rap->lifetime) {
1520 		if (rap->expired) {
1521 			rap->expired = 0;
1522 			loginfox("%s: %s reachable (%s)",
1523 			    ifp->name, taddr, ctx->sfrom);
1524 			rt_build(ifp->ctx, AF_INET6);
1525 			script_runreason(rap->iface, "ROUTERADVERT"); /* XXX */
1526 		}
1527 	}
1528 }
1529 
1530 static void
1531 ipv6nd_handledata(void *arg)
1532 {
1533 	struct dhcpcd_ctx *ctx;
1534 	ssize_t len;
1535 	struct cmsghdr *cm;
1536 	int hoplimit;
1537 	struct in6_pktinfo pkt;
1538 	struct icmp6_hdr *icp;
1539 	struct interface *ifp;
1540 
1541 	ctx = arg;
1542 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1543 	    CMSG_SPACE(sizeof(int));
1544 	len = recvmsg_realloc(ctx->nd_fd, &ctx->rcvhdr, 0);
1545 	if (len == -1) {
1546 		logerr(__func__);
1547 		eloop_event_delete(ctx->eloop, ctx->nd_fd);
1548 		close(ctx->nd_fd);
1549 		ctx->nd_fd = -1;
1550 		return;
1551 	}
1552 	ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
1553 	    ctx->ntopbuf, INET6_ADDRSTRLEN);
1554 	if ((size_t)len < sizeof(struct icmp6_hdr)) {
1555 		logerrx("IPv6 ICMP packet too short from %s", ctx->sfrom);
1556 		return;
1557 	}
1558 
1559 	pkt.ipi6_ifindex = 0;
1560 	hoplimit = 0;
1561 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&ctx->rcvhdr);
1562 	     cm;
1563 	     cm = (struct cmsghdr *)CMSG_NXTHDR(&ctx->rcvhdr, cm))
1564 	{
1565 		if (cm->cmsg_level != IPPROTO_IPV6)
1566 			continue;
1567 		switch(cm->cmsg_type) {
1568 		case IPV6_PKTINFO:
1569 			if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
1570 				memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
1571 			break;
1572 		case IPV6_HOPLIMIT:
1573 			if (cm->cmsg_len == CMSG_LEN(sizeof(int)))
1574 				memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int));
1575 			break;
1576 		}
1577 	}
1578 
1579 	if (pkt.ipi6_ifindex == 0) {
1580 		logerrx("IPv6 RA/NA did not contain index from %s", ctx->sfrom);
1581 		return;
1582 	}
1583 
1584 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
1585 		if (ifp->active &&
1586 		    ifp->index == (unsigned int)pkt.ipi6_ifindex) {
1587 			if (!(ifp->options->options & DHCPCD_IPV6))
1588 				return;
1589 			break;
1590 		}
1591 	}
1592 
1593 	icp = (struct icmp6_hdr *)ctx->rcvhdr.msg_iov[0].iov_base;
1594 	if (icp->icmp6_code == 0) {
1595 		switch(icp->icmp6_type) {
1596 			case ND_NEIGHBOR_ADVERT:
1597 				ipv6nd_handlena(ctx, ifp, icp, (size_t)len,
1598 				   hoplimit);
1599 				return;
1600 			case ND_ROUTER_ADVERT:
1601 				ipv6nd_handlera(ctx, ifp, icp, (size_t)len,
1602 				   hoplimit);
1603 				return;
1604 		}
1605 	}
1606 
1607 	logerrx("invalid IPv6 type %d or code %d from %s",
1608 	    icp->icmp6_type, icp->icmp6_code, ctx->sfrom);
1609 }
1610 
1611 static void
1612 ipv6nd_startrs1(void *arg)
1613 {
1614 	struct interface *ifp = arg;
1615 	struct rs_state *state;
1616 
1617 	loginfox("%s: soliciting an IPv6 router", ifp->name);
1618 	if (ipv6nd_open(ifp->ctx) == -1) {
1619 		logerr(__func__);
1620 		return;
1621 	}
1622 
1623 	state = RS_STATE(ifp);
1624 	if (state == NULL) {
1625 		ifp->if_data[IF_DATA_IPV6ND] = calloc(1, sizeof(*state));
1626 		state = RS_STATE(ifp);
1627 		if (state == NULL) {
1628 			logerr(__func__);
1629 			return;
1630 		}
1631 	}
1632 
1633 	/* Always make a new probe as the underlying hardware
1634 	 * address could have changed. */
1635 	ipv6nd_makersprobe(ifp);
1636 	if (state->rs == NULL) {
1637 		logerr(__func__);
1638 		return;
1639 	}
1640 
1641 	state->rsprobes = 0;
1642 	ipv6nd_sendrsprobe(ifp);
1643 }
1644 
1645 void
1646 ipv6nd_startrs(struct interface *ifp)
1647 {
1648 	struct timespec tv;
1649 
1650 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1651 	if (!(ifp->options->options & DHCPCD_INITIAL_DELAY)) {
1652 		ipv6nd_startrs1(ifp);
1653 		return;
1654 	}
1655 
1656 	tv.tv_sec = 0;
1657 	tv.tv_nsec = (suseconds_t)arc4random_uniform(
1658 	    MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
1659 	timespecnorm(&tv);
1660 	logdebugx("%s: delaying IPv6 router solicitation for %0.1f seconds",
1661 	    ifp->name, timespec_to_double(&tv));
1662 	eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
1663 	return;
1664 }
1665