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