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