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