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