1 /*
2  * dhcpcd - DHCP client daemon
3  * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
4  * All rights reserved
5 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/ioctl.h>
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <net/if.h>
32 #include <net/route.h>
33 #include <netinet/in.h>
34 #include <netinet/ip6.h>
35 #include <netinet/icmp6.h>
36 
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <stddef.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 
44 #define ELOOP_QUEUE 3
45 #include "common.h"
46 #include "dhcpcd.h"
47 #include "dhcp6.h"
48 #include "eloop.h"
49 #include "if.h"
50 #include "ipv6.h"
51 #include "ipv6nd.h"
52 #include "script.h"
53 
54 /* Debugging Router Solicitations is a lot of spam, so disable it */
55 //#define DEBUG_RS
56 
57 #ifndef ND_OPT_RDNSS
58 #define ND_OPT_RDNSS			25
59 struct nd_opt_rdnss {           /* RDNSS option RFC 6106 */
60 	uint8_t		nd_opt_rdnss_type;
61 	uint8_t		nd_opt_rdnss_len;
62 	uint16_t	nd_opt_rdnss_reserved;
63 	uint32_t	nd_opt_rdnss_lifetime;
64         /* followed by list of IP prefixes */
65 } __packed;
66 #endif
67 
68 #ifndef ND_OPT_DNSSL
69 #define ND_OPT_DNSSL			31
70 struct nd_opt_dnssl {		/* DNSSL option RFC 6106 */
71 	uint8_t		nd_opt_dnssl_type;
72 	uint8_t		nd_opt_dnssl_len;
73 	uint16_t	nd_opt_dnssl_reserved;
74 	uint32_t	nd_opt_dnssl_lifetime;
75 	/* followed by list of DNS servers */
76 } __packed;
77 #endif
78 
79 /* Impossible options, so we can easily add extras */
80 #define _ND_OPT_PREFIX_ADDR	255 + 1
81 
82 /* Minimal IPv6 MTU */
83 #ifndef IPV6_MMTU
84 #define IPV6_MMTU 1280
85 #endif
86 
87 #ifndef ND_RA_FLAG_RTPREF_HIGH
88 #define ND_RA_FLAG_RTPREF_MASK		0x18
89 #define ND_RA_FLAG_RTPREF_HIGH		0x08
90 #define ND_RA_FLAG_RTPREF_MEDIUM	0x00
91 #define ND_RA_FLAG_RTPREF_LOW		0x18
92 #define ND_RA_FLAG_RTPREF_RSV		0x10
93 #endif
94 
95 /* RTPREF_MEDIUM has to be 0! */
96 #define RTPREF_HIGH	1
97 #define RTPREF_MEDIUM	0
98 #define RTPREF_LOW	(-1)
99 #define RTPREF_RESERVED	(-2)
100 #define RTPREF_INVALID	(-3)	/* internal */
101 
102 #define MIN_RANDOM_FACTOR	500				/* millisecs */
103 #define MAX_RANDOM_FACTOR	1500				/* millisecs */
104 #define MIN_RANDOM_FACTOR_U	MIN_RANDOM_FACTOR * 1000	/* usecs */
105 #define MAX_RANDOM_FACTOR_U	MAX_RANDOM_FACTOR * 1000	/* usecs */
106 
107 #if BYTE_ORDER == BIG_ENDIAN
108 #define IPV6_ADDR_INT32_ONE     1
109 #define IPV6_ADDR_INT16_MLL     0xff02
110 #elif BYTE_ORDER == LITTLE_ENDIAN
111 #define IPV6_ADDR_INT32_ONE     0x01000000
112 #define IPV6_ADDR_INT16_MLL     0x02ff
113 #endif
114 
115 /* Debugging Neighbor Solicitations is a lot of spam, so disable it */
116 //#define DEBUG_NS
117 //
118 
119 static void ipv6nd_handledata(void *);
120 
121 /*
122  * Android ships buggy ICMP6 filter headers.
123  * Supply our own until they fix their shit.
124  * References:
125  *     https://android-review.googlesource.com/#/c/58438/
126  *     http://code.google.com/p/android/issues/original?id=32621&seq=24
127  */
128 #ifdef __ANDROID__
129 #undef ICMP6_FILTER_WILLPASS
130 #undef ICMP6_FILTER_WILLBLOCK
131 #undef ICMP6_FILTER_SETPASS
132 #undef ICMP6_FILTER_SETBLOCK
133 #undef ICMP6_FILTER_SETPASSALL
134 #undef ICMP6_FILTER_SETBLOCKALL
135 #define ICMP6_FILTER_WILLPASS(type, filterp) \
136 	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
137 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \
138 	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
139 #define ICMP6_FILTER_SETPASS(type, filterp) \
140 	((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
141 #define ICMP6_FILTER_SETBLOCK(type, filterp) \
142 	((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
143 #define ICMP6_FILTER_SETPASSALL(filterp) \
144 	memset(filterp, 0, sizeof(struct icmp6_filter));
145 #define ICMP6_FILTER_SETBLOCKALL(filterp) \
146 	memset(filterp, 0xff, sizeof(struct icmp6_filter));
147 #endif
148 
149 /* Support older systems with different defines */
150 #if !defined(IPV6_RECVHOPLIMIT) && defined(IPV6_HOPLIMIT)
151 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
152 #endif
153 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO)
154 #define IPV6_RECVPKTINFO IPV6_PKTINFO
155 #endif
156 
157 static int
ipv6nd_open(struct dhcpcd_ctx * dctx)158 ipv6nd_open(struct dhcpcd_ctx *dctx)
159 {
160 	struct ipv6_ctx *ctx;
161 	int on;
162 	struct icmp6_filter filt;
163 
164 	ctx = dctx->ipv6;
165 	if (ctx->nd_fd != -1)
166 		return ctx->nd_fd;
167 #ifdef SOCK_CLOEXEC
168 	ctx->nd_fd = socket(PF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
169 	    IPPROTO_ICMPV6);
170 	if (ctx->nd_fd == -1)
171 		return -1;
172 #else
173 	if ((ctx->nd_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1)
174 		return -1;
175 	if ((on = fcntl(ctx->nd_fd, F_GETFD, 0)) == -1 ||
176 	    fcntl(ctx->nd_fd, F_SETFD, on | FD_CLOEXEC) == -1)
177 	{
178 		close(ctx->nd_fd);
179 		ctx->nd_fd = -1;
180 	        return -1;
181 	}
182 	if ((on = fcntl(ctx->nd_fd, F_GETFL, 0)) == -1 ||
183 	    fcntl(ctx->nd_fd, F_SETFL, on | O_NONBLOCK) == -1)
184 	{
185 		close(ctx->nd_fd);
186 		ctx->nd_fd = -1;
187 	        return -1;
188 	}
189 #endif
190 
191 	/* RFC4861 4.1 */
192 	on = 255;
193 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
194 	    &on, sizeof(on)) == -1)
195 		goto eexit;
196 
197 	on = 1;
198 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
199 	    &on, sizeof(on)) == -1)
200 		goto eexit;
201 
202 	on = 1;
203 	if (setsockopt(ctx->nd_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
204 	    &on, sizeof(on)) == -1)
205 		goto eexit;
206 
207 	ICMP6_FILTER_SETBLOCKALL(&filt);
208 	ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt);
209 	ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);
210 	if (setsockopt(ctx->nd_fd, IPPROTO_ICMPV6, ICMP6_FILTER,
211 	    &filt, sizeof(filt)) == -1)
212 		goto eexit;
213 
214 	eloop_event_add(dctx->eloop, ctx->nd_fd,
215 	    ipv6nd_handledata, dctx, NULL, NULL);
216 	return ctx->nd_fd;
217 
218 eexit:
219 	if (ctx->nd_fd != -1) {
220 		eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
221 		close(ctx->nd_fd);
222 		ctx->nd_fd = -1;
223 	}
224 	return -1;
225 }
226 
227 static int
ipv6nd_makersprobe(struct interface * ifp)228 ipv6nd_makersprobe(struct interface *ifp)
229 {
230 	struct rs_state *state;
231 	struct nd_router_solicit *rs;
232 	struct nd_opt_hdr *nd;
233 
234 	state = RS_STATE(ifp);
235 	free(state->rs);
236 	state->rslen = sizeof(*rs) + (size_t)ROUNDUP8(ifp->hwlen + 2);
237 	state->rs = calloc(1, state->rslen);
238 	if (state->rs == NULL)
239 		return -1;
240 	rs = (struct nd_router_solicit *)(void *)state->rs;
241 	rs->nd_rs_type = ND_ROUTER_SOLICIT;
242 	rs->nd_rs_code = 0;
243 	rs->nd_rs_cksum = 0;
244 	rs->nd_rs_reserved = 0;
245 	nd = (struct nd_opt_hdr *)(state->rs + sizeof(*rs));
246 	nd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
247 	nd->nd_opt_len = (uint8_t)((ROUNDUP8(ifp->hwlen + 2)) >> 3);
248 	memcpy(nd + 1, ifp->hwaddr, ifp->hwlen);
249 	return 0;
250 }
251 
252 static void
ipv6nd_sendrsprobe(void * arg)253 ipv6nd_sendrsprobe(void *arg)
254 {
255 	struct interface *ifp = arg;
256 	struct ipv6_ctx *ctx;
257 	struct rs_state *state;
258 	struct sockaddr_in6 dst;
259 	struct cmsghdr *cm;
260 	struct in6_pktinfo pi;
261 
262 	if (ipv6_linklocal(ifp) == NULL) {
263 		logger(ifp->ctx, LOG_DEBUG,
264 		    "%s: delaying Router Solicitation for LL address",
265 		    ifp->name);
266 		ipv6_addlinklocalcallback(ifp, ipv6nd_sendrsprobe, ifp);
267 		return;
268 	}
269 
270 	memset(&dst, 0, sizeof(dst));
271 	dst.sin6_family = AF_INET6;
272 #ifdef SIN6_LEN
273 	dst.sin6_len = sizeof(dst);
274 #endif
275 	dst.sin6_scope_id = ifp->index;
276 	if (inet_pton(AF_INET6, ALLROUTERS, &dst.sin6_addr) != 1) {
277 		logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
278 		return;
279 	}
280 
281 	state = RS_STATE(ifp);
282 	ctx = ifp->ctx->ipv6;
283 	ctx->sndhdr.msg_name = (void *)&dst;
284 	ctx->sndhdr.msg_iov[0].iov_base = state->rs;
285 	ctx->sndhdr.msg_iov[0].iov_len = state->rslen;
286 
287 	/* Set the outbound interface */
288 	cm = CMSG_FIRSTHDR(&ctx->sndhdr);
289 	if (cm == NULL) /* unlikely */
290 		return;
291 	cm->cmsg_level = IPPROTO_IPV6;
292 	cm->cmsg_type = IPV6_PKTINFO;
293 	cm->cmsg_len = CMSG_LEN(sizeof(pi));
294 	memset(&pi, 0, sizeof(pi));
295 	pi.ipi6_ifindex = ifp->index;
296 	memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
297 
298 	logger(ifp->ctx, LOG_DEBUG,
299 	    "%s: sending Router Solicitation", ifp->name);
300 	if (sendmsg(ctx->nd_fd, &ctx->sndhdr, 0) == -1) {
301 		logger(ifp->ctx, LOG_ERR,
302 		    "%s: %s: sendmsg: %m", ifp->name, __func__);
303 		ipv6nd_drop(ifp);
304 		ifp->options->options &= ~(DHCPCD_IPV6 | DHCPCD_IPV6RS);
305 		return;
306 	}
307 
308 	if (state->rsprobes++ < MAX_RTR_SOLICITATIONS)
309 		eloop_timeout_add_sec(ifp->ctx->eloop,
310 		    RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
311 	else {
312 		logger(ifp->ctx, LOG_WARNING,
313 		    "%s: no IPv6 Routers available", ifp->name);
314 		ipv6nd_drop(ifp);
315 		dhcp6_drop(ifp, "EXPIRE6");
316 	}
317 }
318 
319 void
ipv6nd_expire(struct interface * ifp,uint32_t seconds)320 ipv6nd_expire(struct interface *ifp, uint32_t seconds)
321 {
322 	struct ra *rap;
323 	struct timespec now;
324 
325 	get_monotonic(&now);
326 
327 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
328 		if (rap->iface == ifp) {
329 			rap->received = now;
330 			rap->expired = seconds ? 0 : 1;
331 			if (seconds) {
332 				struct ra_opt *rao;
333 				struct ipv6_addr *ap;
334 
335 				rap->lifetime = seconds;
336 				TAILQ_FOREACH(ap, &rap->addrs, next) {
337 					if (ap->prefix_vltime) {
338 						ap->prefix_vltime = seconds;
339 						ap->prefix_pltime = seconds / 2;
340 					}
341 				}
342 				ipv6_addaddrs(&rap->addrs);
343 				TAILQ_FOREACH(rao, &rap->options, next) {
344 					timespecclear(&rao->expire);
345 				}
346 			}
347 		}
348 	}
349 	if (seconds)
350 		ipv6nd_expirera(ifp);
351 	else
352 		ipv6_buildroutes(ifp->ctx);
353 }
354 
355 static void
ipv6nd_reachable(struct ra * rap,int flags)356 ipv6nd_reachable(struct ra *rap, int flags)
357 {
358 
359 	if (flags & IPV6ND_REACHABLE) {
360 		if (rap->lifetime && rap->expired) {
361 			logger(rap->iface->ctx, LOG_INFO,
362 			    "%s: %s is reachable again",
363 			    rap->iface->name, rap->sfrom);
364 			rap->expired = 0;
365 			ipv6_buildroutes(rap->iface->ctx);
366 			/* XXX Not really an RA */
367 			script_runreason(rap->iface, "ROUTERADVERT");
368 		}
369 	} else {
370 		if (rap->lifetime && !rap->expired) {
371 			logger(rap->iface->ctx, LOG_WARNING,
372 			    "%s: %s is unreachable, expiring it",
373 			    rap->iface->name, rap->sfrom);
374 			rap->expired = 1;
375 			ipv6_buildroutes(rap->iface->ctx);
376 			/* XXX Not really an RA */
377 			script_runreason(rap->iface, "ROUTERADVERT");
378 		}
379 	}
380 }
381 
382 void
ipv6nd_neighbour(struct dhcpcd_ctx * ctx,struct in6_addr * addr,int flags)383 ipv6nd_neighbour(struct dhcpcd_ctx *ctx, struct in6_addr *addr, int flags)
384 {
385 	struct ra *rap;
386 
387 	if (ctx->ipv6) {
388 	        TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
389 			if (IN6_ARE_ADDR_EQUAL(&rap->from, addr)) {
390 				ipv6nd_reachable(rap, flags);
391 				break;
392 			}
393 		}
394 	}
395 }
396 
397 static void
ipv6nd_free_opts(struct ra * rap)398 ipv6nd_free_opts(struct ra *rap)
399 {
400 	struct ra_opt *rao;
401 
402 	while ((rao = TAILQ_FIRST(&rap->options))) {
403 		TAILQ_REMOVE(&rap->options, rao, next);
404 		free(rao->option);
405 		free(rao);
406 	}
407 }
408 
409 struct ipv6_addr *
ipv6nd_findaddr(struct dhcpcd_ctx * ctx,const struct in6_addr * addr,short flags)410 ipv6nd_findaddr(struct dhcpcd_ctx *ctx, const struct in6_addr *addr,
411     short flags)
412 {
413 	struct ra *rap;
414 	struct ipv6_addr *ap;
415 
416 	if (ctx->ipv6 == NULL)
417 		return NULL;
418 
419 	TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
420 		TAILQ_FOREACH(ap, &rap->addrs, next) {
421 			if (addr == NULL) {
422 				if ((ap->flags &
423 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED)) ==
424 				    (IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED))
425 					return ap;
426 			} else if (ap->prefix_vltime &&
427 			    IN6_ARE_ADDR_EQUAL(&ap->addr, addr) &&
428 			    (!flags || ap->flags & flags))
429 				return ap;
430 		}
431 	}
432 	return NULL;
433 }
434 
ipv6nd_freedrop_ra(struct ra * rap,int drop)435 void ipv6nd_freedrop_ra(struct ra *rap, int drop)
436 {
437 
438 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap->iface);
439 	eloop_timeout_delete(rap->iface->ctx->eloop, NULL, rap);
440 	if (!drop)
441 		TAILQ_REMOVE(rap->iface->ctx->ipv6->ra_routers, rap, next);
442 	ipv6_freedrop_addrs(&rap->addrs, drop, NULL);
443 	ipv6nd_free_opts(rap);
444 	free(rap->data);
445 	free(rap);
446 }
447 
448 ssize_t
ipv6nd_free(struct interface * ifp)449 ipv6nd_free(struct interface *ifp)
450 {
451 	struct rs_state *state;
452 	struct ra *rap, *ran;
453 	struct dhcpcd_ctx *ctx;
454 	ssize_t n;
455 
456 	state = RS_STATE(ifp);
457 	if (state == NULL)
458 		return 0;
459 
460 	free(state->rs);
461 	free(state);
462 	ifp->if_data[IF_DATA_IPV6ND] = NULL;
463 	n = 0;
464 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
465 		if (rap->iface == ifp) {
466 			ipv6nd_free_ra(rap);
467 			n++;
468 		}
469 	}
470 
471 	/* If we don't have any more IPv6 enabled interfaces,
472 	 * close the global socket and release resources */
473 	ctx = ifp->ctx;
474 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
475 		if (RS_STATE(ifp))
476 			break;
477 	}
478 	if (ifp == NULL) {
479 		if (ctx->ipv6->nd_fd != -1) {
480 			eloop_event_delete(ctx->eloop, ctx->ipv6->nd_fd, 0);
481 			close(ctx->ipv6->nd_fd);
482 			ctx->ipv6->nd_fd = -1;
483 		}
484 	}
485 
486 	return n;
487 }
488 
489 static int
rtpref(struct ra * rap)490 rtpref(struct ra *rap)
491 {
492 
493 	switch (rap->flags & ND_RA_FLAG_RTPREF_MASK) {
494 	case ND_RA_FLAG_RTPREF_HIGH:
495 		return (RTPREF_HIGH);
496 	case ND_RA_FLAG_RTPREF_MEDIUM:
497 	case ND_RA_FLAG_RTPREF_RSV:
498 		return (RTPREF_MEDIUM);
499 	case ND_RA_FLAG_RTPREF_LOW:
500 		return (RTPREF_LOW);
501 	default:
502 		logger(rap->iface->ctx, LOG_ERR,
503 		    "rtpref: impossible RA flag %x", rap->flags);
504 		return (RTPREF_INVALID);
505 	}
506 	/* NOTREACHED */
507 }
508 
509 static void
add_router(struct ipv6_ctx * ctx,struct ra * router)510 add_router(struct ipv6_ctx *ctx, struct ra *router)
511 {
512 	struct ra *rap;
513 
514 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
515 		if (router->iface->metric < rap->iface->metric ||
516 		    (router->iface->metric == rap->iface->metric &&
517 		    rtpref(router) > rtpref(rap)))
518 		{
519 			TAILQ_INSERT_BEFORE(rap, router, next);
520 			return;
521 		}
522 	}
523 	TAILQ_INSERT_TAIL(ctx->ra_routers, router, next);
524 }
525 
526 static int
ipv6nd_scriptrun(struct ra * rap)527 ipv6nd_scriptrun(struct ra *rap)
528 {
529 	int hasdns, hasaddress, pid;
530 	struct ipv6_addr *ap;
531 	const struct ra_opt *rao;
532 
533 	hasaddress = 0;
534 	/* If all addresses have completed DAD run the script */
535 	TAILQ_FOREACH(ap, &rap->addrs, next) {
536 		if ((ap->flags & (IPV6_AF_AUTOCONF | IPV6_AF_ADDED)) ==
537 		    (IPV6_AF_AUTOCONF | IPV6_AF_ADDED))
538 		{
539 			hasaddress = 1;
540 			if (!(ap->flags & IPV6_AF_DADCOMPLETED) &&
541 			    ipv6_iffindaddr(ap->iface, &ap->addr))
542 				ap->flags |= IPV6_AF_DADCOMPLETED;
543 			if ((ap->flags & IPV6_AF_DADCOMPLETED) == 0) {
544 				logger(ap->iface->ctx, LOG_DEBUG,
545 				    "%s: waiting for Router Advertisement"
546 				    " DAD to complete",
547 				    rap->iface->name);
548 				return 0;
549 			}
550 		}
551 	}
552 
553 	/* If we don't require RDNSS then set hasdns = 1 so we fork */
554 	if (!(rap->iface->options->options & DHCPCD_IPV6RA_REQRDNSS))
555 		hasdns = 1;
556 	else {
557 		hasdns = 0;
558 		TAILQ_FOREACH(rao, &rap->options, next) {
559 			if (rao->type == ND_OPT_RDNSS &&
560 			    rao->option &&
561 			    timespecisset(&rao->expire))
562 			{
563 				hasdns = 1;
564 				break;
565 			}
566 		}
567 	}
568 
569 	script_runreason(rap->iface, "ROUTERADVERT");
570 	pid = 0;
571 	if (hasdns && (hasaddress ||
572 	    !(rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))))
573 		pid = dhcpcd_daemonise(rap->iface->ctx);
574 #if 0
575 	else if (options & DHCPCD_DAEMONISE &&
576 	    !(options & DHCPCD_DAEMONISED) && new_data)
577 		logger(rap->iface->ctx, LOG_WARNING,
578 		    "%s: did not fork due to an absent"
579 		    " RDNSS option in the RA",
580 		    ifp->name);
581 }
582 #endif
583 	return pid;
584 }
585 
586 static void
ipv6nd_addaddr(void * arg)587 ipv6nd_addaddr(void *arg)
588 {
589 	struct ipv6_addr *ap = arg;
590 
591 	ipv6_addaddr(ap, NULL);
592 }
593 
594 int
ipv6nd_dadcompleted(const struct interface * ifp)595 ipv6nd_dadcompleted(const struct interface *ifp)
596 {
597 	const struct ra *rap;
598 	const struct ipv6_addr *ap;
599 
600 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
601 		if (rap->iface != ifp)
602 			continue;
603 		TAILQ_FOREACH(ap, &rap->addrs, next) {
604 			if (ap->flags & IPV6_AF_AUTOCONF &&
605 			    ap->flags & IPV6_AF_ADDED &&
606 			    !(ap->flags & IPV6_AF_DADCOMPLETED))
607 				return 0;
608 		}
609 	}
610 	return 1;
611 }
612 
613 static void
ipv6nd_dadcallback(void * arg)614 ipv6nd_dadcallback(void *arg)
615 {
616 	struct ipv6_addr *ap = arg, *rapap;
617 	struct interface *ifp;
618 	struct ra *rap;
619 	int wascompleted, found;
620 	struct timespec tv;
621 	char buf[INET6_ADDRSTRLEN];
622 	const char *p;
623 	int dadcounter;
624 
625 	ifp = ap->iface;
626 	wascompleted = (ap->flags & IPV6_AF_DADCOMPLETED);
627 	ap->flags |= IPV6_AF_DADCOMPLETED;
628 	if (ap->flags & IPV6_AF_DUPLICATED) {
629 		ap->dadcounter++;
630 		logger(ifp->ctx, LOG_WARNING, "%s: DAD detected %s",
631 		    ifp->name, ap->saddr);
632 
633 		/* Try and make another stable private address.
634 		 * Because ap->dadcounter is always increamented,
635 		 * a different address is generated. */
636 		/* XXX Cache DAD counter per prefix/id/ssid? */
637 		if (ifp->options->options & DHCPCD_SLAACPRIVATE) {
638 			if (ap->dadcounter >= IDGEN_RETRIES) {
639 				logger(ifp->ctx, LOG_ERR,
640 				    "%s: unable to obtain a"
641 				    " stable private address",
642 				    ifp->name);
643 				goto try_script;
644 			}
645 			logger(ifp->ctx, LOG_INFO, "%s: deleting address %s",
646 				ifp->name, ap->saddr);
647 			if (if_deladdress6(ap) == -1 &&
648 			    errno != EADDRNOTAVAIL && errno != ENXIO)
649 				logger(ifp->ctx, LOG_ERR, "if_deladdress6: %m");
650 			dadcounter = ap->dadcounter;
651 			if (ipv6_makestableprivate(&ap->addr,
652 			    &ap->prefix, ap->prefix_len,
653 			    ifp, &dadcounter) == -1)
654 			{
655 				logger(ifp->ctx, LOG_ERR,
656 				    "%s: ipv6_makestableprivate: %m",
657 				    ifp->name);
658 				return;
659 			}
660 			ap->dadcounter = dadcounter;
661 			ap->flags &= ~(IPV6_AF_ADDED | IPV6_AF_DADCOMPLETED);
662 			ap->flags |= IPV6_AF_NEW;
663 			p = inet_ntop(AF_INET6, &ap->addr, buf, sizeof(buf));
664 			if (p)
665 				snprintf(ap->saddr,
666 				    sizeof(ap->saddr),
667 				    "%s/%d",
668 				    p, ap->prefix_len);
669 			else
670 				ap->saddr[0] = '\0';
671 			tv.tv_sec = 0;
672 			tv.tv_nsec = (suseconds_t)
673 			    arc4random_uniform(IDGEN_DELAY * NSEC_PER_SEC);
674 			timespecnorm(&tv);
675 			eloop_timeout_add_tv(ifp->ctx->eloop, &tv,
676 			    ipv6nd_addaddr, ap);
677 			return;
678 		}
679 	}
680 
681 try_script:
682 	if (!wascompleted) {
683 		TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
684 			if (rap->iface != ifp)
685 				continue;
686 			wascompleted = 1;
687 			found = 0;
688 			TAILQ_FOREACH(rapap, &rap->addrs, next) {
689 				if (rapap->flags & IPV6_AF_AUTOCONF &&
690 				    rapap->flags & IPV6_AF_ADDED &&
691 				    (rapap->flags & IPV6_AF_DADCOMPLETED) == 0)
692 				{
693 					wascompleted = 0;
694 					break;
695 				}
696 				if (rapap == ap)
697 					found = 1;
698 			}
699 
700 			if (wascompleted && found) {
701 				logger(rap->iface->ctx, LOG_DEBUG,
702 				    "%s: Router Advertisement DAD completed",
703 				    rap->iface->name);
704 				if (ipv6nd_scriptrun(rap))
705 					return;
706 			}
707 		}
708 	}
709 }
710 
711 static int
ipv6nd_ra_has_public_addr(const struct ra * rap)712 ipv6nd_ra_has_public_addr(const struct ra *rap)
713 {
714 	const struct ipv6_addr *ia;
715 
716 	TAILQ_FOREACH(ia, &rap->addrs, next) {
717 		if (ia->flags & IPV6_AF_AUTOCONF &&
718 		    ipv6_publicaddr(ia))
719 			return 1;
720 	}
721 	return 0;
722 }
723 
724 static void
ipv6nd_handlera(struct dhcpcd_ctx * dctx,struct interface * ifp,struct icmp6_hdr * icp,size_t len)725 ipv6nd_handlera(struct dhcpcd_ctx *dctx, struct interface *ifp,
726     struct icmp6_hdr *icp, size_t len)
727 {
728 	struct ipv6_ctx *ctx = dctx->ipv6;
729 	size_t olen, l, n;
730 	ssize_t r;
731 	struct nd_router_advert *nd_ra;
732 	struct nd_opt_prefix_info *pi;
733 	struct nd_opt_mtu *mtu;
734 	struct nd_opt_rdnss *rdnss;
735 	struct nd_opt_dnssl *dnssl;
736 	uint32_t lifetime, mtuv;
737 	uint8_t *p, *op;
738 	struct in6_addr addr;
739 	char buf[INET6_ADDRSTRLEN];
740 	const char *cbp;
741 	struct ra *rap;
742 	struct nd_opt_hdr *ndo;
743 	struct ra_opt *rao;
744 	struct ipv6_addr *ap;
745 	char *opt, *opt2, *tmp;
746 	struct timespec expire;
747 	uint8_t new_rap, new_data;
748 #ifdef IPV6_MANAGETEMPADDR
749 	uint8_t new_ap;
750 #endif
751 
752 	if (len < sizeof(struct nd_router_advert)) {
753 		logger(dctx, LOG_ERR,
754 		    "IPv6 RA packet too short from %s", ctx->sfrom);
755 		return;
756 	}
757 
758 	if (!IN6_IS_ADDR_LINKLOCAL(&ctx->from.sin6_addr)) {
759 		logger(dctx, LOG_ERR,
760 		    "RA from non local address %s", ctx->sfrom);
761 		return;
762 	}
763 
764 	if (ifp == NULL) {
765 #ifdef DEBUG_RS
766 		logger(dctx, LOG_DEBUG,
767 		    "RA for unexpected interface from %s", ctx->sfrom);
768 #endif
769 		return;
770 	}
771 	if (!(ifp->options->options & DHCPCD_IPV6RS)) {
772 #ifdef DEBUG_RS
773 		logger(ifp->ctx, LOG_DEBUG, "%s: unexpected RA from %s",
774 		    ifp->name, ctx->sfrom);
775 #endif
776 		return;
777 	}
778 
779 	/* We could receive a RA before we sent a RS*/
780 	if (ipv6_linklocal(ifp) == NULL) {
781 #ifdef DEBUG_RS
782 		logger(ifp->ctx, LOG_DEBUG,
783 		    "%s: received RA from %s (no link-local)",
784 		    ifp->name, ctx->sfrom);
785 #endif
786 		return;
787 	}
788 
789 	if (ipv6_iffindaddr(ifp, &ctx->from.sin6_addr)) {
790 		logger(ifp->ctx, LOG_DEBUG,
791 		    "%s: ignoring RA from ourself %s", ifp->name, ctx->sfrom);
792 		return;
793 	}
794 
795 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
796 		if (ifp == rap->iface &&
797 		    IN6_ARE_ADDR_EQUAL(&rap->from, &ctx->from.sin6_addr))
798 			break;
799 	}
800 
801 	nd_ra = (struct nd_router_advert *)icp;
802 
803 	/* We don't want to spam the log with the fact we got an RA every
804 	 * 30 seconds or so, so only spam the log if it's different. */
805 	if (rap == NULL || (rap->data_len != len ||
806 	     memcmp(rap->data, (unsigned char *)icp, rap->data_len) != 0))
807 	{
808 		if (rap) {
809 			free(rap->data);
810 			rap->data_len = 0;
811 			rap->no_public_warned = 0;
812 		}
813 		new_data = 1;
814 	} else
815 		new_data = 0;
816 	if (new_data || ifp->options->options & DHCPCD_DEBUG)
817 		logger(ifp->ctx, LOG_INFO, "%s: Router Advertisement from %s",
818 		    ifp->name, ctx->sfrom);
819 
820 	if (rap == NULL) {
821 		rap = calloc(1, sizeof(*rap));
822 		if (rap == NULL) {
823 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
824 			return;
825 		}
826 		rap->iface = ifp;
827 		rap->from = ctx->from.sin6_addr;
828 		strlcpy(rap->sfrom, ctx->sfrom, sizeof(rap->sfrom));
829 		TAILQ_INIT(&rap->addrs);
830 		TAILQ_INIT(&rap->options);
831 		new_rap = 1;
832 	} else
833 		new_rap = 0;
834 	if (rap->data_len == 0) {
835 		rap->data = malloc(len);
836 		if (rap->data == NULL) {
837 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
838 			if (new_rap)
839 				free(rap);
840 			return;
841 		}
842 		memcpy(rap->data, icp, len);
843 		rap->data_len = len;
844 	}
845 
846 	get_monotonic(&rap->received);
847 	rap->flags = nd_ra->nd_ra_flags_reserved;
848 	if (new_rap == 0 && rap->lifetime == 0)
849 		logger(ifp->ctx, LOG_WARNING, "%s: %s router available",
850 		   ifp->name, rap->sfrom);
851 	rap->lifetime = ntohs(nd_ra->nd_ra_router_lifetime);
852 	if (nd_ra->nd_ra_reachable) {
853 		rap->reachable = ntohl(nd_ra->nd_ra_reachable);
854 		if (rap->reachable > MAX_REACHABLE_TIME)
855 			rap->reachable = 0;
856 	}
857 	if (nd_ra->nd_ra_retransmit)
858 		rap->retrans = ntohl(nd_ra->nd_ra_retransmit);
859 	if (rap->lifetime)
860 		rap->expired = 0;
861 
862 	ipv6_settempstale(ifp);
863 	TAILQ_FOREACH(ap, &rap->addrs, next) {
864 		ap->flags |= IPV6_AF_STALE;
865 	}
866 
867 	len -= sizeof(struct nd_router_advert);
868 	p = ((uint8_t *)icp) + sizeof(struct nd_router_advert);
869 	lifetime = ~0U;
870 	for (; len > 0; p += olen, len -= olen) {
871 		if (len < sizeof(struct nd_opt_hdr)) {
872 			logger(ifp->ctx, LOG_ERR,
873 			    "%s: short option", ifp->name);
874 			break;
875 		}
876 		ndo = (struct nd_opt_hdr *)p;
877 		olen = (size_t)ndo->nd_opt_len * 8;
878 		if (olen == 0) {
879 			logger(ifp->ctx, LOG_ERR,
880 			    "%s: zero length option", ifp->name);
881 			break;
882 		}
883 		if (olen > len) {
884 			logger(ifp->ctx, LOG_ERR,
885 			    "%s: option length exceeds message", ifp->name);
886 			break;
887 		}
888 
889 		opt = opt2 = NULL;
890 		switch (ndo->nd_opt_type) {
891 		case ND_OPT_PREFIX_INFORMATION:
892 			pi = (struct nd_opt_prefix_info *)(void *)ndo;
893 			if (pi->nd_opt_pi_len != 4) {
894 				logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
895 				    "%s: invalid option len for prefix",
896 				    ifp->name);
897 				continue;
898 			}
899 			if (pi->nd_opt_pi_prefix_len > 128) {
900 				logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
901 				    "%s: invalid prefix len",
902 				    ifp->name);
903 				continue;
904 			}
905 			if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) ||
906 			    IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix))
907 			{
908 				logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
909 				    "%s: invalid prefix in RA", ifp->name);
910 				continue;
911 			}
912 			if (ntohl(pi->nd_opt_pi_preferred_time) >
913 			    ntohl(pi->nd_opt_pi_valid_time))
914 			{
915 				logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
916 				    "%s: pltime > vltime", ifp->name);
917 				continue;
918 			}
919 			TAILQ_FOREACH(ap, &rap->addrs, next)
920 				if (ap->prefix_len ==pi->nd_opt_pi_prefix_len &&
921 				    IN6_ARE_ADDR_EQUAL(&ap->prefix,
922 				    &pi->nd_opt_pi_prefix))
923 					break;
924 			if (ap == NULL) {
925 				if (!(pi->nd_opt_pi_flags_reserved &
926 				    ND_OPT_PI_FLAG_AUTO) &&
927 				    !(pi->nd_opt_pi_flags_reserved &
928 				    ND_OPT_PI_FLAG_ONLINK))
929 					continue;
930 				ap = calloc(1, sizeof(*ap));
931 				if (ap == NULL)
932 					break;
933 				ap->iface = rap->iface;
934 				ap->flags = IPV6_AF_NEW;
935 				ap->prefix_len = pi->nd_opt_pi_prefix_len;
936 				ap->prefix = pi->nd_opt_pi_prefix;
937 				if (pi->nd_opt_pi_flags_reserved &
938 				    ND_OPT_PI_FLAG_AUTO &&
939 				    ap->iface->options->options &
940 				    DHCPCD_IPV6RA_AUTOCONF)
941 				{
942 					ap->flags |= IPV6_AF_AUTOCONF;
943 					ap->dadcounter =
944 					    ipv6_makeaddr(&ap->addr, ifp,
945 					    &ap->prefix,
946 					    pi->nd_opt_pi_prefix_len);
947 					if (ap->dadcounter == -1) {
948 						free(ap);
949 						break;
950 					}
951 					cbp = inet_ntop(AF_INET6,
952 					    &ap->addr,
953 					    buf, sizeof(buf));
954 					if (cbp)
955 						snprintf(ap->saddr,
956 						    sizeof(ap->saddr),
957 						    "%s/%d",
958 						    cbp, ap->prefix_len);
959 					else
960 						ap->saddr[0] = '\0';
961 				} else {
962 					memset(&ap->addr, 0, sizeof(ap->addr));
963 					ap->saddr[0] = '\0';
964 				}
965 				ap->dadcallback = ipv6nd_dadcallback;
966 				ap->created = ap->acquired = rap->received;
967 				TAILQ_INSERT_TAIL(&rap->addrs, ap, next);
968 
969 #ifdef IPV6_MANAGETEMPADDR
970 				/* New address to dhcpcd RA handling.
971 				 * If the address already exists and a valid
972 				 * temporary address also exists then
973 				 * extend the existing one rather than
974 				 * create a new one */
975 				if (ipv6_iffindaddr(ifp, &ap->addr) &&
976 				    ipv6_settemptime(ap, 0))
977 					new_ap = 0;
978 				else
979 					new_ap = 1;
980 #endif
981 			} else {
982 #ifdef IPV6_MANAGETEMPADDR
983 				new_ap = 0;
984 #endif
985 				ap->flags &= ~IPV6_AF_STALE;
986 				ap->acquired = rap->received;
987 			}
988 			if (pi->nd_opt_pi_flags_reserved &
989 			    ND_OPT_PI_FLAG_ONLINK)
990 				ap->flags |= IPV6_AF_ONLINK;
991 			ap->prefix_vltime =
992 			    ntohl(pi->nd_opt_pi_valid_time);
993 			ap->prefix_pltime =
994 			    ntohl(pi->nd_opt_pi_preferred_time);
995 			ap->nsprobes = 0;
996 			cbp = inet_ntop(AF_INET6, &ap->prefix, buf, sizeof(buf));
997 			if (cbp) {
998 				l = strlen(cbp);
999 				opt = malloc(l + 5);
1000 				if (opt) {
1001 					snprintf(opt, l + 5, "%s/%d", cbp,
1002 					    ap->prefix_len);
1003 					opt2 = strdup(ap->saddr);
1004 				}
1005 			}
1006 
1007 #ifdef IPV6_MANAGETEMPADDR
1008 			/* RFC4941 Section 3.3.3 */
1009 			if (ap->flags & IPV6_AF_AUTOCONF &&
1010 			    ap->iface->options->options & DHCPCD_IPV6RA_OWN &&
1011 			    ip6_use_tempaddr(ap->iface->name))
1012 			{
1013 				if (!new_ap) {
1014 					if (ipv6_settemptime(ap, 1) == NULL)
1015 						new_ap = 1;
1016 				}
1017 				if (new_ap && ap->prefix_pltime) {
1018 					if (ipv6_createtempaddr(ap,
1019 					    &ap->acquired) == NULL)
1020 						logger(ap->iface->ctx, LOG_ERR,
1021 						    "ipv6_createtempaddr: %m");
1022 				}
1023 			}
1024 #endif
1025 
1026 			lifetime = ap->prefix_vltime;
1027 			break;
1028 
1029 		case ND_OPT_MTU:
1030 			mtu = (struct nd_opt_mtu *)(void *)p;
1031 			mtuv = ntohl(mtu->nd_opt_mtu_mtu);
1032 			if (mtuv < IPV6_MMTU) {
1033 				logger(ifp->ctx, LOG_ERR, "%s: invalid MTU %d",
1034 				    ifp->name, mtuv);
1035 				break;
1036 			}
1037 			rap->mtu = mtuv;
1038 			snprintf(buf, sizeof(buf), "%d", mtuv);
1039 			opt = strdup(buf);
1040 			break;
1041 
1042 		case ND_OPT_RDNSS:
1043 			rdnss = (struct nd_opt_rdnss *)p;
1044 			lifetime = ntohl(rdnss->nd_opt_rdnss_lifetime);
1045 			op = (uint8_t *)ndo;
1046 			op += offsetof(struct nd_opt_rdnss,
1047 			    nd_opt_rdnss_lifetime);
1048 			op += sizeof(rdnss->nd_opt_rdnss_lifetime);
1049 			l = 0;
1050 			for (n = (size_t)ndo->nd_opt_len - 1; n > 1; n -= 2,
1051 			    op += sizeof(addr))
1052 			{
1053 				r = ipv6_printaddr(NULL, 0, op, ifp->name);
1054 				if (r != -1)
1055 					l += (size_t)r + 1;
1056 			}
1057 			op = (uint8_t *)ndo;
1058 			op += offsetof(struct nd_opt_rdnss,
1059 			    nd_opt_rdnss_lifetime);
1060 			op += sizeof(rdnss->nd_opt_rdnss_lifetime);
1061 			tmp = opt = malloc(l);
1062 			if (opt == NULL)
1063 				continue;
1064 			for (n = (size_t)ndo->nd_opt_len - 1; n > 1; n -= 2,
1065 			    op += sizeof(addr))
1066 			{
1067 				r = ipv6_printaddr(tmp, l, op,
1068 				    ifp->name);
1069 				if (r != -1) {
1070 					l -= ((size_t)r + 1);
1071 					tmp += (size_t)r;
1072 					*tmp++ = ' ';
1073 				}
1074 			}
1075 			if (tmp != opt)
1076 				(*--tmp) = '\0';
1077 			else
1078 				*opt = '\0';
1079 			break;
1080 
1081 		case ND_OPT_DNSSL:
1082 			dnssl = (struct nd_opt_dnssl *)p;
1083 			lifetime = ntohl(dnssl->nd_opt_dnssl_lifetime);
1084 			op = p + offsetof(struct nd_opt_dnssl,
1085 			    nd_opt_dnssl_lifetime);
1086 			op += sizeof(dnssl->nd_opt_dnssl_lifetime);
1087 			n = (size_t)(dnssl->nd_opt_dnssl_len - 1) * 8;
1088 			r = decode_rfc3397(NULL, 0, op, n);
1089 			if (r < 1) {
1090 				logger(ifp->ctx, new_data ? LOG_ERR : LOG_DEBUG,
1091 				    "%s: invalid DNSSL option",
1092 				    ifp->name);
1093 				continue;
1094 			} else {
1095 				l = (size_t)r + 1;
1096 				tmp = malloc(l);
1097 				if (tmp) {
1098 					decode_rfc3397(tmp, l, op, n);
1099 					l -= 1;
1100 					n = (size_t)print_string(NULL, 0,
1101 					    STRING | ARRAY | DOMAIN,
1102 					    (const uint8_t *)tmp, l);
1103 					n++;
1104 					opt = malloc(n);
1105 					if (opt) {
1106 						print_string(opt, n,
1107 						    STRING | ARRAY | DOMAIN,
1108 						    (const uint8_t *)tmp, l);
1109 					} else
1110 						logger(ifp->ctx, LOG_ERR,
1111 						    "%s: %m", __func__);
1112 					free(tmp);
1113 				}
1114 			}
1115 			break;
1116 
1117 		default:
1118 			continue;
1119 		}
1120 
1121 		if (opt == NULL) {
1122 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1123 			continue;
1124 		}
1125 
1126 		n = ndo->nd_opt_type;
1127 extra_opt:
1128 		TAILQ_FOREACH(rao, &rap->options, next) {
1129 			if (rao->type == n &&
1130 			    strcmp(rao->option, opt) == 0)
1131 				break;
1132 		}
1133 		if (lifetime == 0 || *opt == '\0') {
1134 			if (rao) {
1135 				TAILQ_REMOVE(&rap->options, rao, next);
1136 				free(rao->option);
1137 				free(rao);
1138 			}
1139 			free(opt);
1140 			free(opt2);
1141 			continue;
1142 		}
1143 
1144 		if (rao == NULL) {
1145 			rao = malloc(sizeof(*rao));
1146 			if (rao == NULL) {
1147 				logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1148 				continue;
1149 			}
1150 			rao->type = (uint16_t)n;
1151 			rao->option = opt;
1152 			TAILQ_INSERT_TAIL(&rap->options, rao, next);
1153 		} else
1154 			free(opt);
1155 		if (lifetime == ~0U)
1156 			timespecclear(&rao->expire);
1157 		else {
1158 			expire.tv_sec = (time_t)lifetime;
1159 			expire.tv_nsec = 0;
1160 			timespecadd(&rap->received, &expire, &rao->expire);
1161 		}
1162 		if (rao && rao->type == ND_OPT_PREFIX_INFORMATION && opt2) {
1163 			n = _ND_OPT_PREFIX_ADDR;
1164 			opt = opt2;
1165 			opt2 = NULL;
1166 			goto extra_opt;
1167 		}
1168 	}
1169 
1170 	if (new_rap)
1171 		add_router(ifp->ctx->ipv6, rap);
1172 	if (!ipv6nd_ra_has_public_addr(rap) &&
1173 	    !(rap->iface->options->options & DHCPCD_IPV6RA_ACCEPT_NOPUBLIC) &&
1174 	    (!(rap->flags & ND_RA_FLAG_MANAGED) ||
1175 	    !dhcp6_has_public_addr(rap->iface)))
1176 	{
1177 		logger(rap->iface->ctx,
1178 		    rap->no_public_warned ? LOG_DEBUG : LOG_WARNING,
1179 		    "%s: ignoring RA from %s"
1180 		    " (no public prefix, no managed address)",
1181 		    rap->iface->name, rap->sfrom);
1182 		rap->no_public_warned = 1;
1183 		return;
1184 	}
1185 	if (ifp->ctx->options & DHCPCD_TEST) {
1186 		script_runreason(ifp, "TEST");
1187 		goto handle_flag;
1188 	}
1189 	ipv6_addaddrs(&rap->addrs);
1190 #ifdef IPV6_MANAGETEMPADDR
1191 	ipv6_addtempaddrs(ifp, &rap->received);
1192 #endif
1193 
1194 	/* Find any freshly added routes, such as the subnet route.
1195 	 * We do this because we cannot rely on recieving the kernel
1196 	 * notification right now via our link socket. */
1197 	if_initrt6(ifp);
1198 
1199 	ipv6_buildroutes(ifp->ctx);
1200 	if (ipv6nd_scriptrun(rap))
1201 		return;
1202 
1203 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1204 	eloop_timeout_delete(ifp->ctx->eloop, NULL, rap); /* reachable timer */
1205 
1206 handle_flag:
1207 	if (!(ifp->options->options & DHCPCD_DHCP6))
1208 		goto nodhcp6;
1209 	if (rap->flags & ND_RA_FLAG_MANAGED) {
1210 		if (new_data && dhcp6_start(ifp, DH6S_INIT) == -1)
1211 			logger(ifp->ctx, LOG_ERR,
1212 			    "dhcp6_start: %s: %m", ifp->name);
1213 	} else if (rap->flags & ND_RA_FLAG_OTHER) {
1214 		if (new_data && dhcp6_start(ifp, DH6S_INFORM) == -1)
1215 			logger(ifp->ctx, LOG_ERR,
1216 			    "dhcp6_start: %s: %m", ifp->name);
1217 	} else {
1218 		if (new_data)
1219 			logger(ifp->ctx, LOG_DEBUG,
1220 			    "%s: No DHCPv6 instruction in RA", ifp->name);
1221 nodhcp6:
1222 		if (ifp->ctx->options & DHCPCD_TEST) {
1223 			eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
1224 			return;
1225 		}
1226 	}
1227 
1228 	/* Expire should be called last as the rap object could be destroyed */
1229 	ipv6nd_expirera(ifp);
1230 }
1231 
1232 /* Run RA's we ignored becuase they had no public addresses
1233  * This should only be called when DHCPv6 applies a public address */
1234 void
ipv6nd_runignoredra(struct interface * ifp)1235 ipv6nd_runignoredra(struct interface *ifp)
1236 {
1237 	struct ra *rap;
1238 
1239 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
1240 		if (rap->iface == ifp &&
1241 		    !rap->expired &&
1242 		    rap->no_public_warned)
1243 		{
1244 			rap->no_public_warned = 0;
1245 			logger(rap->iface->ctx, LOG_INFO,
1246 			    "%s: applying ignored RA from %s",
1247 			    rap->iface->name, rap->sfrom);
1248 			if (ifp->ctx->options & DHCPCD_TEST) {
1249 				script_runreason(ifp, "TEST");
1250 				continue;
1251 			}
1252 			if (ipv6nd_scriptrun(rap))
1253 				return;
1254 			eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1255 			eloop_timeout_delete(ifp->ctx->eloop, NULL, rap);
1256 		}
1257 	}
1258 }
1259 
1260 int
ipv6nd_hasra(const struct interface * ifp)1261 ipv6nd_hasra(const struct interface *ifp)
1262 {
1263 	const struct ra *rap;
1264 
1265 	if (ifp->ctx->ipv6) {
1266 		TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next)
1267 			if (rap->iface == ifp && !rap->expired)
1268 				return 1;
1269 	}
1270 	return 0;
1271 }
1272 
1273 int
ipv6nd_hasradhcp(const struct interface * ifp)1274 ipv6nd_hasradhcp(const struct interface *ifp)
1275 {
1276 	const struct ra *rap;
1277 
1278 	if (ifp->ctx->ipv6) {
1279 		TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
1280 			if (rap->iface == ifp &&
1281 			    !rap->expired &&
1282 			    (rap->flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER)))
1283 				return 1;
1284 		}
1285 	}
1286 	return 0;
1287 }
1288 
1289 ssize_t
ipv6nd_env(char ** env,const char * prefix,const struct interface * ifp)1290 ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
1291 {
1292 	size_t i, l, len;
1293 	const struct ra *rap;
1294 	const struct ra_opt *rao;
1295 	char buffer[32];
1296 	const char *optn;
1297 	char **pref, **addr, **mtu, **rdnss, **dnssl, ***var, *new;
1298 
1299 	i = l = 0;
1300 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
1301 		if (rap->iface != ifp)
1302 			continue;
1303 		i++;
1304 		if (env) {
1305 			snprintf(buffer, sizeof(buffer),
1306 			    "ra%zu_from", i);
1307 			setvar(ifp->ctx, &env, prefix, buffer, rap->sfrom);
1308 		}
1309 		l++;
1310 
1311 		pref = addr = mtu = rdnss = dnssl = NULL;
1312 		TAILQ_FOREACH(rao, &rap->options, next) {
1313 			if (rao->option == NULL)
1314 				continue;
1315 			var = NULL;
1316 			switch(rao->type) {
1317 			case ND_OPT_PREFIX_INFORMATION:
1318 				optn = "prefix";
1319 				var = &pref;
1320 				break;
1321 			case _ND_OPT_PREFIX_ADDR:
1322 				optn = "addr";
1323 				var = &addr;
1324 				break;
1325 			case ND_OPT_MTU:
1326 				optn = "mtu";
1327 				var = &mtu;
1328 				break;
1329 			case ND_OPT_RDNSS:
1330 				optn = "rdnss";
1331 				var = &rdnss;
1332 				break;
1333 			case ND_OPT_DNSSL:
1334 				optn = "dnssl";
1335 				var = &dnssl;
1336 				break;
1337 			default:
1338 				continue;
1339 			}
1340 			if (*var == NULL) {
1341 				*var = env ? env : &new;
1342 				l++;
1343 			} else if (env) {
1344 				/* With single only options, last one takes
1345 				 * precedence */
1346 				if (rao->type == ND_OPT_MTU) {
1347 					new = strchr(**var, '=');
1348 					if (new == NULL) {
1349 						logger(ifp->ctx, LOG_ERR,
1350 						    "new is null");
1351 						continue;
1352 					} else
1353 						new++;
1354 					len = (size_t)(new - **var) +
1355 					    strlen(rao->option) + 1;
1356 					if (len > strlen(**var))
1357 						new = realloc(**var, len);
1358 					else
1359 						new = **var;
1360 					if (new) {
1361 						**var = new;
1362 						new = strchr(**var, '=');
1363 						if (new) {
1364 							len -=
1365 							    (size_t)
1366 							    (new - **var);
1367 							strlcpy(new + 1,
1368 							    rao->option,
1369 							    len - 1);
1370 						} else
1371 							logger(ifp->ctx,
1372 							    LOG_ERR,
1373 							    "new is null");
1374 					}
1375 					continue;
1376 				}
1377 				len = strlen(rao->option) + 1;
1378 				new = realloc(**var, strlen(**var) + 1 + len);
1379 				if (new) {
1380 					**var = new;
1381 					new += strlen(new);
1382 					*new++ = ' ';
1383 					strlcpy(new, rao->option, len);
1384 				} else
1385 					logger(ifp->ctx, LOG_ERR,
1386 					    "%s: %m", __func__);
1387 				continue;
1388 			}
1389 			if (env) {
1390 				snprintf(buffer, sizeof(buffer),
1391 				    "ra%zu_%s", i, optn);
1392 				setvar(ifp->ctx, &env,
1393 				    prefix, buffer, rao->option);
1394 			}
1395 		}
1396 	}
1397 
1398 	if (env)
1399 		setvard(ifp->ctx, &env, prefix, "ra_count", i);
1400 	l++;
1401 	return (ssize_t)l;
1402 }
1403 
1404 void
ipv6nd_handleifa(struct dhcpcd_ctx * ctx,int cmd,const char * ifname,const struct in6_addr * addr,int flags)1405 ipv6nd_handleifa(struct dhcpcd_ctx *ctx, int cmd, const char *ifname,
1406     const struct in6_addr *addr, int flags)
1407 {
1408 	struct ra *rap;
1409 
1410 	if (ctx->ipv6 == NULL)
1411 		return;
1412 	TAILQ_FOREACH(rap, ctx->ipv6->ra_routers, next) {
1413 		if (strcmp(rap->iface->name, ifname))
1414 			continue;
1415 		ipv6_handleifa_addrs(cmd, &rap->addrs, addr, flags);
1416 	}
1417 }
1418 
1419 void
ipv6nd_expirera(void * arg)1420 ipv6nd_expirera(void *arg)
1421 {
1422 	struct interface *ifp;
1423 	struct ra *rap, *ran;
1424 	struct ra_opt *rao, *raon;
1425 	struct timespec now, lt, expire, next;
1426 	uint8_t expired, valid, validone;
1427 
1428 	ifp = arg;
1429 	get_monotonic(&now);
1430 	expired = 0;
1431 	timespecclear(&next);
1432 
1433 	validone = 0;
1434 	TAILQ_FOREACH_SAFE(rap, ifp->ctx->ipv6->ra_routers, next, ran) {
1435 		if (rap->iface != ifp)
1436 			continue;
1437 		valid = 0;
1438 		if (rap->lifetime) {
1439 			lt.tv_sec = (time_t)rap->lifetime;
1440 			lt.tv_nsec = 0;
1441 			timespecadd(&rap->received, &lt, &expire);
1442 			if (rap->lifetime == 0 || timespeccmp(&now, &expire, >))
1443 			{
1444 				if (!rap->expired) {
1445 					logger(ifp->ctx, LOG_WARNING,
1446 					    "%s: %s: router expired",
1447 					    ifp->name, rap->sfrom);
1448 					rap->expired = expired = 1;
1449 					rap->lifetime = 0;
1450 				}
1451 			} else {
1452 				valid = 1;
1453 				timespecsub(&expire, &now, &lt);
1454 				if (!timespecisset(&next) ||
1455 				    timespeccmp(&next, &lt, >))
1456 					next = lt;
1457 			}
1458 		}
1459 
1460 		/* Addresses are expired in ipv6_addaddrs
1461 		 * so that DHCPv6 addresses can be removed also. */
1462 		TAILQ_FOREACH_SAFE(rao, &rap->options, next, raon) {
1463 			if (rap->expired) {
1464 				switch(rao->type) {
1465 				case ND_OPT_RDNSS: /* FALLTHROUGH */
1466 				case ND_OPT_DNSSL:
1467 					/* RFC6018 end of section 5.2 states
1468 					 * that if tha RA has a lifetime of 0
1469 					 * then we should expire these
1470 					 * options */
1471 					TAILQ_REMOVE(&rap->options, rao, next);
1472 					expired = 1;
1473 					free(rao->option);
1474 					free(rao);
1475 					continue;
1476 				}
1477 			}
1478 			if (!timespecisset(&rao->expire))
1479 				continue;
1480 			if (timespeccmp(&now, &rao->expire, >)) {
1481 				/* Expired prefixes are logged above */
1482 				if (rao->type != ND_OPT_PREFIX_INFORMATION)
1483 					logger(ifp->ctx, LOG_WARNING,
1484 					    "%s: %s: expired option %d",
1485 					    ifp->name, rap->sfrom, rao->type);
1486 				TAILQ_REMOVE(&rap->options, rao, next);
1487 				expired = 1;
1488 				free(rao->option);
1489 				free(rao);
1490 				continue;
1491 			}
1492 			valid = 1;
1493 			timespecsub(&rao->expire, &now, &lt);
1494 			if (!timespecisset(&next) || timespeccmp(&next, &lt, >))
1495 				next = lt;
1496 		}
1497 
1498 		/* No valid lifetimes are left on the RA, so we might
1499 		 * as well punt it. */
1500 		if (!valid && TAILQ_FIRST(&rap->addrs) == NULL)
1501 			ipv6nd_free_ra(rap);
1502 		else
1503 			validone = 1;
1504 	}
1505 
1506 	if (timespecisset(&next))
1507 		eloop_timeout_add_tv(ifp->ctx->eloop,
1508 		    &next, ipv6nd_expirera, ifp);
1509 	if (expired) {
1510 		ipv6_buildroutes(ifp->ctx);
1511 		script_runreason(ifp, "ROUTERADVERT");
1512 	}
1513 
1514 	/* No valid routers? Kill any DHCPv6. */
1515 	if (!validone)
1516 		dhcp6_drop(ifp, "EXPIRE6");
1517 }
1518 
1519 void
ipv6nd_drop(struct interface * ifp)1520 ipv6nd_drop(struct interface *ifp)
1521 {
1522 	struct ra *rap;
1523 	uint8_t expired = 0;
1524 	TAILQ_HEAD(rahead, ra) rtrs;
1525 
1526 	if (ifp->ctx->ipv6 == NULL)
1527 		return;
1528 
1529 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1530 	TAILQ_INIT(&rtrs);
1531 	TAILQ_FOREACH(rap, ifp->ctx->ipv6->ra_routers, next) {
1532 		if (rap->iface == ifp) {
1533 			rap->expired = expired = 1;
1534 			TAILQ_REMOVE(ifp->ctx->ipv6->ra_routers, rap, next);
1535 			TAILQ_INSERT_TAIL(&rtrs, rap, next);
1536 		}
1537 	}
1538 	if (expired) {
1539 		while ((rap = TAILQ_FIRST(&rtrs))) {
1540 			TAILQ_REMOVE(&rtrs, rap, next);
1541 			ipv6nd_drop_ra(rap);
1542 		}
1543 		ipv6_buildroutes(ifp->ctx);
1544 		if ((ifp->options->options &
1545 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT)) !=
1546 		    (DHCPCD_EXITING | DHCPCD_PERSISTENT))
1547 			script_runreason(ifp, "ROUTERADVERT");
1548 	}
1549 }
1550 
1551 static void
ipv6nd_handlena(struct dhcpcd_ctx * dctx,struct interface * ifp,struct icmp6_hdr * icp,size_t len)1552 ipv6nd_handlena(struct dhcpcd_ctx *dctx, struct interface *ifp,
1553     struct icmp6_hdr *icp, size_t len)
1554 {
1555 	struct ipv6_ctx *ctx = dctx->ipv6;
1556 	struct nd_neighbor_advert *nd_na;
1557 	struct ra *rap;
1558 	uint32_t is_router, is_solicited;
1559 	char buf[INET6_ADDRSTRLEN];
1560 	const char *taddr;
1561 
1562 	if (ifp == NULL) {
1563 #ifdef DEBUG_NS
1564 		logger(ctx, LOG_DEBUG, "NA for unexpected interface from %s",
1565 		    dctx->sfrom);
1566 #endif
1567 		return;
1568 	}
1569 
1570 	if ((size_t)len < sizeof(struct nd_neighbor_advert)) {
1571 		logger(ifp->ctx, LOG_ERR, "%s: IPv6 NA too short from %s",
1572 		    ifp->name, ctx->sfrom);
1573 		return;
1574 	}
1575 
1576 	nd_na = (struct nd_neighbor_advert *)icp;
1577 	is_router = nd_na->nd_na_flags_reserved & ND_NA_FLAG_ROUTER;
1578 	is_solicited = nd_na->nd_na_flags_reserved & ND_NA_FLAG_SOLICITED;
1579 	taddr = inet_ntop(AF_INET6, &nd_na->nd_na_target,
1580 	    buf, INET6_ADDRSTRLEN);
1581 
1582 	if (IN6_IS_ADDR_MULTICAST(&nd_na->nd_na_target)) {
1583 		logger(ifp->ctx, LOG_ERR, "%s: NA multicast address %s (%s)",
1584 		    ifp->name, taddr, ctx->sfrom);
1585 		return;
1586 	}
1587 
1588 	TAILQ_FOREACH(rap, ctx->ra_routers, next) {
1589 		if (rap->iface == ifp &&
1590 		    IN6_ARE_ADDR_EQUAL(&rap->from, &nd_na->nd_na_target))
1591 			break;
1592 	}
1593 	if (rap == NULL) {
1594 #ifdef DEBUG_NS
1595 		logger(ifp->ctx, LOG_DEBUG, "%s: unexpected NA from %s for %s",
1596 		    ifp->name, ctx->sfrom, taddr);
1597 #endif
1598 		return;
1599 	}
1600 
1601 #ifdef DEBUG_NS
1602 	logger(ifp->ctx, LOG_DEBUG, "%s: %sNA for %s from %s",
1603 	    ifp->name, is_solicited ? "solicited " : "", taddr, ctx->sfrom);
1604 #endif
1605 
1606 	/* Node is no longer a router, so remove it from consideration */
1607 	if (!is_router && !rap->expired) {
1608 		logger(ifp->ctx, LOG_INFO, "%s: %s not a router (%s)",
1609 		    ifp->name, taddr, ctx->sfrom);
1610 		rap->expired = 1;
1611 		ipv6_buildroutes(ifp->ctx);
1612 		script_runreason(ifp, "ROUTERADVERT");
1613 		return;
1614 	}
1615 
1616 	if (is_solicited && is_router && rap->lifetime) {
1617 		if (rap->expired) {
1618 			rap->expired = 0;
1619 			logger(ifp->ctx, LOG_INFO, "%s: %s reachable (%s)",
1620 			    ifp->name, taddr, ctx->sfrom);
1621 			ipv6_buildroutes(ifp->ctx);
1622 			script_runreason(rap->iface, "ROUTERADVERT"); /* XXX */
1623 		}
1624 	}
1625 }
1626 
1627 static void
ipv6nd_handledata(void * arg)1628 ipv6nd_handledata(void *arg)
1629 {
1630 	struct dhcpcd_ctx *dctx;
1631 	struct ipv6_ctx *ctx;
1632 	ssize_t len;
1633 	struct cmsghdr *cm;
1634 	int hoplimit;
1635 	struct in6_pktinfo pkt;
1636 	struct icmp6_hdr *icp;
1637 	struct interface *ifp;
1638 
1639 	dctx = arg;
1640 	ctx = dctx->ipv6;
1641 	ctx->rcvhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
1642 	    CMSG_SPACE(sizeof(int));
1643 	len = recvmsg(ctx->nd_fd, &ctx->rcvhdr, 0);
1644 	if (len == -1) {
1645 		logger(dctx, LOG_ERR, "recvmsg: %m");
1646 		eloop_event_delete(dctx->eloop, ctx->nd_fd, 0);
1647 		close(ctx->nd_fd);
1648 		ctx->nd_fd = -1;
1649 		return;
1650 	}
1651 	ctx->sfrom = inet_ntop(AF_INET6, &ctx->from.sin6_addr,
1652 	    ctx->ntopbuf, INET6_ADDRSTRLEN);
1653 	if ((size_t)len < sizeof(struct icmp6_hdr)) {
1654 		logger(dctx, LOG_ERR, "IPv6 ICMP packet too short from %s",
1655 		    ctx->sfrom);
1656 		return;
1657 	}
1658 
1659 	pkt.ipi6_ifindex = 0;
1660 	hoplimit = 0;
1661 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&ctx->rcvhdr);
1662 	     cm;
1663 	     cm = (struct cmsghdr *)CMSG_NXTHDR(&ctx->rcvhdr, cm))
1664 	{
1665 		if (cm->cmsg_level != IPPROTO_IPV6)
1666 			continue;
1667 		switch(cm->cmsg_type) {
1668 		case IPV6_PKTINFO:
1669 			if (cm->cmsg_len == CMSG_LEN(sizeof(pkt)))
1670 				memcpy(&pkt, CMSG_DATA(cm), sizeof(pkt));
1671 			break;
1672 		case IPV6_HOPLIMIT:
1673 			if (cm->cmsg_len == CMSG_LEN(sizeof(int)))
1674 				memcpy(&hoplimit, CMSG_DATA(cm), sizeof(int));
1675 			break;
1676 		}
1677 	}
1678 
1679 	if (pkt.ipi6_ifindex == 0 || hoplimit == 0) {
1680 		logger(dctx, LOG_ERR,
1681 		    "IPv6 RA/NA did not contain index or hop limit from %s",
1682 		    ctx->sfrom);
1683 		return;
1684 	}
1685 
1686 	TAILQ_FOREACH(ifp, dctx->ifaces, next) {
1687 		if (ifp->index == (unsigned int)pkt.ipi6_ifindex &&
1688 		    !(ifp->options->options & DHCPCD_PFXDLGONLY))
1689 		{
1690 			if (!(ifp->options->options & DHCPCD_IPV6))
1691 				return;
1692 			break;
1693 		}
1694 	}
1695 
1696 	icp = (struct icmp6_hdr *)ctx->rcvhdr.msg_iov[0].iov_base;
1697 	if (icp->icmp6_code == 0) {
1698 		switch(icp->icmp6_type) {
1699 			case ND_NEIGHBOR_ADVERT:
1700 				ipv6nd_handlena(dctx, ifp, icp, (size_t)len);
1701 				return;
1702 			case ND_ROUTER_ADVERT:
1703 				ipv6nd_handlera(dctx, ifp, icp, (size_t)len);
1704 				return;
1705 		}
1706 	}
1707 
1708 	logger(dctx, LOG_ERR, "invalid IPv6 type %d or code %d from %s",
1709 	    icp->icmp6_type, icp->icmp6_code, ctx->sfrom);
1710 }
1711 
1712 static void
ipv6nd_startrs1(void * arg)1713 ipv6nd_startrs1(void *arg)
1714 {
1715 	struct interface *ifp = arg;
1716 	struct rs_state *state;
1717 
1718 	logger(ifp->ctx, LOG_INFO, "%s: soliciting an IPv6 router", ifp->name);
1719 	if (ipv6nd_open(ifp->ctx) == -1) {
1720 		logger(ifp->ctx, LOG_ERR, "%s: ipv6nd_open: %m", __func__);
1721 		return;
1722 	}
1723 
1724 	state = RS_STATE(ifp);
1725 	if (state == NULL) {
1726 		ifp->if_data[IF_DATA_IPV6ND] = calloc(1, sizeof(*state));
1727 		state = RS_STATE(ifp);
1728 		if (state == NULL) {
1729 			logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
1730 			return;
1731 		}
1732 	}
1733 
1734 	/* Always make a new probe as the underlying hardware
1735 	 * address could have changed. */
1736 	ipv6nd_makersprobe(ifp);
1737 	if (state->rs == NULL) {
1738 		logger(ifp->ctx, LOG_ERR,
1739 		    "%s: ipv6ns_makersprobe: %m", __func__);
1740 		return;
1741 	}
1742 
1743 	state->rsprobes = 0;
1744 	ipv6nd_sendrsprobe(ifp);
1745 }
1746 
1747 void
ipv6nd_startrs(struct interface * ifp)1748 ipv6nd_startrs(struct interface *ifp)
1749 {
1750 	struct timespec tv;
1751 
1752 	eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1753 	tv.tv_sec = 0;
1754 	tv.tv_nsec = (suseconds_t)arc4random_uniform(
1755 	    MAX_RTR_SOLICITATION_DELAY * NSEC_PER_SEC);
1756 	timespecnorm(&tv);
1757 	logger(ifp->ctx, LOG_DEBUG,
1758 	    "%s: delaying IPv6 router solicitation for %0.1f seconds",
1759 	    ifp->name, timespec_to_double(&tv));
1760 	eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp);
1761 	return;
1762 }
1763