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