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