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