1 /* $OpenBSD: frontend.c,v 1.55 2024/11/21 13:38:15 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Florian Obser <florian@openbsd.org> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 1. Redistributions of source code must retain the above copyright 30 * notice, this list of conditions and the following disclaimer. 31 * 2. Redistributions in binary form must reproduce the above copyright 32 * notice, this list of conditions and the following disclaimer in the 33 * documentation and/or other materials provided with the distribution. 34 * 3. Neither the name of the project nor the names of its contributors 35 * may be used to endorse or promote products derived from this software 36 * without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 */ 50 51 #include <sys/types.h> 52 #include <sys/ioctl.h> 53 #include <sys/queue.h> 54 #include <sys/socket.h> 55 #include <sys/syslog.h> 56 #include <sys/uio.h> 57 58 #include <net/if.h> 59 #include <net/if_dl.h> 60 #include <net/if_types.h> 61 #include <net/route.h> 62 63 #include <arpa/inet.h> 64 65 #include <netinet/in.h> 66 #include <netinet/if_ether.h> 67 #include <netinet6/nd6.h> 68 #include <netinet6/in6_var.h> 69 #include <netinet/ip6.h> 70 #include <netinet/icmp6.h> 71 72 #include <ctype.h> 73 #include <errno.h> 74 #include <event.h> 75 #include <ifaddrs.h> 76 #include <imsg.h> 77 #include <pwd.h> 78 #include <signal.h> 79 #include <stdio.h> 80 #include <stdlib.h> 81 #include <string.h> 82 #include <unistd.h> 83 84 #include "log.h" 85 #include "rad.h" 86 #include "frontend.h" 87 #include "control.h" 88 89 #define RA_MAX_SIZE 1500 90 #define ROUTE_SOCKET_BUF_SIZE 16384 91 92 struct icmp6_ev { 93 struct event ev; 94 uint8_t answer[1500]; 95 struct msghdr rcvmhdr; 96 struct iovec rcviov[1]; 97 struct sockaddr_in6 from; 98 int refcnt; 99 }; 100 101 struct ra_iface { 102 TAILQ_ENTRY(ra_iface) entry; 103 struct icmp6_ev *icmp6ev; 104 struct ra_prefix_conf_head prefixes; 105 struct ether_addr hw_addr; 106 char name[IF_NAMESIZE]; 107 char conf_name[IF_NAMESIZE]; 108 uint32_t if_index; 109 int rdomain; 110 int removed; 111 int link_state; 112 int prefix_count; 113 int ltime_decaying; 114 size_t datalen; 115 uint8_t data[RA_MAX_SIZE]; 116 }; 117 118 #define ND_OPT_PREF64 38 119 struct nd_opt_pref64 { 120 u_int8_t nd_opt_pref64_type; 121 u_int8_t nd_opt_pref64_len; 122 u_int16_t nd_opt_pref64_sltime_plc; 123 u_int8_t nd_opt_pref64[12]; 124 }; 125 126 struct nd_opt_source_link_addr { 127 u_int8_t nd_opt_source_link_addr_type; 128 u_int8_t nd_opt_source_link_addr_len; 129 struct ether_addr nd_opt_source_link_addr_hw_addr; 130 }; 131 132 TAILQ_HEAD(, ra_iface) ra_interfaces; 133 134 __dead void frontend_shutdown(void); 135 void frontend_sig_handler(int, short, void *); 136 void frontend_startup(void); 137 void icmp6_receive(int, short, void *); 138 void join_all_routers_mcast_group(struct ra_iface *); 139 void leave_all_routers_mcast_group(struct ra_iface *); 140 int get_ifrdomain(char *); 141 void merge_ra_interface(char *, char *, struct ifaddrs *); 142 void merge_ra_interfaces(void); 143 struct ra_iface *find_ra_iface_by_id(uint32_t); 144 struct ra_iface *find_ra_iface_by_name(char *); 145 struct ra_iface_conf *find_ra_iface_conf(struct ra_iface_conf_head *, 146 char *); 147 struct ra_prefix_conf *find_ra_prefix_conf(struct ra_prefix_conf_head*, 148 struct in6_addr *, int); 149 struct icmp6_ev *get_icmp6ev_by_rdomain(int); 150 void unref_icmp6ev(struct ra_iface *); 151 void set_icmp6sock(int, int); 152 void add_new_prefix_to_ra_iface(struct ra_iface *r, 153 struct in6_addr *, int, struct ra_prefix_conf *, 154 uint32_t, uint32_t); 155 void free_ra_iface(struct ra_iface *); 156 int in6_mask2prefixlen(struct in6_addr *); 157 void get_interface_prefixes(struct ra_iface *, 158 struct ra_prefix_conf *, struct ifaddrs *); 159 int build_packet(struct ra_iface *); 160 void build_leaving_packet(struct ra_iface *); 161 void ra_output(struct ra_iface *, struct sockaddr_in6 *); 162 void get_rtaddrs(int, struct sockaddr *, 163 struct sockaddr **); 164 void route_receive(int, short, void *); 165 void handle_route_message(struct rt_msghdr *, 166 struct sockaddr **); 167 168 struct rad_conf *frontend_conf; 169 static struct imsgev *iev_main; 170 static struct imsgev *iev_engine; 171 struct event ev_route; 172 int ioctlsock = -1, routesock = -1; 173 struct ipv6_mreq all_routers; 174 struct msghdr sndmhdr; 175 struct iovec sndiov[2]; 176 177 void 178 frontend_sig_handler(int sig, short event, void *bula) 179 { 180 /* 181 * Normal signal handler rules don't apply because libevent 182 * decouples for us. 183 */ 184 185 switch (sig) { 186 case SIGINT: 187 case SIGTERM: 188 frontend_shutdown(); 189 default: 190 fatalx("unexpected signal"); 191 } 192 } 193 194 void 195 frontend(int debug, int verbose) 196 { 197 struct event ev_sigint, ev_sigterm; 198 struct passwd *pw; 199 size_t sndcmsgbuflen; 200 uint8_t *sndcmsgbuf = NULL; 201 202 frontend_conf = config_new_empty(); 203 204 log_init(debug, LOG_DAEMON); 205 log_setverbose(verbose); 206 207 if ((pw = getpwnam(RAD_USER)) == NULL) 208 fatal("getpwnam"); 209 210 if (chroot(pw->pw_dir) == -1) 211 fatal("chroot"); 212 if (chdir("/") == -1) 213 fatal("chdir(\"/\")"); 214 215 setproctitle("%s", "frontend"); 216 log_procinit("frontend"); 217 218 if (setgroups(1, &pw->pw_gid) || 219 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 220 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 221 fatal("can't drop privileges"); 222 223 /* XXX pass in from main */ 224 if ((ioctlsock = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1) 225 fatal("socket"); 226 227 if (pledge("stdio inet unix recvfd route mcast", NULL) == -1) 228 fatal("pledge"); 229 230 event_init(); 231 232 /* Setup signal handler. */ 233 signal_set(&ev_sigint, SIGINT, frontend_sig_handler, NULL); 234 signal_set(&ev_sigterm, SIGTERM, frontend_sig_handler, NULL); 235 signal_add(&ev_sigint, NULL); 236 signal_add(&ev_sigterm, NULL); 237 signal(SIGPIPE, SIG_IGN); 238 signal(SIGHUP, SIG_IGN); 239 240 /* Setup pipe and event handler to the parent process. */ 241 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 242 fatal(NULL); 243 if (imsgbuf_init(&iev_main->ibuf, 3) == -1) 244 fatal(NULL); 245 imsgbuf_allow_fdpass(&iev_main->ibuf); 246 iev_main->handler = frontend_dispatch_main; 247 iev_main->events = EV_READ; 248 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 249 iev_main->handler, iev_main); 250 event_add(&iev_main->ev, NULL); 251 252 if (inet_pton(AF_INET6, "ff02::2", 253 &all_routers.ipv6mr_multiaddr.s6_addr) == -1) 254 fatal("inet_pton"); 255 256 sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + 257 CMSG_SPACE(sizeof(int)); 258 if ((sndcmsgbuf = malloc(sndcmsgbuflen)) == NULL) 259 fatal("%s", __func__); 260 261 sndmhdr.msg_namelen = sizeof(struct sockaddr_in6); 262 sndmhdr.msg_iov = sndiov; 263 sndmhdr.msg_iovlen = 1; 264 sndmhdr.msg_control = sndcmsgbuf; 265 sndmhdr.msg_controllen = sndcmsgbuflen; 266 267 TAILQ_INIT(&ra_interfaces); 268 269 event_dispatch(); 270 271 frontend_shutdown(); 272 } 273 274 __dead void 275 frontend_shutdown(void) 276 { 277 /* Close pipes. */ 278 imsgbuf_write(&iev_engine->ibuf); 279 imsgbuf_clear(&iev_engine->ibuf); 280 close(iev_engine->ibuf.fd); 281 imsgbuf_write(&iev_main->ibuf); 282 imsgbuf_clear(&iev_main->ibuf); 283 close(iev_main->ibuf.fd); 284 285 config_clear(frontend_conf); 286 287 free(iev_engine); 288 free(iev_main); 289 290 log_info("frontend exiting"); 291 exit(0); 292 } 293 294 int 295 frontend_imsg_compose_main(int type, pid_t pid, void *data, uint16_t datalen) 296 { 297 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, 298 datalen)); 299 } 300 301 int 302 frontend_imsg_compose_engine(int type, pid_t pid, void *data, uint16_t datalen) 303 { 304 return (imsg_compose_event(iev_engine, type, 0, pid, -1, data, 305 datalen)); 306 } 307 308 void 309 frontend_dispatch_main(int fd, short event, void *bula) 310 { 311 static struct rad_conf *nconf; 312 static struct ra_iface_conf *ra_iface_conf; 313 static struct ra_options_conf *ra_options; 314 struct imsg imsg; 315 struct imsgev *iev = bula; 316 struct imsgbuf *ibuf = &iev->ibuf; 317 struct ra_prefix_conf *ra_prefix_conf; 318 struct ra_rdnss_conf *ra_rdnss_conf; 319 struct ra_dnssl_conf *ra_dnssl_conf; 320 struct ra_pref64_conf *pref64; 321 int n, shut = 0, icmp6sock, rdomain; 322 323 if (event & EV_READ) { 324 if ((n = imsgbuf_read(ibuf)) == -1) 325 fatal("imsgbuf_read error"); 326 if (n == 0) /* Connection closed. */ 327 shut = 1; 328 } 329 if (event & EV_WRITE) { 330 if (imsgbuf_write(ibuf) == -1) { 331 if (errno == EPIPE) /* connection closed */ 332 shut = 1; 333 else 334 fatal("imsgbuf_write"); 335 } 336 } 337 338 for (;;) { 339 if ((n = imsg_get(ibuf, &imsg)) == -1) 340 fatal("%s: imsg_get error", __func__); 341 if (n == 0) /* No more messages. */ 342 break; 343 344 switch (imsg.hdr.type) { 345 case IMSG_SOCKET_IPC: 346 /* 347 * Setup pipe and event handler to the engine 348 * process. 349 */ 350 if (iev_engine) 351 fatalx("%s: received unexpected imsg fd to " 352 "frontend", __func__); 353 if ((fd = imsg_get_fd(&imsg)) == -1) 354 fatalx("%s: expected to receive imsg fd to " 355 "frontend but didn't receive any", 356 __func__); 357 358 iev_engine = malloc(sizeof(struct imsgev)); 359 if (iev_engine == NULL) 360 fatal(NULL); 361 362 if (imsgbuf_init(&iev_engine->ibuf, fd) == -1) 363 fatal(NULL); 364 iev_engine->handler = frontend_dispatch_engine; 365 iev_engine->events = EV_READ; 366 367 event_set(&iev_engine->ev, iev_engine->ibuf.fd, 368 iev_engine->events, iev_engine->handler, iev_engine); 369 event_add(&iev_engine->ev, NULL); 370 break; 371 case IMSG_RECONF_CONF: 372 if (nconf != NULL) 373 fatalx("%s: IMSG_RECONF_CONF already in " 374 "progress", __func__); 375 if (IMSG_DATA_SIZE(imsg) != sizeof(struct rad_conf)) 376 fatalx("%s: IMSG_RECONF_CONF wrong length: %lu", 377 __func__, IMSG_DATA_SIZE(imsg)); 378 if ((nconf = malloc(sizeof(struct rad_conf))) == 379 NULL) 380 fatal(NULL); 381 memcpy(nconf, imsg.data, sizeof(struct rad_conf)); 382 SIMPLEQ_INIT(&nconf->ra_iface_list); 383 SIMPLEQ_INIT(&nconf->ra_options.ra_rdnss_list); 384 SIMPLEQ_INIT(&nconf->ra_options.ra_dnssl_list); 385 SIMPLEQ_INIT(&nconf->ra_options.ra_pref64_list); 386 ra_options = &nconf->ra_options; 387 break; 388 case IMSG_RECONF_RA_IFACE: 389 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 390 ra_iface_conf)) 391 fatalx("%s: IMSG_RECONF_RA_IFACE wrong length: " 392 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 393 if ((ra_iface_conf = malloc(sizeof(struct 394 ra_iface_conf))) == NULL) 395 fatal(NULL); 396 memcpy(ra_iface_conf, imsg.data, sizeof(struct 397 ra_iface_conf)); 398 ra_iface_conf->autoprefix = NULL; 399 SIMPLEQ_INIT(&ra_iface_conf->ra_prefix_list); 400 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_rdnss_list); 401 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_dnssl_list); 402 SIMPLEQ_INIT(&ra_iface_conf->ra_options.ra_pref64_list); 403 SIMPLEQ_INSERT_TAIL(&nconf->ra_iface_list, 404 ra_iface_conf, entry); 405 ra_options = &ra_iface_conf->ra_options; 406 break; 407 case IMSG_RECONF_RA_AUTOPREFIX: 408 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 409 ra_prefix_conf)) 410 fatalx("%s: IMSG_RECONF_RA_AUTOPREFIX wrong " 411 "length: %lu", __func__, 412 IMSG_DATA_SIZE(imsg)); 413 if ((ra_iface_conf->autoprefix = malloc(sizeof(struct 414 ra_prefix_conf))) == NULL) 415 fatal(NULL); 416 memcpy(ra_iface_conf->autoprefix, imsg.data, 417 sizeof(struct ra_prefix_conf)); 418 break; 419 case IMSG_RECONF_RA_PREFIX: 420 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 421 ra_prefix_conf)) 422 fatalx("%s: IMSG_RECONF_RA_PREFIX wrong " 423 "length: %lu", __func__, 424 IMSG_DATA_SIZE(imsg)); 425 if ((ra_prefix_conf = malloc(sizeof(struct 426 ra_prefix_conf))) == NULL) 427 fatal(NULL); 428 memcpy(ra_prefix_conf, imsg.data, 429 sizeof(struct ra_prefix_conf)); 430 SIMPLEQ_INSERT_TAIL(&ra_iface_conf->ra_prefix_list, 431 ra_prefix_conf, entry); 432 break; 433 case IMSG_RECONF_RA_RDNSS: 434 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 435 ra_rdnss_conf)) 436 fatalx("%s: IMSG_RECONF_RA_RDNSS wrong length: " 437 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 438 if ((ra_rdnss_conf = malloc(sizeof(struct 439 ra_rdnss_conf))) == NULL) 440 fatal(NULL); 441 memcpy(ra_rdnss_conf, imsg.data, sizeof(struct 442 ra_rdnss_conf)); 443 SIMPLEQ_INSERT_TAIL(&ra_options->ra_rdnss_list, 444 ra_rdnss_conf, entry); 445 break; 446 case IMSG_RECONF_RA_DNSSL: 447 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 448 ra_dnssl_conf)) 449 fatalx("%s: IMSG_RECONF_RA_DNSSL wrong length: " 450 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 451 if ((ra_dnssl_conf = malloc(sizeof(struct 452 ra_dnssl_conf))) == NULL) 453 fatal(NULL); 454 memcpy(ra_dnssl_conf, imsg.data, sizeof(struct 455 ra_dnssl_conf)); 456 SIMPLEQ_INSERT_TAIL(&ra_options->ra_dnssl_list, 457 ra_dnssl_conf, entry); 458 break; 459 case IMSG_RECONF_RA_PREF64: 460 if (IMSG_DATA_SIZE(imsg) != sizeof(struct 461 ra_pref64_conf)) 462 fatalx("%s: IMSG_RECONF_RA_PREF64 wrong length: " 463 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 464 if ((pref64 = malloc(sizeof(struct ra_pref64_conf))) == 465 NULL) 466 fatal(NULL); 467 memcpy(pref64, imsg.data, sizeof(struct ra_pref64_conf)); 468 SIMPLEQ_INSERT_TAIL(&ra_options->ra_pref64_list, pref64, 469 entry); 470 break; 471 case IMSG_RECONF_END: 472 if (nconf == NULL) 473 fatalx("%s: IMSG_RECONF_END without " 474 "IMSG_RECONF_CONF", __func__); 475 merge_config(frontend_conf, nconf); 476 merge_ra_interfaces(); 477 nconf = NULL; 478 break; 479 case IMSG_ICMP6SOCK: 480 if ((icmp6sock = imsg_get_fd(&imsg)) == -1) 481 fatalx("%s: expected to receive imsg " 482 "ICMPv6 fd but didn't receive any", 483 __func__); 484 if (IMSG_DATA_SIZE(imsg) != sizeof(rdomain)) 485 fatalx("%s: IMSG_ICMP6SOCK wrong length: " 486 "%lu", __func__, IMSG_DATA_SIZE(imsg)); 487 memcpy(&rdomain, imsg.data, sizeof(rdomain)); 488 set_icmp6sock(icmp6sock, rdomain); 489 break; 490 case IMSG_ROUTESOCK: 491 if (routesock != -1) 492 fatalx("%s: received unexpected routesock fd", 493 __func__); 494 if ((routesock = imsg_get_fd(&imsg)) == -1) 495 fatalx("%s: expected to receive imsg " 496 "routesocket fd but didn't receive any", 497 __func__); 498 event_set(&ev_route, routesock, EV_READ | EV_PERSIST, 499 route_receive, NULL); 500 break; 501 case IMSG_STARTUP: 502 frontend_startup(); 503 break; 504 case IMSG_CONTROLFD: 505 if ((fd = imsg_get_fd(&imsg)) == -1) 506 fatalx("%s: expected to receive imsg " 507 "control fd but didn't receive any", 508 __func__); 509 /* Listen on control socket. */ 510 control_listen(fd); 511 break; 512 default: 513 log_debug("%s: error handling imsg %d", __func__, 514 imsg.hdr.type); 515 break; 516 } 517 imsg_free(&imsg); 518 } 519 if (!shut) 520 imsg_event_add(iev); 521 else { 522 /* This pipe is dead. Remove its event handler. */ 523 event_del(&iev->ev); 524 event_loopexit(NULL); 525 } 526 } 527 528 void 529 frontend_dispatch_engine(int fd, short event, void *bula) 530 { 531 struct imsgev *iev = bula; 532 struct imsgbuf *ibuf = &iev->ibuf; 533 struct imsg imsg; 534 struct imsg_send_ra send_ra; 535 struct ra_iface *ra_iface; 536 uint32_t if_index; 537 int n, shut = 0; 538 539 if (event & EV_READ) { 540 if ((n = imsgbuf_read(ibuf)) == -1) 541 fatal("imsgbuf_read error"); 542 if (n == 0) /* Connection closed. */ 543 shut = 1; 544 } 545 if (event & EV_WRITE) { 546 if (imsgbuf_write(ibuf) == -1) { 547 if (errno == EPIPE) /* connection closed */ 548 shut = 1; 549 else 550 fatal("imsgbuf_write"); 551 } 552 } 553 554 for (;;) { 555 if ((n = imsg_get(ibuf, &imsg)) == -1) 556 fatal("%s: imsg_get error", __func__); 557 if (n == 0) /* No more messages. */ 558 break; 559 560 switch (imsg.hdr.type) { 561 case IMSG_SEND_RA: 562 if (IMSG_DATA_SIZE(imsg) != sizeof(send_ra)) 563 fatalx("%s: IMSG_SEND_RA wrong length: %lu", 564 __func__, IMSG_DATA_SIZE(imsg)); 565 memcpy(&send_ra, imsg.data, sizeof(send_ra)); 566 ra_iface = find_ra_iface_by_id(send_ra.if_index); 567 if (ra_iface) 568 ra_output(ra_iface, &send_ra.to); 569 break; 570 case IMSG_REMOVE_IF: 571 if (IMSG_DATA_SIZE(imsg) != sizeof(if_index)) 572 fatalx("%s: IMSG_REMOVE_IF wrong length: %lu", 573 __func__, IMSG_DATA_SIZE(imsg)); 574 memcpy(&if_index, imsg.data, sizeof(if_index)); 575 ra_iface = find_ra_iface_by_id(if_index); 576 if (ra_iface) { 577 TAILQ_REMOVE(&ra_interfaces, ra_iface, entry); 578 free_ra_iface(ra_iface); 579 } 580 break; 581 default: 582 log_debug("%s: error handling imsg %d", __func__, 583 imsg.hdr.type); 584 break; 585 } 586 imsg_free(&imsg); 587 } 588 if (!shut) 589 imsg_event_add(iev); 590 else { 591 /* This pipe is dead. Remove its event handler. */ 592 event_del(&iev->ev); 593 event_loopexit(NULL); 594 } 595 } 596 597 void 598 frontend_startup(void) 599 { 600 if (!event_initialized(&ev_route)) 601 fatalx("%s: did not receive a route socket from the main " 602 "process", __func__); 603 604 event_add(&ev_route, NULL); 605 } 606 607 608 void 609 icmp6_receive(int fd, short events, void *arg) 610 { 611 struct icmp6_ev *icmp6ev; 612 struct icmp6_hdr *icmp6_hdr; 613 struct imsg_ra_rs ra_rs; 614 struct in6_pktinfo *pi = NULL; 615 struct cmsghdr *cm; 616 ssize_t len; 617 int if_index = 0, *hlimp = NULL; 618 char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ]; 619 620 icmp6ev = arg; 621 if ((len = recvmsg(fd, &icmp6ev->rcvmhdr, 0)) == -1) { 622 log_warn("recvmsg"); 623 return; 624 } 625 626 if ((size_t)len < sizeof(struct icmp6_hdr)) 627 return; 628 629 icmp6_hdr = (struct icmp6_hdr *)icmp6ev->answer; 630 if (icmp6_hdr->icmp6_type != ND_ROUTER_ADVERT && 631 icmp6_hdr->icmp6_type != ND_ROUTER_SOLICIT) 632 return; 633 634 /* extract optional information via Advanced API */ 635 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&icmp6ev->rcvmhdr); cm; 636 cm = (struct cmsghdr *)CMSG_NXTHDR(&icmp6ev->rcvmhdr, cm)) { 637 if (cm->cmsg_level == IPPROTO_IPV6 && 638 cm->cmsg_type == IPV6_PKTINFO && 639 cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { 640 pi = (struct in6_pktinfo *)(CMSG_DATA(cm)); 641 if_index = pi->ipi6_ifindex; 642 } 643 if (cm->cmsg_level == IPPROTO_IPV6 && 644 cm->cmsg_type == IPV6_HOPLIMIT && 645 cm->cmsg_len == CMSG_LEN(sizeof(int))) 646 hlimp = (int *)CMSG_DATA(cm); 647 } 648 649 if (if_index == 0) { 650 log_warnx("failed to get receiving interface"); 651 return; 652 } 653 654 if (hlimp == NULL) { 655 log_warnx("failed to get receiving hop limit"); 656 return; 657 } 658 659 if (*hlimp != 255) { 660 log_warnx("invalid RA or RS with hop limit of %d from %s on %s", 661 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 662 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 663 ifnamebuf)); 664 return; 665 } 666 667 log_debug("RA or RS with hop limit of %d from %s on %s", 668 *hlimp, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 669 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 670 ifnamebuf)); 671 672 if ((size_t)len > sizeof(ra_rs.packet)) { 673 log_warnx("invalid RA or RS with size %ld from %s on %s", 674 len, inet_ntop(AF_INET6, &icmp6ev->from.sin6_addr, 675 ntopbuf, INET6_ADDRSTRLEN), if_indextoname(if_index, 676 ifnamebuf)); 677 return; 678 } 679 680 ra_rs.if_index = if_index; 681 memcpy(&ra_rs.from, &icmp6ev->from, sizeof(ra_rs.from)); 682 ra_rs.len = len; 683 memcpy(ra_rs.packet, icmp6ev->answer, len); 684 685 frontend_imsg_compose_engine(IMSG_RA_RS, 0, &ra_rs, sizeof(ra_rs)); 686 } 687 688 void 689 join_all_routers_mcast_group(struct ra_iface *ra_iface) 690 { 691 if (!event_initialized(&ra_iface->icmp6ev->ev)) 692 return; 693 log_debug("joining multicast group on %s", ra_iface->name); 694 all_routers.ipv6mr_interface = ra_iface->if_index; 695 if (setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6, 696 IPV6_JOIN_GROUP, &all_routers, sizeof(all_routers)) == -1) 697 fatal("IPV6_JOIN_GROUP(%s)", ra_iface->name); 698 } 699 700 void 701 leave_all_routers_mcast_group(struct ra_iface *ra_iface) 702 { 703 if (!event_initialized(&ra_iface->icmp6ev->ev)) 704 return; 705 log_debug("leaving multicast group on %s", ra_iface->name); 706 all_routers.ipv6mr_interface = ra_iface->if_index; 707 setsockopt(EVENT_FD(&ra_iface->icmp6ev->ev), IPPROTO_IPV6, 708 IPV6_LEAVE_GROUP, &all_routers, sizeof(all_routers)); 709 } 710 711 struct ra_iface* 712 find_ra_iface_by_id(uint32_t if_index) 713 { 714 struct ra_iface *ra_iface; 715 716 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 717 if (ra_iface->if_index == if_index) 718 return ra_iface; 719 } 720 return (NULL); 721 } 722 723 struct ra_iface* 724 find_ra_iface_by_name(char *if_name) 725 { 726 struct ra_iface *ra_iface; 727 728 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 729 if (strcmp(ra_iface->name, if_name) == 0) 730 return ra_iface; 731 } 732 return (NULL); 733 } 734 735 struct ra_iface_conf* 736 find_ra_iface_conf(struct ra_iface_conf_head *head, char *if_name) 737 { 738 struct ra_iface_conf *ra_iface_conf; 739 740 SIMPLEQ_FOREACH(ra_iface_conf, head, entry) { 741 if (strcmp(ra_iface_conf->name, if_name) == 0) 742 return ra_iface_conf; 743 } 744 return (NULL); 745 } 746 747 int 748 get_ifrdomain(char *if_name) 749 { 750 struct ifreq ifr; 751 752 strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); 753 if (ioctl(ioctlsock, SIOCGIFRDOMAIN, (caddr_t)&ifr) == -1) { 754 log_warn("SIOCGIFRDOMAIN"); 755 return -1; 756 } 757 return ifr.ifr_rdomainid; 758 } 759 760 void 761 merge_ra_interface(char *if_name, char *conf_name, struct ifaddrs *ifap) 762 { 763 struct ra_iface *ra_iface; 764 struct ifaddrs *ifa; 765 struct sockaddr_in6 *sin6; 766 struct in6_ifreq ifr6; 767 struct sockaddr_dl *sdl; 768 struct ether_addr hw_addr; 769 uint32_t if_index; 770 int link_state = LINK_STATE_UNKNOWN; 771 int has_linklocal = 0, ifrdomain; 772 int has_hw_addr = 0; 773 774 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 775 if (ifa->ifa_addr == NULL) 776 continue; 777 if (ifa->ifa_addr->sa_family != AF_LINK && 778 ifa->ifa_addr->sa_family != AF_INET6) 779 continue; 780 if (strcmp(if_name, ifa->ifa_name) != 0) 781 continue; 782 783 if (ifa->ifa_addr->sa_family == AF_LINK) { 784 link_state = 785 ((struct if_data*)ifa->ifa_data)->ifi_link_state; 786 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 787 if (sdl != NULL && (sdl->sdl_type == IFT_ETHER || 788 sdl->sdl_type == IFT_CARP) && sdl->sdl_alen == 789 ETHER_ADDR_LEN) { 790 has_hw_addr = 1; 791 memcpy(&hw_addr, LLADDR(sdl), ETHER_ADDR_LEN); 792 } 793 } else if (ifa->ifa_addr->sa_family == AF_INET6) { 794 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 795 796 if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 797 continue; 798 799 memset(&ifr6, 0, sizeof(ifr6)); 800 strlcpy(ifr6.ifr_name, if_name, sizeof(ifr6.ifr_name)); 801 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); 802 if (ioctl(ioctlsock, SIOCGIFAFLAG_IN6, 803 (caddr_t)&ifr6) == -1) { 804 log_warn("SIOCGIFAFLAG_IN6"); 805 continue; 806 } 807 808 if (ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_TENTATIVE | 809 IN6_IFF_DUPLICATED)) 810 continue; 811 has_linklocal = 1; 812 } 813 } 814 815 ifrdomain = get_ifrdomain(if_name); 816 817 if ((ra_iface = find_ra_iface_by_name(if_name)) != NULL) { 818 ra_iface->link_state = link_state; 819 if (!LINK_STATE_IS_UP(link_state)) { 820 log_debug("%s down, removing", if_name); 821 ra_iface->removed = 1; 822 } else if (!has_linklocal) { 823 log_debug("%s has no IPv6 link-local address, " 824 "removing", if_name); 825 ra_iface->removed = 1; 826 } else if (ifrdomain == -1) { 827 log_debug("can't get rdomain for %s, removing", if_name); 828 ra_iface->removed = 1; 829 } else if (!has_hw_addr) { 830 log_debug("%s has no mac address, removing", if_name); 831 ra_iface->removed = 1; 832 } else if (ra_iface->rdomain != ifrdomain) { 833 leave_all_routers_mcast_group(ra_iface); 834 unref_icmp6ev(ra_iface); 835 ra_iface->rdomain = ifrdomain; 836 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain); 837 join_all_routers_mcast_group(ra_iface); 838 ra_iface->removed = 0; 839 } else { 840 log_debug("keeping interface %s", if_name); 841 ra_iface->removed = 0; 842 } 843 memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr)); 844 return; 845 } 846 847 if (!LINK_STATE_IS_UP(link_state)) { 848 log_debug("%s down, ignoring", if_name); 849 return; 850 } 851 852 if (!has_linklocal) { 853 log_debug("%s has no IPv6 link-local address, ignoring", 854 if_name); 855 return; 856 } 857 858 if (ifrdomain == -1) { 859 log_debug("can't get rdomain for %s, ignoring", if_name); 860 return; 861 } 862 863 if (!has_hw_addr) { 864 log_debug("%s has no mac address, ignoring", if_name); 865 return; 866 } 867 868 log_debug("new interface %s", if_name); 869 if ((if_index = if_nametoindex(if_name)) == 0) 870 return; 871 872 log_debug("adding interface %s", if_name); 873 if ((ra_iface = calloc(1, sizeof(*ra_iface))) == NULL) 874 fatal("%s", __func__); 875 876 strlcpy(ra_iface->name, if_name, sizeof(ra_iface->name)); 877 strlcpy(ra_iface->conf_name, conf_name, 878 sizeof(ra_iface->conf_name)); 879 880 ra_iface->if_index = if_index; 881 ra_iface->rdomain = ifrdomain; 882 memcpy(&ra_iface->hw_addr, &hw_addr, sizeof(hw_addr)); 883 SIMPLEQ_INIT(&ra_iface->prefixes); 884 885 ra_iface->icmp6ev = get_icmp6ev_by_rdomain(ifrdomain); 886 join_all_routers_mcast_group(ra_iface); 887 TAILQ_INSERT_TAIL(&ra_interfaces, ra_iface, entry); 888 } 889 890 void 891 merge_ra_interfaces(void) 892 { 893 struct ra_iface_conf *ra_iface_conf; 894 struct ra_prefix_conf *ra_prefix_conf; 895 struct ra_iface *ra_iface; 896 struct ifgroupreq ifgr; 897 struct ifg_req *ifg; 898 struct ifaddrs *ifap; 899 char *conf_name; 900 unsigned int len; 901 902 if (getifaddrs(&ifap) != 0) { 903 log_warn("getifaddrs"); 904 return; 905 } 906 907 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) 908 ra_iface->removed = 1; 909 910 SIMPLEQ_FOREACH(ra_iface_conf, &frontend_conf->ra_iface_list, entry) { 911 conf_name = ra_iface_conf->name; 912 913 /* check if network interface or group */ 914 if (isdigit((unsigned char)conf_name[strlen(conf_name) - 1])) { 915 merge_ra_interface(conf_name, conf_name, ifap); 916 } else { 917 log_debug("interface group %s", conf_name); 918 919 memset(&ifgr, 0, sizeof(ifgr)); 920 strlcpy(ifgr.ifgr_name, conf_name, 921 sizeof(ifgr.ifgr_name)); 922 if (ioctl(ioctlsock, SIOCGIFGMEMB, 923 (caddr_t)&ifgr) == -1) 924 continue; 925 926 len = ifgr.ifgr_len; 927 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 928 fatal("%s: calloc", __func__); 929 if (ioctl(ioctlsock, SIOCGIFGMEMB, 930 (caddr_t)&ifgr) == -1) { 931 log_debug("group %s without members", 932 conf_name); 933 free(ifgr.ifgr_groups); 934 continue; 935 } 936 937 for (ifg = ifgr.ifgr_groups; 938 (ifg != NULL) && (len >= sizeof(struct ifg_req)); 939 ifg++) { 940 len -= sizeof(struct ifg_req); 941 merge_ra_interface(ifg->ifgrq_member, 942 conf_name, ifap); 943 } 944 free(ifgr.ifgr_groups); 945 } 946 } 947 948 TAILQ_FOREACH(ra_iface, &ra_interfaces, entry) { 949 while ((ra_prefix_conf = SIMPLEQ_FIRST(&ra_iface->prefixes)) 950 != NULL) { 951 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes, 952 entry); 953 free(ra_prefix_conf); 954 } 955 ra_iface->prefix_count = 0; 956 957 if (ra_iface->removed) { 958 log_debug("iface removed: %s", ra_iface->name); 959 build_leaving_packet(ra_iface); 960 frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 961 &ra_iface->if_index, sizeof(ra_iface->if_index)); 962 continue; 963 } 964 965 ra_iface_conf = find_ra_iface_conf( 966 &frontend_conf->ra_iface_list, ra_iface->conf_name); 967 968 log_debug("add static prefixes for %s", ra_iface->name); 969 970 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface_conf->ra_prefix_list, 971 entry) { 972 add_new_prefix_to_ra_iface(ra_iface, 973 &ra_prefix_conf->prefix, 974 ra_prefix_conf->prefixlen, ra_prefix_conf, 975 ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME); 976 } 977 978 if (ra_iface_conf->autoprefix) 979 get_interface_prefixes(ra_iface, 980 ra_iface_conf->autoprefix, ifap); 981 982 if (build_packet(ra_iface)) { 983 /* packet changed; send new advertisements */ 984 if (event_initialized(&ra_iface->icmp6ev->ev)) 985 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 986 &ra_iface->if_index, 987 sizeof(ra_iface->if_index)); 988 } 989 } 990 freeifaddrs(ifap); 991 } 992 993 void 994 free_ra_iface(struct ra_iface *ra_iface) 995 { 996 struct ra_prefix_conf *prefix; 997 998 leave_all_routers_mcast_group(ra_iface); 999 1000 while ((prefix = SIMPLEQ_FIRST(&ra_iface->prefixes)) != NULL) { 1001 SIMPLEQ_REMOVE_HEAD(&ra_iface->prefixes, entry); 1002 free(prefix); 1003 } 1004 1005 unref_icmp6ev(ra_iface); 1006 free(ra_iface); 1007 } 1008 1009 /* from kame via ifconfig, where it's called prefix() */ 1010 int 1011 in6_mask2prefixlen(struct in6_addr *in6) 1012 { 1013 u_char *nam = (u_char *)in6; 1014 int byte, bit, plen = 0, size = sizeof(struct in6_addr); 1015 1016 for (byte = 0; byte < size; byte++, plen += 8) 1017 if (nam[byte] != 0xff) 1018 break; 1019 if (byte == size) 1020 return (plen); 1021 for (bit = 7; bit != 0; bit--, plen++) 1022 if (!(nam[byte] & (1 << bit))) 1023 break; 1024 for (; bit != 0; bit--) 1025 if (nam[byte] & (1 << bit)) 1026 return (0); 1027 byte++; 1028 for (; byte < size; byte++) 1029 if (nam[byte]) 1030 return (0); 1031 return (plen); 1032 } 1033 1034 void 1035 get_interface_prefixes(struct ra_iface *ra_iface, struct ra_prefix_conf 1036 *autoprefix_conf, struct ifaddrs *ifap) 1037 { 1038 struct in6_ifreq ifr6; 1039 struct ifaddrs *ifa; 1040 struct sockaddr_in6 *sin6; 1041 uint32_t decaying_vltime, decaying_pltime; 1042 int prefixlen; 1043 1044 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 1045 if (ifa->ifa_addr == NULL || 1046 ifa->ifa_addr->sa_family != AF_INET6) 1047 continue; 1048 1049 if (strcmp(ra_iface->name, ifa->ifa_name) != 0) 1050 continue; 1051 1052 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1053 1054 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 1055 continue; 1056 1057 memset(&ifr6, 0, sizeof(ifr6)); 1058 strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name)); 1059 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); 1060 1061 decaying_vltime = ND6_INFINITE_LIFETIME; 1062 decaying_pltime = ND6_INFINITE_LIFETIME; 1063 1064 if (ioctl(ioctlsock, SIOCGIFALIFETIME_IN6, 1065 (caddr_t)&ifr6) != -1) { 1066 struct in6_addrlifetime *lifetime; 1067 1068 lifetime = &ifr6.ifr_ifru.ifru_lifetime; 1069 if (lifetime->ia6t_preferred) 1070 decaying_pltime = lifetime->ia6t_preferred; 1071 if (lifetime->ia6t_expire) 1072 decaying_vltime = lifetime->ia6t_expire; 1073 } 1074 1075 memset(&ifr6, 0, sizeof(ifr6)); 1076 strlcpy(ifr6.ifr_name, ra_iface->name, sizeof(ifr6.ifr_name)); 1077 memcpy(&ifr6.ifr_addr, sin6, sizeof(ifr6.ifr_addr)); 1078 1079 if (ioctl(ioctlsock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1) 1080 continue; /* addr got deleted while we were looking */ 1081 1082 prefixlen = in6_mask2prefixlen(&((struct sockaddr_in6 *) 1083 &ifr6.ifr_addr)->sin6_addr); 1084 1085 if (prefixlen == 128) 1086 continue; 1087 1088 mask_prefix(&sin6->sin6_addr, prefixlen); 1089 1090 add_new_prefix_to_ra_iface(ra_iface, &sin6->sin6_addr, 1091 prefixlen, autoprefix_conf, decaying_vltime, 1092 decaying_pltime); 1093 } 1094 } 1095 1096 struct ra_prefix_conf* 1097 find_ra_prefix_conf(struct ra_prefix_conf_head* head, struct in6_addr *prefix, 1098 int prefixlen) 1099 { 1100 struct ra_prefix_conf *ra_prefix_conf; 1101 1102 SIMPLEQ_FOREACH(ra_prefix_conf, head, entry) { 1103 if (ra_prefix_conf->prefixlen == prefixlen && 1104 memcmp(&ra_prefix_conf->prefix, prefix, sizeof(*prefix)) == 1105 0) 1106 return (ra_prefix_conf); 1107 } 1108 return (NULL); 1109 } 1110 1111 void 1112 add_new_prefix_to_ra_iface(struct ra_iface *ra_iface, struct in6_addr *addr, 1113 int prefixlen, struct ra_prefix_conf *ra_prefix_conf, 1114 uint32_t decaying_vltime, uint32_t decaying_pltime) 1115 { 1116 struct ra_prefix_conf *new_ra_prefix_conf; 1117 1118 if ((new_ra_prefix_conf = find_ra_prefix_conf(&ra_iface->prefixes, addr, 1119 prefixlen)) != NULL) { 1120 if (decaying_vltime != ND6_INFINITE_LIFETIME || 1121 decaying_pltime != ND6_INFINITE_LIFETIME) { 1122 ra_iface->ltime_decaying = 1; 1123 new_ra_prefix_conf->ltime_decaying = 0; 1124 if (decaying_vltime != ND6_INFINITE_LIFETIME) { 1125 new_ra_prefix_conf->vltime = decaying_vltime; 1126 new_ra_prefix_conf->ltime_decaying |= 1127 VLTIME_DECAYING; 1128 } 1129 if (decaying_pltime != ND6_INFINITE_LIFETIME) { 1130 new_ra_prefix_conf->pltime = decaying_pltime; 1131 new_ra_prefix_conf->ltime_decaying |= 1132 PLTIME_DECAYING; 1133 } 1134 } else if (new_ra_prefix_conf->ltime_decaying) { 1135 struct ra_prefix_conf *pc; 1136 1137 new_ra_prefix_conf->ltime_decaying = 0; 1138 ra_iface->ltime_decaying = 0; 1139 SIMPLEQ_FOREACH(pc, &ra_iface->prefixes, entry) { 1140 if (pc->ltime_decaying) { 1141 ra_iface->ltime_decaying = 1; 1142 break; 1143 } 1144 } 1145 } else 1146 log_debug("ignoring duplicate %s/%d prefix", 1147 in6_to_str(addr), prefixlen); 1148 return; 1149 } 1150 1151 log_debug("adding %s/%d prefix", in6_to_str(addr), prefixlen); 1152 1153 if ((new_ra_prefix_conf = calloc(1, sizeof(*ra_prefix_conf))) == NULL) 1154 fatal("%s", __func__); 1155 new_ra_prefix_conf->prefix = *addr; 1156 new_ra_prefix_conf->prefixlen = prefixlen; 1157 new_ra_prefix_conf->vltime = ra_prefix_conf->vltime; 1158 new_ra_prefix_conf->pltime = ra_prefix_conf->pltime; 1159 if (decaying_vltime != ND6_INFINITE_LIFETIME || 1160 decaying_pltime != ND6_INFINITE_LIFETIME) { 1161 ra_iface->ltime_decaying = 1; 1162 if (decaying_vltime != ND6_INFINITE_LIFETIME) { 1163 new_ra_prefix_conf->vltime = decaying_vltime; 1164 new_ra_prefix_conf->ltime_decaying |= VLTIME_DECAYING; 1165 } 1166 if (decaying_pltime != ND6_INFINITE_LIFETIME) { 1167 new_ra_prefix_conf->pltime = decaying_pltime; 1168 new_ra_prefix_conf->ltime_decaying |= PLTIME_DECAYING; 1169 } 1170 } 1171 new_ra_prefix_conf->aflag = ra_prefix_conf->aflag; 1172 new_ra_prefix_conf->lflag = ra_prefix_conf->lflag; 1173 SIMPLEQ_INSERT_TAIL(&ra_iface->prefixes, new_ra_prefix_conf, entry); 1174 ra_iface->prefix_count++; 1175 } 1176 1177 int 1178 build_packet(struct ra_iface *ra_iface) 1179 { 1180 struct nd_router_advert *ra; 1181 struct nd_opt_source_link_addr *ndopt_source_link_addr; 1182 struct nd_opt_mtu *ndopt_mtu; 1183 struct nd_opt_prefix_info *ndopt_pi; 1184 struct ra_iface_conf *ra_iface_conf; 1185 struct ra_options_conf *ra_options_conf; 1186 struct ra_prefix_conf *ra_prefix_conf; 1187 struct nd_opt_rdnss *ndopt_rdnss; 1188 struct nd_opt_dnssl *ndopt_dnssl; 1189 struct nd_opt_pref64 *ndopt_pref64; 1190 struct ra_rdnss_conf *ra_rdnss; 1191 struct ra_dnssl_conf *ra_dnssl; 1192 struct ra_pref64_conf *pref64; 1193 size_t len, label_len; 1194 time_t t; 1195 uint32_t vltime, pltime; 1196 uint8_t *p, buf[RA_MAX_SIZE]; 1197 char *label_start, *label_end; 1198 1199 ra_iface_conf = find_ra_iface_conf(&frontend_conf->ra_iface_list, 1200 ra_iface->conf_name); 1201 ra_options_conf = &ra_iface_conf->ra_options; 1202 t = time(NULL); 1203 len = sizeof(*ra); 1204 if (ra_iface_conf->ra_options.source_link_addr) 1205 len += sizeof(*ndopt_source_link_addr); 1206 if (ra_options_conf->mtu > 0) 1207 len += sizeof(*ndopt_mtu); 1208 len += sizeof(*ndopt_pi) * ra_iface->prefix_count; 1209 if (ra_iface_conf->ra_options.rdnss_count > 0) 1210 len += sizeof(*ndopt_rdnss) + 1211 ra_iface_conf->ra_options.rdnss_count * 1212 sizeof(struct in6_addr); 1213 1214 if (ra_iface_conf->ra_options.dnssl_len > 0) 1215 /* round up to 8 byte boundary */ 1216 len += sizeof(*ndopt_dnssl) + 1217 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7); 1218 1219 SIMPLEQ_FOREACH(pref64, &ra_iface_conf->ra_options.ra_pref64_list, 1220 entry) 1221 len += sizeof(struct nd_opt_pref64); 1222 1223 if (len > sizeof(ra_iface->data)) 1224 fatalx("%s: packet too big", __func__); /* XXX send multiple */ 1225 1226 p = buf; 1227 1228 ra = (struct nd_router_advert *)p; 1229 1230 memset(ra, 0, sizeof(*ra)); 1231 1232 ra->nd_ra_type = ND_ROUTER_ADVERT; 1233 ra->nd_ra_curhoplimit = ra_options_conf->cur_hl; 1234 if (ra_options_conf->m_flag) 1235 ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; 1236 if (ra_options_conf->o_flag) 1237 ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; 1238 if (ra_iface->removed) 1239 /* tell clients that we are no longer a default router */ 1240 ra->nd_ra_router_lifetime = 0; 1241 else if (ra_options_conf->dfr) { 1242 ra->nd_ra_router_lifetime = 1243 htons(ra_options_conf->router_lifetime); 1244 /* 1245 * RFC 4191 1246 * If the Router Lifetime is zero, the preference value MUST be 1247 * set to (00) by the sender and MUST be ignored by the 1248 * receiver. 1249 */ 1250 if (ra_options_conf->router_lifetime > 0) 1251 ra->nd_ra_flags_reserved |= ra_options_conf->rtpref; 1252 } 1253 ra->nd_ra_reachable = htonl(ra_options_conf->reachable_time); 1254 ra->nd_ra_retransmit = htonl(ra_options_conf->retrans_timer); 1255 p += sizeof(*ra); 1256 1257 if (ra_iface_conf->ra_options.source_link_addr) { 1258 ndopt_source_link_addr = (struct nd_opt_source_link_addr *)p; 1259 ndopt_source_link_addr->nd_opt_source_link_addr_type = 1260 ND_OPT_SOURCE_LINKADDR; 1261 ndopt_source_link_addr->nd_opt_source_link_addr_len = 1; 1262 memcpy(&ndopt_source_link_addr->nd_opt_source_link_addr_hw_addr, 1263 &ra_iface->hw_addr, ETHER_ADDR_LEN); 1264 p += sizeof(*ndopt_source_link_addr); 1265 } 1266 1267 if (ra_options_conf->mtu > 0) { 1268 ndopt_mtu = (struct nd_opt_mtu *)p; 1269 ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU; 1270 ndopt_mtu->nd_opt_mtu_len = 1; 1271 ndopt_mtu->nd_opt_mtu_reserved = 0; 1272 ndopt_mtu->nd_opt_mtu_mtu = htonl(ra_options_conf->mtu); 1273 p += sizeof(*ndopt_mtu); 1274 } 1275 1276 SIMPLEQ_FOREACH(ra_prefix_conf, &ra_iface->prefixes, entry) { 1277 ndopt_pi = (struct nd_opt_prefix_info *)p; 1278 memset(ndopt_pi, 0, sizeof(*ndopt_pi)); 1279 ndopt_pi->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; 1280 ndopt_pi->nd_opt_pi_len = 4; 1281 ndopt_pi->nd_opt_pi_prefix_len = ra_prefix_conf->prefixlen; 1282 if (ra_prefix_conf->lflag) 1283 ndopt_pi->nd_opt_pi_flags_reserved |= 1284 ND_OPT_PI_FLAG_ONLINK; 1285 if (ra_prefix_conf->aflag) 1286 ndopt_pi->nd_opt_pi_flags_reserved |= 1287 ND_OPT_PI_FLAG_AUTO; 1288 1289 if (ra_prefix_conf->ltime_decaying & VLTIME_DECAYING) 1290 vltime = ra_prefix_conf->vltime < t ? 0 : 1291 ra_prefix_conf->vltime - t; 1292 else 1293 vltime = ra_prefix_conf->vltime; 1294 if (ra_prefix_conf->ltime_decaying & PLTIME_DECAYING) 1295 pltime = ra_prefix_conf->pltime < t ? 0 : 1296 ra_prefix_conf->pltime - t; 1297 else 1298 pltime = ra_prefix_conf->pltime; 1299 1300 ndopt_pi->nd_opt_pi_valid_time = htonl(vltime); 1301 ndopt_pi->nd_opt_pi_preferred_time = htonl(pltime); 1302 ndopt_pi->nd_opt_pi_prefix = ra_prefix_conf->prefix; 1303 1304 p += sizeof(*ndopt_pi); 1305 } 1306 1307 if (ra_iface_conf->ra_options.rdnss_count > 0) { 1308 ndopt_rdnss = (struct nd_opt_rdnss *)p; 1309 ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS; 1310 ndopt_rdnss->nd_opt_rdnss_len = 1 + 1311 ra_iface_conf->ra_options.rdnss_count * 2; 1312 ndopt_rdnss->nd_opt_rdnss_reserved = 0; 1313 ndopt_rdnss->nd_opt_rdnss_lifetime = 1314 htonl(ra_iface_conf->ra_options.rdns_lifetime); 1315 p += sizeof(struct nd_opt_rdnss); 1316 SIMPLEQ_FOREACH(ra_rdnss, 1317 &ra_iface_conf->ra_options.ra_rdnss_list, entry) { 1318 memcpy(p, &ra_rdnss->rdnss, sizeof(ra_rdnss->rdnss)); 1319 p += sizeof(ra_rdnss->rdnss); 1320 } 1321 } 1322 1323 if (ra_iface_conf->ra_options.dnssl_len > 0) { 1324 ndopt_dnssl = (struct nd_opt_dnssl *)p; 1325 ndopt_dnssl->nd_opt_dnssl_type = ND_OPT_DNSSL; 1326 /* round up to 8 byte boundary */ 1327 ndopt_dnssl->nd_opt_dnssl_len = 1 + 1328 ((ra_iface_conf->ra_options.dnssl_len + 7) & ~7) / 8; 1329 ndopt_dnssl->nd_opt_dnssl_reserved = 0; 1330 ndopt_dnssl->nd_opt_dnssl_lifetime = 1331 htonl(ra_iface_conf->ra_options.rdns_lifetime); 1332 p += sizeof(struct nd_opt_dnssl); 1333 1334 SIMPLEQ_FOREACH(ra_dnssl, 1335 &ra_iface_conf->ra_options.ra_dnssl_list, entry) { 1336 label_start = ra_dnssl->search; 1337 while ((label_end = strchr(label_start, '.')) != NULL) { 1338 label_len = label_end - label_start; 1339 *p++ = label_len; 1340 memcpy(p, label_start, label_len); 1341 p += label_len; 1342 label_start = label_end + 1; 1343 } 1344 *p++ = '\0'; /* last dot */ 1345 } 1346 /* zero pad */ 1347 while (((uintptr_t)p) % 8 != 0) 1348 *p++ = '\0'; 1349 } 1350 1351 SIMPLEQ_FOREACH(pref64, &ra_iface_conf->ra_options.ra_pref64_list, 1352 entry) { 1353 uint16_t sltime_plc; 1354 1355 /* scaled lifetime in units of 8 seconds */ 1356 sltime_plc = pref64->ltime / 8; 1357 sltime_plc = sltime_plc << 3; 1358 /* encode prefix length in lower 3 bits */ 1359 switch (pref64->prefixlen) { 1360 case 96: 1361 sltime_plc |= 0; 1362 break; 1363 case 64: 1364 sltime_plc |= 1; 1365 break; 1366 case 56: 1367 sltime_plc |= 2; 1368 break; 1369 case 48: 1370 sltime_plc |= 3; 1371 break; 1372 case 40: 1373 sltime_plc |= 4; 1374 break; 1375 case 32: 1376 sltime_plc |= 5; 1377 break; 1378 default: 1379 fatalx("%s: invalid pref64 length: %d", __func__, 1380 pref64->prefixlen); 1381 } 1382 ndopt_pref64 = (struct nd_opt_pref64 *)p; 1383 ndopt_pref64->nd_opt_pref64_type = ND_OPT_PREF64; 1384 ndopt_pref64->nd_opt_pref64_len = 2; 1385 ndopt_pref64->nd_opt_pref64_sltime_plc = htons(sltime_plc); 1386 memcpy(ndopt_pref64->nd_opt_pref64, &pref64->prefix, 1387 sizeof(ndopt_pref64->nd_opt_pref64)); 1388 p += sizeof(struct nd_opt_pref64); 1389 } 1390 1391 if (len != ra_iface->datalen || memcmp(buf, ra_iface->data, len) 1392 != 0) { 1393 memcpy(ra_iface->data, buf, len); 1394 ra_iface->datalen = len; 1395 return 1; 1396 } 1397 return 0; 1398 } 1399 1400 void 1401 build_leaving_packet(struct ra_iface *ra_iface) 1402 { 1403 struct nd_router_advert ra; 1404 1405 memset(&ra, 0, sizeof(ra)); 1406 1407 ra.nd_ra_type = ND_ROUTER_ADVERT; 1408 1409 memcpy(ra_iface->data, &ra, sizeof(ra)); 1410 ra_iface->datalen = sizeof(ra); 1411 } 1412 1413 void 1414 ra_output(struct ra_iface *ra_iface, struct sockaddr_in6 *to) 1415 { 1416 1417 struct cmsghdr *cm; 1418 struct in6_pktinfo *pi; 1419 ssize_t len; 1420 int hoplimit = 255; 1421 1422 if (!LINK_STATE_IS_UP(ra_iface->link_state)) 1423 return; 1424 1425 if (ra_iface->ltime_decaying) 1426 /* update vltime & pltime */ 1427 build_packet(ra_iface); 1428 1429 sndmhdr.msg_name = to; 1430 sndmhdr.msg_iov[0].iov_base = ra_iface->data; 1431 sndmhdr.msg_iov[0].iov_len = ra_iface->datalen; 1432 1433 cm = CMSG_FIRSTHDR(&sndmhdr); 1434 /* specify the outgoing interface */ 1435 cm->cmsg_level = IPPROTO_IPV6; 1436 cm->cmsg_type = IPV6_PKTINFO; 1437 cm->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 1438 pi = (struct in6_pktinfo *)CMSG_DATA(cm); 1439 memset(&pi->ipi6_addr, 0, sizeof(pi->ipi6_addr)); 1440 pi->ipi6_ifindex = ra_iface->if_index; 1441 1442 /* specify the hop limit of the packet */ 1443 cm = CMSG_NXTHDR(&sndmhdr, cm); 1444 cm->cmsg_level = IPPROTO_IPV6; 1445 cm->cmsg_type = IPV6_HOPLIMIT; 1446 cm->cmsg_len = CMSG_LEN(sizeof(int)); 1447 memcpy(CMSG_DATA(cm), &hoplimit, sizeof(int)); 1448 1449 log_debug("send RA on %s", ra_iface->name); 1450 1451 len = sendmsg(EVENT_FD(&ra_iface->icmp6ev->ev), &sndmhdr, 0); 1452 if (len == -1) 1453 log_warn("sendmsg on %s", ra_iface->name); 1454 1455 } 1456 1457 #define ROUNDUP(a) \ 1458 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) 1459 1460 void 1461 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 1462 { 1463 int i; 1464 1465 for (i = 0; i < RTAX_MAX; i++) { 1466 if (addrs & (1 << i)) { 1467 rti_info[i] = sa; 1468 sa = (struct sockaddr *)((char *)(sa) + 1469 ROUNDUP(sa->sa_len)); 1470 } else 1471 rti_info[i] = NULL; 1472 } 1473 } 1474 1475 void 1476 route_receive(int fd, short events, void *arg) 1477 { 1478 static uint8_t *buf; 1479 1480 struct rt_msghdr *rtm; 1481 struct sockaddr *sa, *rti_info[RTAX_MAX]; 1482 ssize_t n; 1483 1484 if (buf == NULL) { 1485 buf = malloc(ROUTE_SOCKET_BUF_SIZE); 1486 if (buf == NULL) 1487 fatal("malloc"); 1488 } 1489 rtm = (struct rt_msghdr *)buf; 1490 if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) { 1491 if (errno == EAGAIN || errno == EINTR) 1492 return; 1493 log_warn("dispatch_rtmsg: read error"); 1494 return; 1495 } 1496 1497 if (n == 0) 1498 fatal("routing socket closed"); 1499 1500 if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) { 1501 log_warnx("partial rtm of %zd in buffer", n); 1502 return; 1503 } 1504 1505 if (rtm->rtm_version != RTM_VERSION) 1506 return; 1507 1508 sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen); 1509 get_rtaddrs(rtm->rtm_addrs, sa, rti_info); 1510 1511 handle_route_message(rtm, rti_info); 1512 } 1513 1514 void 1515 handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) 1516 { 1517 switch (rtm->rtm_type) { 1518 case RTM_IFINFO: 1519 case RTM_NEWADDR: 1520 case RTM_DELADDR: 1521 case RTM_CHGADDRATTR: 1522 /* 1523 * do the same thing as after a config reload when interfaces 1524 * change or IPv6 addresses show up / disappear 1525 */ 1526 merge_ra_interfaces(); 1527 break; 1528 default: 1529 log_debug("unexpected RTM: %d", rtm->rtm_type); 1530 break; 1531 } 1532 } 1533 1534 struct icmp6_ev* 1535 get_icmp6ev_by_rdomain(int rdomain) 1536 { 1537 struct ra_iface *ra_iface; 1538 struct icmp6_ev *icmp6ev = NULL; 1539 1540 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1541 if (ra_iface->rdomain == rdomain) { 1542 icmp6ev = ra_iface->icmp6ev; 1543 break; 1544 } 1545 } 1546 1547 if (icmp6ev == NULL) { 1548 if ((icmp6ev = calloc(1, sizeof(*icmp6ev))) == NULL) 1549 fatal("calloc"); 1550 1551 icmp6ev->rcviov[0].iov_base = (caddr_t)icmp6ev->answer; 1552 icmp6ev->rcviov[0].iov_len = sizeof(icmp6ev->answer); 1553 icmp6ev->rcvmhdr.msg_name = (caddr_t)&icmp6ev->from; 1554 icmp6ev->rcvmhdr.msg_namelen = sizeof(icmp6ev->from); 1555 icmp6ev->rcvmhdr.msg_iov = icmp6ev->rcviov; 1556 icmp6ev->rcvmhdr.msg_iovlen = 1; 1557 icmp6ev->rcvmhdr.msg_controllen = 1558 CMSG_SPACE(sizeof(struct in6_pktinfo)) + 1559 CMSG_SPACE(sizeof(int)); 1560 if ((icmp6ev->rcvmhdr.msg_control = malloc(icmp6ev-> 1561 rcvmhdr.msg_controllen)) == NULL) 1562 fatal("malloc"); 1563 frontend_imsg_compose_main(IMSG_OPEN_ICMP6SOCK, 0, 1564 &rdomain, sizeof(rdomain)); 1565 } 1566 1567 icmp6ev->refcnt++; 1568 return (icmp6ev); 1569 } 1570 1571 void 1572 unref_icmp6ev(struct ra_iface *ra_iface) 1573 { 1574 struct icmp6_ev *icmp6ev = ra_iface->icmp6ev; 1575 1576 ra_iface->icmp6ev = NULL; 1577 1578 if (icmp6ev != NULL) { 1579 icmp6ev->refcnt--; 1580 if (icmp6ev->refcnt == 0) { 1581 event_del(&icmp6ev->ev); 1582 close(EVENT_FD(&icmp6ev->ev)); 1583 free(icmp6ev); 1584 } 1585 } 1586 } 1587 1588 void 1589 set_icmp6sock(int icmp6sock, int rdomain) 1590 { 1591 struct ra_iface *ra_iface; 1592 1593 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1594 if (!event_initialized(&ra_iface->icmp6ev->ev) && 1595 ra_iface->rdomain == rdomain) { 1596 event_set(&ra_iface->icmp6ev->ev, icmp6sock, EV_READ | 1597 EV_PERSIST, icmp6_receive, ra_iface->icmp6ev); 1598 event_add(&ra_iface->icmp6ev->ev, NULL); 1599 icmp6sock = -1; 1600 break; 1601 } 1602 } 1603 1604 if (icmp6sock != -1) { 1605 /* 1606 * The interface disappeared or changed rdomain while we were 1607 * waiting for the parent process to open the raw socket. 1608 */ 1609 close(icmp6sock); 1610 return; 1611 } 1612 1613 TAILQ_FOREACH (ra_iface, &ra_interfaces, entry) { 1614 if (ra_iface->rdomain == rdomain) { 1615 join_all_routers_mcast_group(ra_iface); 1616 frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 1617 &ra_iface->if_index, sizeof(ra_iface->if_index)); 1618 } 1619 } 1620 } 1621