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