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, <, &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, <);
1415 if (!timespecisset(&next) ||
1416 timespeccmp(&next, <, >))
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