bgpd.c revision 1.244
1/* $OpenBSD: bgpd.c,v 1.244 2022/06/05 12:43:13 claudio Exp $ */ 2 3/* 4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20#include <sys/socket.h> 21#include <sys/wait.h> 22#include <netinet/in.h> 23#include <arpa/inet.h> 24#include <err.h> 25#include <errno.h> 26#include <fcntl.h> 27#include <poll.h> 28#include <pwd.h> 29#include <signal.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33#include <syslog.h> 34#include <unistd.h> 35 36#include "bgpd.h" 37#include "session.h" 38#include "log.h" 39#include "version.h" 40 41void sighdlr(int); 42__dead void usage(void); 43int main(int, char *[]); 44pid_t start_child(enum bgpd_process, char *, int, int, int); 45int send_filterset(struct imsgbuf *, struct filter_set_head *); 46int reconfigure(char *, struct bgpd_config *); 47int send_config(struct bgpd_config *); 48int dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *); 49int control_setup(struct bgpd_config *); 50static void getsockpair(int [2]); 51int imsg_send_sockets(struct imsgbuf *, struct imsgbuf *, 52 struct imsgbuf *); 53void bgpd_rtr_connect(struct rtr_config *); 54void bgpd_rtr_connect_done(int, struct bgpd_config *); 55 56int cflags; 57volatile sig_atomic_t mrtdump; 58volatile sig_atomic_t quit; 59volatile sig_atomic_t reconfig; 60pid_t reconfpid; 61int reconfpending; 62struct imsgbuf *ibuf_se; 63struct imsgbuf *ibuf_rde; 64struct imsgbuf *ibuf_rtr; 65struct rib_names ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames); 66char *cname; 67char *rcname; 68 69struct connect_elm { 70 TAILQ_ENTRY(connect_elm) entry; 71 uint32_t id; 72 int fd; 73}; 74 75TAILQ_HEAD( ,connect_elm) connect_queue = \ 76 TAILQ_HEAD_INITIALIZER(connect_queue); 77u_int connect_cnt; 78#define MAX_CONNECT_CNT 32 79 80void 81sighdlr(int sig) 82{ 83 switch (sig) { 84 case SIGTERM: 85 case SIGINT: 86 quit = 1; 87 break; 88 case SIGHUP: 89 reconfig = 1; 90 break; 91 case SIGALRM: 92 case SIGUSR1: 93 mrtdump = 1; 94 break; 95 } 96} 97 98__dead void 99usage(void) 100{ 101 extern char *__progname; 102 103 fprintf(stderr, "usage: %s [-cdnvV] [-D macro=value] [-f file]\n", 104 __progname); 105 exit(1); 106} 107 108#define PFD_PIPE_SESSION 0 109#define PFD_PIPE_RDE 1 110#define PFD_PIPE_RTR 2 111#define PFD_SOCK_ROUTE 3 112#define PFD_SOCK_PFKEY 4 113#define PFD_CONNECT_START 5 114#define MAX_TIMEOUT 3600 115 116int cmd_opts; 117 118int 119main(int argc, char *argv[]) 120{ 121 struct bgpd_config *conf; 122 enum bgpd_process proc = PROC_MAIN; 123 struct rde_rib *rr; 124 struct peer *p; 125 struct pollfd *pfd = NULL; 126 struct connect_elm *ce; 127 time_t timeout; 128 pid_t se_pid = 0, rde_pid = 0, rtr_pid = 0, pid; 129 char *conffile; 130 char *saved_argv0; 131 u_int pfd_elms = 0, npfd, i; 132 int debug = 0; 133 int rfd, keyfd; 134 int ch, status; 135 int pipe_m2s[2]; 136 int pipe_m2r[2]; 137 int pipe_m2roa[2]; 138 139 conffile = CONFFILE; 140 141 log_init(1, LOG_DAEMON); /* log to stderr until daemonized */ 142 log_procinit(log_procnames[PROC_MAIN]); 143 log_setverbose(1); 144 145 saved_argv0 = argv[0]; 146 if (saved_argv0 == NULL) 147 saved_argv0 = "bgpd"; 148 149 while ((ch = getopt(argc, argv, "cdD:f:nRSTvV")) != -1) { 150 switch (ch) { 151 case 'c': 152 cmd_opts |= BGPD_OPT_FORCE_DEMOTE; 153 break; 154 case 'd': 155 debug = 1; 156 break; 157 case 'D': 158 if (cmdline_symset(optarg) < 0) 159 log_warnx("could not parse macro definition %s", 160 optarg); 161 break; 162 case 'f': 163 conffile = optarg; 164 break; 165 case 'n': 166 cmd_opts |= BGPD_OPT_NOACTION; 167 break; 168 case 'v': 169 if (cmd_opts & BGPD_OPT_VERBOSE) 170 cmd_opts |= BGPD_OPT_VERBOSE2; 171 cmd_opts |= BGPD_OPT_VERBOSE; 172 break; 173 case 'R': 174 proc = PROC_RDE; 175 break; 176 case 'S': 177 proc = PROC_SE; 178 break; 179 case 'T': 180 proc = PROC_RTR; 181 break; 182 case 'V': 183 fprintf(stderr, "OpenBGPD %s\n", BGPD_VERSION); 184 return 0; 185 default: 186 usage(); 187 /* NOTREACHED */ 188 } 189 } 190 191 argc -= optind; 192 argv += optind; 193 if (argc > 0) 194 usage(); 195 196 if (cmd_opts & BGPD_OPT_NOACTION) { 197 if ((conf = parse_config(conffile, NULL, NULL)) == NULL) 198 exit(1); 199 200 if (cmd_opts & BGPD_OPT_VERBOSE) 201 print_config(conf, &ribnames); 202 else 203 fprintf(stderr, "configuration OK\n"); 204 205 while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { 206 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 207 free(rr); 208 } 209 free_config(conf); 210 exit(0); 211 } 212 213 switch (proc) { 214 case PROC_MAIN: 215 break; 216 case PROC_RDE: 217 rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE); 218 /* NOTREACHED */ 219 case PROC_SE: 220 session_main(debug, cmd_opts & BGPD_OPT_VERBOSE); 221 /* NOTREACHED */ 222 case PROC_RTR: 223 rtr_main(debug, cmd_opts & BGPD_OPT_VERBOSE); 224 /* NOTREACHED */ 225 } 226 227 if (geteuid()) 228 errx(1, "need root privileges"); 229 230 if (getpwnam(BGPD_USER) == NULL) 231 errx(1, "unknown user %s", BGPD_USER); 232 233 if ((conf = parse_config(conffile, NULL, NULL)) == NULL) { 234 log_warnx("config file %s has errors", conffile); 235 exit(1); 236 } 237 238 if (prepare_listeners(conf) == -1) 239 exit(1); 240 241 log_init(debug, LOG_DAEMON); 242 log_setverbose(cmd_opts & BGPD_OPT_VERBOSE); 243 244 if (!debug) 245 daemon(1, 0); 246 247 log_info("startup"); 248 249 getsockpair(pipe_m2s); 250 getsockpair(pipe_m2r); 251 getsockpair(pipe_m2roa); 252 253 /* fork children */ 254 rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug, 255 cmd_opts & BGPD_OPT_VERBOSE); 256 se_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug, 257 cmd_opts & BGPD_OPT_VERBOSE); 258 rtr_pid = start_child(PROC_RTR, saved_argv0, pipe_m2roa[1], debug, 259 cmd_opts & BGPD_OPT_VERBOSE); 260 261 signal(SIGTERM, sighdlr); 262 signal(SIGINT, sighdlr); 263 signal(SIGHUP, sighdlr); 264 signal(SIGALRM, sighdlr); 265 signal(SIGUSR1, sighdlr); 266 signal(SIGPIPE, SIG_IGN); 267 268 if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL || 269 (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL || 270 (ibuf_rtr = malloc(sizeof(struct imsgbuf))) == NULL) 271 fatal(NULL); 272 imsg_init(ibuf_se, pipe_m2s[0]); 273 imsg_init(ibuf_rde, pipe_m2r[0]); 274 imsg_init(ibuf_rtr, pipe_m2roa[0]); 275 mrt_init(ibuf_rde, ibuf_se); 276 if (kr_init(&rfd, conf->fib_priority) == -1) 277 quit = 1; 278 keyfd = pfkey_init(); 279 280 /* 281 * rpath, read config file 282 * cpath, unlink control socket 283 * fattr, chmod on control socket 284 * wpath, needed if we are doing mrt dumps 285 * 286 * pledge placed here because kr_init() does a setsockopt on the 287 * routing socket thats not allowed at all. 288 */ 289#if 0 290 /* 291 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR 292 * this needs some redesign of bgpd to be fixed. 293 */ 294BROKEN if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd", 295 NULL) == -1) 296 fatal("pledge"); 297#endif 298 299 if (imsg_send_sockets(ibuf_se, ibuf_rde, ibuf_rtr)) 300 fatal("could not establish imsg links"); 301 /* control setup needs to happen late since it sends imsgs */ 302 if (control_setup(conf) == -1) 303 quit = 1; 304 if (send_config(conf) != 0) 305 quit = 1; 306 if (pftable_clear_all() != 0) 307 quit = 1; 308 309 while (quit == 0) { 310 if (pfd_elms < PFD_CONNECT_START + connect_cnt) { 311 struct pollfd *newp; 312 313 if ((newp = reallocarray(pfd, 314 PFD_CONNECT_START + connect_cnt, 315 sizeof(struct pollfd))) == NULL) { 316 log_warn("could not resize pfd from %u -> %u" 317 " entries", pfd_elms, PFD_CONNECT_START + 318 connect_cnt); 319 fatalx("exiting"); 320 } 321 pfd = newp; 322 pfd_elms = PFD_CONNECT_START + connect_cnt; 323 } 324 bzero(pfd, sizeof(struct pollfd) * pfd_elms); 325 326 timeout = mrt_timeout(conf->mrt); 327 328 pfd[PFD_SOCK_ROUTE].fd = rfd; 329 pfd[PFD_SOCK_ROUTE].events = POLLIN; 330 331 pfd[PFD_SOCK_PFKEY].fd = keyfd; 332 pfd[PFD_SOCK_PFKEY].events = POLLIN; 333 334 set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se); 335 set_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde); 336 set_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr); 337 338 npfd = PFD_CONNECT_START; 339 TAILQ_FOREACH(ce, &connect_queue, entry) { 340 pfd[npfd].fd = ce->fd; 341 pfd[npfd++].events = POLLOUT; 342 if (npfd > pfd_elms) 343 fatalx("polli pfd overflow"); 344 } 345 346 if (timeout < 0 || timeout > MAX_TIMEOUT) 347 timeout = MAX_TIMEOUT; 348 if (poll(pfd, npfd, timeout * 1000) == -1) { 349 if (errno != EINTR) { 350 log_warn("poll error"); 351 quit = 1; 352 } 353 goto next_loop; 354 } 355 356 if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) { 357 log_warnx("main: Lost connection to SE"); 358 msgbuf_clear(&ibuf_se->w); 359 free(ibuf_se); 360 ibuf_se = NULL; 361 quit = 1; 362 } else { 363 if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) == 364 -1) 365 quit = 1; 366 } 367 368 if (handle_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde) == -1) { 369 log_warnx("main: Lost connection to RDE"); 370 msgbuf_clear(&ibuf_rde->w); 371 free(ibuf_rde); 372 ibuf_rde = NULL; 373 quit = 1; 374 } else { 375 if (dispatch_imsg(ibuf_rde, PFD_PIPE_RDE, conf) == -1) 376 quit = 1; 377 } 378 379 if (handle_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr) == -1) { 380 log_warnx("main: Lost connection to RTR"); 381 msgbuf_clear(&ibuf_rtr->w); 382 free(ibuf_rtr); 383 ibuf_rtr = NULL; 384 quit = 1; 385 } else { 386 if (dispatch_imsg(ibuf_rtr, PFD_PIPE_RTR, conf) == -1) 387 quit = 1; 388 } 389 390 if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) { 391 if (kr_dispatch_msg(conf->default_tableid) == -1) 392 quit = 1; 393 } 394 395 if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) { 396 if (pfkey_read(keyfd, NULL) == -1) { 397 log_warnx("pfkey_read failed, exiting..."); 398 quit = 1; 399 } 400 } 401 402 for (i = PFD_CONNECT_START; i < npfd; i++) 403 if (pfd[i].revents != 0) 404 bgpd_rtr_connect_done(pfd[i].fd, conf); 405 406 next_loop: 407 if (reconfig) { 408 u_int error; 409 410 reconfig = 0; 411 switch (reconfigure(conffile, conf)) { 412 case -1: /* fatal error */ 413 quit = 1; 414 break; 415 case 0: /* all OK */ 416 error = 0; 417 break; 418 case 2: 419 log_info("previous reload still running"); 420 error = CTL_RES_PENDING; 421 break; 422 default: /* parse error */ 423 log_warnx("config file %s has errors, " 424 "not reloading", conffile); 425 error = CTL_RES_PARSE_ERROR; 426 break; 427 } 428 if (reconfpid != 0) { 429 send_imsg_session(IMSG_CTL_RESULT, reconfpid, 430 &error, sizeof(error)); 431 reconfpid = 0; 432 } 433 } 434 435 if (mrtdump) { 436 mrtdump = 0; 437 mrt_handler(conf->mrt); 438 } 439 } 440 441 /* close pipes */ 442 if (ibuf_se) { 443 msgbuf_clear(&ibuf_se->w); 444 close(ibuf_se->fd); 445 free(ibuf_se); 446 ibuf_se = NULL; 447 } 448 if (ibuf_rde) { 449 msgbuf_clear(&ibuf_rde->w); 450 close(ibuf_rde->fd); 451 free(ibuf_rde); 452 ibuf_rde = NULL; 453 } 454 if (ibuf_rtr) { 455 msgbuf_clear(&ibuf_rtr->w); 456 close(ibuf_rtr->fd); 457 free(ibuf_rtr); 458 ibuf_rtr = NULL; 459 } 460 461 /* cleanup kernel data structures */ 462 carp_demote_shutdown(); 463 kr_shutdown(conf->default_tableid); 464 pftable_clear_all(); 465 466 RB_FOREACH(p, peer_head, &conf->peers) 467 pfkey_remove(p); 468 469 while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { 470 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 471 free(rr); 472 } 473 free_config(conf); 474 475 log_debug("waiting for children to terminate"); 476 do { 477 pid = wait(&status); 478 if (pid == -1) { 479 if (errno != EINTR && errno != ECHILD) 480 fatal("wait"); 481 } else if (WIFSIGNALED(status)) { 482 char *name = "unknown process"; 483 if (pid == rde_pid) 484 name = "route decision engine"; 485 else if (pid == se_pid) 486 name = "session engine"; 487 else if (pid == rtr_pid) 488 name = "rtr engine"; 489 log_warnx("%s terminated; signal %d", name, 490 WTERMSIG(status)); 491 } 492 } while (pid != -1 || (pid == -1 && errno == EINTR)); 493 494 free(rcname); 495 free(cname); 496 497 log_info("terminating"); 498 return (0); 499} 500 501pid_t 502start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose) 503{ 504 char *argv[5]; 505 int argc = 0; 506 pid_t pid; 507 508 switch (pid = fork()) { 509 case -1: 510 fatal("cannot fork"); 511 case 0: 512 break; 513 default: 514 close(fd); 515 return (pid); 516 } 517 518 if (fd != 3) { 519 if (dup2(fd, 3) == -1) 520 fatal("cannot setup imsg fd"); 521 } else if (fcntl(fd, F_SETFD, 0) == -1) 522 fatal("cannot setup imsg fd"); 523 524 argv[argc++] = argv0; 525 switch (p) { 526 case PROC_MAIN: 527 fatalx("Can not start main process"); 528 case PROC_RDE: 529 argv[argc++] = "-R"; 530 break; 531 case PROC_SE: 532 argv[argc++] = "-S"; 533 break; 534 case PROC_RTR: 535 argv[argc++] = "-T"; 536 break; 537 } 538 if (debug) 539 argv[argc++] = "-d"; 540 if (verbose) 541 argv[argc++] = "-v"; 542 argv[argc++] = NULL; 543 544 execvp(argv0, argv); 545 fatal("execvp"); 546} 547 548int 549send_filterset(struct imsgbuf *i, struct filter_set_head *set) 550{ 551 struct filter_set *s; 552 553 TAILQ_FOREACH(s, set, entry) 554 if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s, 555 sizeof(struct filter_set)) == -1) 556 return (-1); 557 return (0); 558} 559 560int 561reconfigure(char *conffile, struct bgpd_config *conf) 562{ 563 struct bgpd_config *new_conf; 564 565 if (reconfpending) 566 return (2); 567 568 log_info("rereading config"); 569 if ((new_conf = parse_config(conffile, &conf->peers, 570 &conf->rtrs)) == NULL) 571 return (1); 572 573 merge_config(conf, new_conf); 574 575 if (prepare_listeners(conf) == -1) { 576 return (1); 577 } 578 579 if (control_setup(conf) == -1) { 580 return (1); 581 } 582 583 return send_config(conf); 584} 585 586int 587send_config(struct bgpd_config *conf) 588{ 589 struct peer *p; 590 struct filter_rule *r; 591 struct listen_addr *la; 592 struct rde_rib *rr; 593 struct l3vpn *vpn; 594 struct as_set *aset; 595 struct prefixset *ps; 596 struct prefixset_item *psi, *npsi; 597 struct roa *roa, *nroa; 598 struct rtr_config *rtr; 599 600 reconfpending = 3; /* one per child */ 601 602 expand_networks(conf); 603 604 cflags = conf->flags; 605 606 /* start reconfiguration */ 607 if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1, 608 conf, sizeof(*conf)) == -1) 609 return (-1); 610 if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1, 611 conf, sizeof(*conf)) == -1) 612 return (-1); 613 if (imsg_compose(ibuf_rtr, IMSG_RECONF_CONF, 0, 0, -1, 614 conf, sizeof(*conf)) == -1) 615 return (-1); 616 617 TAILQ_FOREACH(la, conf->listen_addrs, entry) { 618 if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd, 619 la, sizeof(*la)) == -1) 620 return (-1); 621 la->fd = -1; 622 } 623 624 /* adjust fib syncing on reload */ 625 ktable_preload(); 626 627 /* RIBs for the RDE */ 628 while ((rr = SIMPLEQ_FIRST(&ribnames))) { 629 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 630 if (ktable_update(rr->rtableid, rr->name, rr->flags) == -1) { 631 log_warnx("failed to load routing table %d", 632 rr->rtableid); 633 return (-1); 634 } 635 if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1, 636 rr, sizeof(*rr)) == -1) 637 return (-1); 638 free(rr); 639 } 640 641 /* send peer list to the SE */ 642 RB_FOREACH(p, peer_head, &conf->peers) { 643 if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1, 644 &p->conf, sizeof(p->conf)) == -1) 645 return (-1); 646 647 if (p->reconf_action == RECONF_REINIT) 648 if (pfkey_establish(p) == -1) 649 log_peer_warnx(&p->conf, "pfkey setup failed"); 650 } 651 652 /* networks go via kroute to the RDE */ 653 kr_net_reload(conf->default_tableid, 0, &conf->networks); 654 655 /* prefixsets for filters in the RDE */ 656 while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) { 657 SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry); 658 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET, 0, 0, -1, 659 ps->name, sizeof(ps->name)) == -1) 660 return (-1); 661 RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) { 662 RB_REMOVE(prefixset_tree, &ps->psitems, psi); 663 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM, 664 0, 0, -1, psi, sizeof(*psi)) == -1) 665 return (-1); 666 free(psi); 667 } 668 free(ps); 669 } 670 671 /* originsets for filters in the RDE */ 672 while ((ps = SIMPLEQ_FIRST(&conf->originsets)) != NULL) { 673 SIMPLEQ_REMOVE_HEAD(&conf->originsets, entry); 674 if (imsg_compose(ibuf_rde, IMSG_RECONF_ORIGIN_SET, 0, 0, -1, 675 ps->name, sizeof(ps->name)) == -1) 676 return (-1); 677 RB_FOREACH_SAFE(roa, roa_tree, &ps->roaitems, nroa) { 678 RB_REMOVE(roa_tree, &ps->roaitems, roa); 679 if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_ITEM, 0, 0, 680 -1, roa, sizeof(*roa)) == -1) 681 return (-1); 682 free(roa); 683 } 684 free(ps); 685 } 686 687 /* roa table and rtr config are sent to the RTR engine */ 688 RB_FOREACH_SAFE(roa, roa_tree, &conf->roa, nroa) { 689 RB_REMOVE(roa_tree, &conf->roa, roa); 690 if (imsg_compose(ibuf_rtr, IMSG_RECONF_ROA_ITEM, 0, 0, 691 -1, roa, sizeof(*roa)) == -1) 692 return (-1); 693 free(roa); 694 } 695 SIMPLEQ_FOREACH(rtr, &conf->rtrs, entry) { 696 if (imsg_compose(ibuf_rtr, IMSG_RECONF_RTR_CONFIG, rtr->id, 697 0, -1, rtr->descr, sizeof(rtr->descr)) == -1) 698 return (-1); 699 } 700 701 /* as-sets for filters in the RDE */ 702 while ((aset = SIMPLEQ_FIRST(&conf->as_sets)) != NULL) { 703 struct ibuf *wbuf; 704 uint32_t *as; 705 size_t i, l, n; 706 707 SIMPLEQ_REMOVE_HEAD(&conf->as_sets, entry); 708 709 as = set_get(aset->set, &n); 710 if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0, 711 sizeof(n) + sizeof(aset->name))) == NULL) 712 return -1; 713 if (imsg_add(wbuf, &n, sizeof(n)) == -1 || 714 imsg_add(wbuf, aset->name, sizeof(aset->name)) == -1) 715 return -1; 716 imsg_close(ibuf_rde, wbuf); 717 718 for (i = 0; i < n; i += l) { 719 l = (n - i > 1024 ? 1024 : n - i); 720 if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_ITEMS, 721 0, 0, -1, as + i, l * sizeof(*as)) == -1) 722 return -1; 723 } 724 725 if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_DONE, 0, 0, -1, 726 NULL, 0) == -1) 727 return -1; 728 729 set_free(aset->set); 730 free(aset); 731 } 732 733 /* filters for the RDE */ 734 while ((r = TAILQ_FIRST(conf->filters)) != NULL) { 735 TAILQ_REMOVE(conf->filters, r, entry); 736 if (send_filterset(ibuf_rde, &r->set) == -1) 737 return (-1); 738 if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1, 739 r, sizeof(struct filter_rule)) == -1) 740 return (-1); 741 filterset_free(&r->set); 742 free(r); 743 } 744 745 while ((vpn = SIMPLEQ_FIRST(&conf->l3vpns)) != NULL) { 746 SIMPLEQ_REMOVE_HEAD(&conf->l3vpns, entry); 747 if (ktable_update(vpn->rtableid, vpn->descr, vpn->flags) == 748 -1) { 749 log_warnx("failed to load routing table %d", 750 vpn->rtableid); 751 return (-1); 752 } 753 /* networks go via kroute to the RDE */ 754 kr_net_reload(vpn->rtableid, vpn->rd, &vpn->net_l); 755 756 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN, 0, 0, -1, 757 vpn, sizeof(*vpn)) == -1) 758 return (-1); 759 760 /* export targets */ 761 if (send_filterset(ibuf_rde, &vpn->export) == -1) 762 return (-1); 763 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_EXPORT, 0, 0, 764 -1, NULL, 0) == -1) 765 return (-1); 766 filterset_free(&vpn->export); 767 768 /* import targets */ 769 if (send_filterset(ibuf_rde, &vpn->import) == -1) 770 return (-1); 771 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_IMPORT, 0, 0, 772 -1, NULL, 0) == -1) 773 return (-1); 774 filterset_free(&vpn->import); 775 776 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_DONE, 0, 0, 777 -1, NULL, 0) == -1) 778 return (-1); 779 780 free(vpn); 781 } 782 783 /* send a drain message to know when all messages where processed */ 784 if (imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1) 785 return (-1); 786 if (imsg_compose(ibuf_rde, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1) 787 return (-1); 788 if (imsg_compose(ibuf_rtr, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1) 789 return (-1); 790 791 /* mrt changes can be sent out of bound */ 792 mrt_reconfigure(conf->mrt); 793 return (0); 794} 795 796int 797dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf) 798{ 799 struct imsg imsg; 800 struct peer *p; 801 struct rtr_config *r; 802 ssize_t n; 803 int rv, verbose; 804 805 rv = 0; 806 while (ibuf) { 807 if ((n = imsg_get(ibuf, &imsg)) == -1) 808 return (-1); 809 810 if (n == 0) 811 break; 812 813 switch (imsg.hdr.type) { 814 case IMSG_KROUTE_CHANGE: 815 if (idx != PFD_PIPE_RDE) 816 log_warnx("route request not from RDE"); 817 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 818 sizeof(struct kroute_full)) 819 log_warnx("wrong imsg len"); 820 else if (kr_change(imsg.hdr.peerid, imsg.data)) 821 rv = -1; 822 break; 823 case IMSG_KROUTE_DELETE: 824 if (idx != PFD_PIPE_RDE) 825 log_warnx("route request not from RDE"); 826 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 827 sizeof(struct kroute_full)) 828 log_warnx("wrong imsg len"); 829 else if (kr_delete(imsg.hdr.peerid, imsg.data)) 830 rv = -1; 831 break; 832 case IMSG_KROUTE_FLUSH: 833 if (idx != PFD_PIPE_RDE) 834 log_warnx("route request not from RDE"); 835 else if (imsg.hdr.len != IMSG_HEADER_SIZE) 836 log_warnx("wrong imsg len"); 837 else if (kr_flush(imsg.hdr.peerid)) 838 rv = -1; 839 break; 840 case IMSG_NEXTHOP_ADD: 841 if (idx != PFD_PIPE_RDE) 842 log_warnx("nexthop request not from RDE"); 843 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 844 sizeof(struct bgpd_addr)) 845 log_warnx("wrong imsg len"); 846 else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data, 847 conf) == -1) 848 rv = -1; 849 break; 850 case IMSG_NEXTHOP_REMOVE: 851 if (idx != PFD_PIPE_RDE) 852 log_warnx("nexthop request not from RDE"); 853 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 854 sizeof(struct bgpd_addr)) 855 log_warnx("wrong imsg len"); 856 else 857 kr_nexthop_delete(imsg.hdr.peerid, imsg.data, 858 conf); 859 break; 860 case IMSG_PFTABLE_ADD: 861 if (idx != PFD_PIPE_RDE) 862 log_warnx("pftable request not from RDE"); 863 else 864 if (imsg.hdr.len != IMSG_HEADER_SIZE + 865 sizeof(struct pftable_msg)) 866 log_warnx("wrong imsg len"); 867 else if (pftable_addr_add(imsg.data) != 0) 868 rv = -1; 869 break; 870 case IMSG_PFTABLE_REMOVE: 871 if (idx != PFD_PIPE_RDE) 872 log_warnx("pftable request not from RDE"); 873 else 874 if (imsg.hdr.len != IMSG_HEADER_SIZE + 875 sizeof(struct pftable_msg)) 876 log_warnx("wrong imsg len"); 877 else if (pftable_addr_remove(imsg.data) != 0) 878 rv = -1; 879 break; 880 case IMSG_PFTABLE_COMMIT: 881 if (idx != PFD_PIPE_RDE) 882 log_warnx("pftable request not from RDE"); 883 else if (imsg.hdr.len != IMSG_HEADER_SIZE) 884 log_warnx("wrong imsg len"); 885 else if (pftable_commit() != 0) 886 rv = -1; 887 break; 888 case IMSG_PFKEY_RELOAD: 889 if (idx != PFD_PIPE_SESSION) { 890 log_warnx("pfkey reload request not from SE"); 891 break; 892 } 893 p = getpeerbyid(conf, imsg.hdr.peerid); 894 if (p != NULL) { 895 if (pfkey_establish(p) == -1) 896 log_peer_warnx(&p->conf, 897 "pfkey setup failed"); 898 } 899 break; 900 case IMSG_CTL_RELOAD: 901 if (idx != PFD_PIPE_SESSION) 902 log_warnx("reload request not from SE"); 903 else { 904 reconfig = 1; 905 reconfpid = imsg.hdr.pid; 906 if (imsg.hdr.len == IMSG_HEADER_SIZE + 907 REASON_LEN && ((char *)imsg.data)[0]) 908 log_info("reload due to: %s", 909 log_reason(imsg.data)); 910 } 911 break; 912 case IMSG_CTL_FIB_COUPLE: 913 if (idx != PFD_PIPE_SESSION) 914 log_warnx("couple request not from SE"); 915 else 916 kr_fib_couple(imsg.hdr.peerid); 917 break; 918 case IMSG_CTL_FIB_DECOUPLE: 919 if (idx != PFD_PIPE_SESSION) 920 log_warnx("decouple request not from SE"); 921 else 922 kr_fib_decouple(imsg.hdr.peerid); 923 break; 924 case IMSG_CTL_KROUTE: 925 case IMSG_CTL_KROUTE_ADDR: 926 case IMSG_CTL_SHOW_NEXTHOP: 927 case IMSG_CTL_SHOW_INTERFACE: 928 case IMSG_CTL_SHOW_FIB_TABLES: 929 if (idx != PFD_PIPE_SESSION) 930 log_warnx("kroute request not from SE"); 931 else 932 kr_show_route(&imsg); 933 break; 934 case IMSG_IFINFO: 935 if (idx != PFD_PIPE_SESSION) 936 log_warnx("IFINFO request not from SE"); 937 else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ) 938 log_warnx("IFINFO request with wrong len"); 939 else 940 kr_ifinfo(imsg.data); 941 break; 942 case IMSG_DEMOTE: 943 if (idx != PFD_PIPE_SESSION) 944 log_warnx("demote request not from SE"); 945 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 946 sizeof(struct demote_msg)) 947 log_warnx("DEMOTE request with wrong len"); 948 else { 949 struct demote_msg *msg; 950 951 msg = imsg.data; 952 carp_demote_set(msg->demote_group, msg->level); 953 } 954 break; 955 case IMSG_CTL_LOG_VERBOSE: 956 /* already checked by SE */ 957 memcpy(&verbose, imsg.data, sizeof(verbose)); 958 log_setverbose(verbose); 959 break; 960 case IMSG_RECONF_DONE: 961 if (reconfpending == 0) { 962 log_warnx("unexpected RECONF_DONE received"); 963 break; 964 } 965 if (idx == PFD_PIPE_SESSION) { 966 imsg_compose(ibuf_rtr, IMSG_RECONF_DONE, 0, 967 0, -1, NULL, 0); 968 } else if (idx == PFD_PIPE_RTR) { 969 imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 970 0, -1, NULL, 0); 971 972 /* finally fix kroute information */ 973 ktable_postload(); 974 975 /* redistribute list needs to be reloaded too */ 976 kr_reload(); 977 } 978 reconfpending--; 979 break; 980 case IMSG_RECONF_DRAIN: 981 if (reconfpending == 0) { 982 log_warnx("unexpected RECONF_DRAIN received"); 983 break; 984 } 985 reconfpending--; 986 if (reconfpending == 0) { 987 /* 988 * SE goes first to bring templated neighbors 989 * in sync. 990 */ 991 imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 992 0, -1, NULL, 0); 993 reconfpending = 3; /* expecting 2 DONE msg */ 994 } 995 break; 996 case IMSG_SOCKET_CONN: 997 if (idx != PFD_PIPE_RTR) { 998 log_warnx("connect request not from RTR"); 999 } else { 1000 SIMPLEQ_FOREACH(r, &conf->rtrs, entry) { 1001 if (imsg.hdr.peerid == r->id) 1002 break; 1003 } 1004 if (r == NULL) 1005 log_warnx("unknown rtr id %d", 1006 imsg.hdr.peerid); 1007 else 1008 bgpd_rtr_connect(r); 1009 } 1010 break; 1011 case IMSG_CTL_SHOW_RTR: 1012 if (idx == PFD_PIPE_SESSION) { 1013 SIMPLEQ_FOREACH(r, &conf->rtrs, entry) { 1014 imsg_compose(ibuf_rtr, imsg.hdr.type, 1015 r->id, imsg.hdr.pid, -1, NULL, 0); 1016 } 1017 imsg_compose(ibuf_rtr, IMSG_CTL_END, 1018 0, imsg.hdr.pid, -1, NULL, 0); 1019 } else if (imsg.hdr.len != IMSG_HEADER_SIZE + 1020 sizeof(struct ctl_show_rtr)) { 1021 log_warnx("IMSG_CTL_SHOW_RTR with wrong len"); 1022 } else if (idx == PFD_PIPE_RTR) { 1023 SIMPLEQ_FOREACH(r, &conf->rtrs, entry) { 1024 if (imsg.hdr.peerid == r->id) 1025 break; 1026 } 1027 if (r != NULL) { 1028 struct ctl_show_rtr *msg; 1029 msg = imsg.data; 1030 strlcpy(msg->descr, r->descr, 1031 sizeof(msg->descr)); 1032 msg->local_addr = r->local_addr; 1033 msg->remote_addr = r->remote_addr; 1034 msg->remote_port = r->remote_port; 1035 1036 imsg_compose(ibuf_se, imsg.hdr.type, 1037 imsg.hdr.peerid, imsg.hdr.pid, 1038 -1, imsg.data, 1039 imsg.hdr.len - IMSG_HEADER_SIZE); 1040 } 1041 } 1042 break; 1043 case IMSG_CTL_END: 1044 case IMSG_CTL_SHOW_TIMER: 1045 if (idx != PFD_PIPE_RTR) { 1046 log_warnx("connect request not from RTR"); 1047 break; 1048 } 1049 imsg_compose(ibuf_se, imsg.hdr.type, imsg.hdr.peerid, 1050 imsg.hdr.pid, -1, imsg.data, 1051 imsg.hdr.len - IMSG_HEADER_SIZE); 1052 break; 1053 default: 1054 break; 1055 } 1056 imsg_free(&imsg); 1057 if (rv != 0) 1058 return (rv); 1059 } 1060 return (0); 1061} 1062 1063void 1064send_nexthop_update(struct kroute_nexthop *msg) 1065{ 1066 char *gw = NULL; 1067 1068 if (msg->gateway.aid) 1069 if (asprintf(&gw, ": via %s", 1070 log_addr(&msg->gateway)) == -1) { 1071 log_warn("send_nexthop_update"); 1072 quit = 1; 1073 } 1074 1075 log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop), 1076 msg->valid ? "valid" : "invalid", 1077 msg->connected ? ": directly connected" : "", 1078 msg->gateway.aid ? gw : ""); 1079 1080 free(gw); 1081 1082 if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1, 1083 msg, sizeof(struct kroute_nexthop)) == -1) 1084 quit = 1; 1085} 1086 1087void 1088send_imsg_session(int type, pid_t pid, void *data, uint16_t datalen) 1089{ 1090 imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen); 1091} 1092 1093int 1094send_network(int type, struct network_config *net, struct filter_set_head *h) 1095{ 1096 if (quit) 1097 return (0); 1098 if (imsg_compose(ibuf_rde, type, 0, 0, -1, net, 1099 sizeof(struct network_config)) == -1) 1100 return (-1); 1101 /* networks that get deleted don't need to send the filter set */ 1102 if (type == IMSG_NETWORK_REMOVE) 1103 return (0); 1104 if (send_filterset(ibuf_rde, h) == -1) 1105 return (-1); 1106 if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1) 1107 return (-1); 1108 1109 return (0); 1110} 1111 1112int 1113bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6) 1114{ 1115 /* kernel routes are never filtered */ 1116 if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0) 1117 return (0); 1118 if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0) 1119 return (0); 1120 1121 if (cflags & BGPD_FLAG_NEXTHOP_BGP) { 1122 if (kr && kr->flags & F_BGPD_INSERTED) 1123 return (0); 1124 if (kr6 && kr6->flags & F_BGPD_INSERTED) 1125 return (0); 1126 } 1127 1128 if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) { 1129 if (kr && kr->prefixlen == 0) 1130 return (0); 1131 if (kr6 && kr6->prefixlen == 0) 1132 return (0); 1133 } 1134 1135 return (1); 1136} 1137 1138int 1139control_setup(struct bgpd_config *conf) 1140{ 1141 int fd, restricted; 1142 1143 /* control socket is outside chroot */ 1144 if (!cname || strcmp(cname, conf->csock)) { 1145 if (cname) { 1146 free(cname); 1147 } 1148 if ((cname = strdup(conf->csock)) == NULL) 1149 fatal("strdup"); 1150 if (control_check(cname) == -1) 1151 return (-1); 1152 if ((fd = control_init(0, cname)) == -1) 1153 fatalx("control socket setup failed"); 1154 if (control_listen(fd) == -1) 1155 fatalx("control socket setup failed"); 1156 restricted = 0; 1157 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 1158 &restricted, sizeof(restricted)) == -1) 1159 return (-1); 1160 } 1161 if (!conf->rcsock) { 1162 /* remove restricted socket */ 1163 free(rcname); 1164 rcname = NULL; 1165 } else if (!rcname || strcmp(rcname, conf->rcsock)) { 1166 if (rcname) { 1167 free(rcname); 1168 } 1169 if ((rcname = strdup(conf->rcsock)) == NULL) 1170 fatal("strdup"); 1171 if (control_check(rcname) == -1) 1172 return (-1); 1173 if ((fd = control_init(1, rcname)) == -1) 1174 fatalx("control socket setup failed"); 1175 if (control_listen(fd) == -1) 1176 fatalx("control socket setup failed"); 1177 restricted = 1; 1178 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 1179 &restricted, sizeof(restricted)) == -1) 1180 return (-1); 1181 } 1182 return (0); 1183} 1184 1185void 1186set_pollfd(struct pollfd *pfd, struct imsgbuf *i) 1187{ 1188 if (i == NULL || i->fd == -1) { 1189 pfd->fd = -1; 1190 return; 1191 } 1192 pfd->fd = i->fd; 1193 pfd->events = POLLIN; 1194 if (i->w.queued > 0) 1195 pfd->events |= POLLOUT; 1196} 1197 1198int 1199handle_pollfd(struct pollfd *pfd, struct imsgbuf *i) 1200{ 1201 ssize_t n; 1202 1203 if (i == NULL) 1204 return (0); 1205 1206 if (pfd->revents & POLLOUT) 1207 if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) { 1208 log_warn("imsg write error"); 1209 close(i->fd); 1210 i->fd = -1; 1211 return (-1); 1212 } 1213 1214 if (pfd->revents & POLLIN) { 1215 if ((n = imsg_read(i)) == -1 && errno != EAGAIN) { 1216 log_warn("imsg read error"); 1217 close(i->fd); 1218 i->fd = -1; 1219 return (-1); 1220 } 1221 if (n == 0) { 1222 log_warnx("peer closed imsg connection"); 1223 close(i->fd); 1224 i->fd = -1; 1225 return (-1); 1226 } 1227 } 1228 return (0); 1229} 1230 1231static void 1232getsockpair(int pipe[2]) 1233{ 1234 int bsize, i; 1235 1236 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 1237 PF_UNSPEC, pipe) == -1) 1238 fatal("socketpair"); 1239 1240 for (i = 0; i < 2; i++) { 1241 for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) { 1242 if (setsockopt(pipe[i], SOL_SOCKET, SO_RCVBUF, 1243 &bsize, sizeof(bsize)) == -1) { 1244 if (errno != ENOBUFS) 1245 fatal("setsockopt(SO_RCVBUF, %d)", 1246 bsize); 1247 log_warn("setsockopt(SO_RCVBUF, %d)", bsize); 1248 continue; 1249 } 1250 break; 1251 } 1252 } 1253 for (i = 0; i < 2; i++) { 1254 for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) { 1255 if (setsockopt(pipe[i], SOL_SOCKET, SO_SNDBUF, 1256 &bsize, sizeof(bsize)) == -1) { 1257 if (errno != ENOBUFS) 1258 fatal("setsockopt(SO_SNDBUF, %d)", 1259 bsize); 1260 log_warn("setsockopt(SO_SNDBUF, %d)", bsize); 1261 continue; 1262 } 1263 break; 1264 } 1265 } 1266} 1267 1268int 1269imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde, struct imsgbuf *roa) 1270{ 1271 int pipe_s2r[2]; 1272 int pipe_s2r_ctl[2]; 1273 int pipe_r2r[2]; 1274 1275 getsockpair(pipe_s2r); 1276 getsockpair(pipe_s2r_ctl); 1277 getsockpair(pipe_r2r); 1278 1279 if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0], 1280 NULL, 0) == -1) 1281 return (-1); 1282 if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1], 1283 NULL, 0) == -1) 1284 return (-1); 1285 1286 if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0], 1287 NULL, 0) == -1) 1288 return (-1); 1289 if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1], 1290 NULL, 0) == -1) 1291 return (-1); 1292 1293 if (imsg_compose(roa, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[0], 1294 NULL, 0) == -1) 1295 return (-1); 1296 if (imsg_compose(rde, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[1], 1297 NULL, 0) == -1) 1298 return (-1); 1299 1300 return (0); 1301} 1302 1303void 1304bgpd_rtr_connect(struct rtr_config *r) 1305{ 1306 struct connect_elm *ce; 1307 struct sockaddr *sa; 1308 socklen_t len; 1309 1310 if (connect_cnt >= MAX_CONNECT_CNT) { 1311 log_warnx("rtr %s: too many concurrent connection requests", 1312 r->descr); 1313 return; 1314 } 1315 1316 if ((ce = calloc(1, sizeof(*ce))) == NULL) { 1317 log_warn("rtr %s", r->descr); 1318 return; 1319 } 1320 1321 ce->id = r->id; 1322 ce->fd = socket(aid2af(r->remote_addr.aid), 1323 SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_TCP); 1324 if (ce->fd == -1) { 1325 log_warn("rtr %s", r->descr); 1326 free(ce); 1327 return; 1328 } 1329 1330 if ((sa = addr2sa(&r->local_addr, 0, &len)) != NULL) { 1331 if (bind(ce->fd, sa, len) == -1) { 1332 log_warn("rtr %s: bind to %s", r->descr, 1333 log_addr(&r->local_addr)); 1334 close(ce->fd); 1335 free(ce); 1336 return; 1337 } 1338 } 1339 1340 sa = addr2sa(&r->remote_addr, r->remote_port, &len); 1341 if (connect(ce->fd, sa, len) == -1) { 1342 if (errno != EINPROGRESS) { 1343 log_warn("rtr %s: connect to %s:%u", r->descr, 1344 log_addr(&r->remote_addr), r->remote_port); 1345 close(ce->fd); 1346 free(ce); 1347 return; 1348 } 1349 TAILQ_INSERT_TAIL(&connect_queue, ce, entry); 1350 connect_cnt++; 1351 return; 1352 } 1353 1354 imsg_compose(ibuf_rtr, IMSG_SOCKET_CONN, ce->id, 0, ce->fd, NULL, 0); 1355 free(ce); 1356} 1357 1358void 1359bgpd_rtr_connect_done(int fd, struct bgpd_config *conf) 1360{ 1361 struct rtr_config *r; 1362 struct connect_elm *ce; 1363 int error = 0; 1364 socklen_t len; 1365 1366 TAILQ_FOREACH(ce, &connect_queue, entry) { 1367 if (ce->fd == fd) 1368 break; 1369 } 1370 if (ce == NULL) 1371 fatalx("connect entry not found"); 1372 1373 TAILQ_REMOVE(&connect_queue, ce, entry); 1374 connect_cnt--; 1375 1376 SIMPLEQ_FOREACH(r, &conf->rtrs, entry) { 1377 if (ce->id == r->id) 1378 break; 1379 } 1380 if (r == NULL) { 1381 log_warnx("rtr id %d no longer exists", ce->id); 1382 goto fail; 1383 } 1384 1385 len = sizeof(error); 1386 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) { 1387 log_warn("rtr %s: getsockopt SO_ERROR", r->descr); 1388 goto fail; 1389 } 1390 1391 if (error != 0) { 1392 errno = error; 1393 log_warn("rtr %s: connect to %s:%u", r->descr, 1394 log_addr(&r->remote_addr), r->remote_port); 1395 goto fail; 1396 } 1397 1398 imsg_compose(ibuf_rtr, IMSG_SOCKET_CONN, ce->id, 0, ce->fd, NULL, 0); 1399 free(ce); 1400 return; 1401 1402fail: 1403 close(fd); 1404 free(ce); 1405} 1406