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