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