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