bgpd.c revision 1.224
1/* $OpenBSD: bgpd.c,v 1.224 2019/08/05 08:46:55 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 40void sighdlr(int); 41__dead void usage(void); 42int main(int, char *[]); 43pid_t start_child(enum bgpd_process, char *, int, int, int); 44int send_filterset(struct imsgbuf *, struct filter_set_head *); 45int reconfigure(char *, struct bgpd_config *); 46int dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *); 47int control_setup(struct bgpd_config *); 48static void getsockpair(int [2]); 49int imsg_send_sockets(struct imsgbuf *, struct imsgbuf *); 50 51int cflags; 52volatile sig_atomic_t mrtdump; 53volatile sig_atomic_t quit; 54volatile sig_atomic_t reconfig; 55pid_t reconfpid; 56int reconfpending; 57struct imsgbuf *ibuf_se; 58struct imsgbuf *ibuf_rde; 59struct rib_names ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames); 60char *cname; 61char *rcname; 62 63void 64sighdlr(int sig) 65{ 66 switch (sig) { 67 case SIGTERM: 68 case SIGINT: 69 quit = 1; 70 break; 71 case SIGHUP: 72 reconfig = 1; 73 break; 74 case SIGALRM: 75 case SIGUSR1: 76 mrtdump = 1; 77 break; 78 } 79} 80 81__dead void 82usage(void) 83{ 84 extern char *__progname; 85 86 fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n", 87 __progname); 88 exit(1); 89} 90 91#define PFD_PIPE_SESSION 0 92#define PFD_PIPE_ROUTE 1 93#define PFD_SOCK_ROUTE 2 94#define PFD_SOCK_PFKEY 3 95#define POLL_MAX 4 96#define MAX_TIMEOUT 3600 97 98int cmd_opts; 99 100int 101main(int argc, char *argv[]) 102{ 103 struct bgpd_config *conf; 104 struct rde_rib *rr; 105 struct peer *p; 106 struct pollfd pfd[POLL_MAX]; 107 time_t timeout; 108 pid_t se_pid = 0, rde_pid = 0, pid; 109 char *conffile; 110 char *saved_argv0; 111 int debug = 0; 112 int rflag = 0, sflag = 0; 113 int rfd, keyfd; 114 int ch, status; 115 int pipe_m2s[2]; 116 int pipe_m2r[2]; 117 118 conffile = CONFFILE; 119 bgpd_process = PROC_MAIN; 120 121 log_init(1, LOG_DAEMON); /* log to stderr until daemonized */ 122 log_procinit(log_procnames[bgpd_process]); 123 log_setverbose(1); 124 125 saved_argv0 = argv[0]; 126 if (saved_argv0 == NULL) 127 saved_argv0 = "bgpd"; 128 129 while ((ch = getopt(argc, argv, "cdD:f:nRSv")) != -1) { 130 switch (ch) { 131 case 'c': 132 cmd_opts |= BGPD_OPT_FORCE_DEMOTE; 133 break; 134 case 'd': 135 debug = 1; 136 break; 137 case 'D': 138 if (cmdline_symset(optarg) < 0) 139 log_warnx("could not parse macro definition %s", 140 optarg); 141 break; 142 case 'f': 143 conffile = optarg; 144 break; 145 case 'n': 146 cmd_opts |= BGPD_OPT_NOACTION; 147 break; 148 case 'v': 149 if (cmd_opts & BGPD_OPT_VERBOSE) 150 cmd_opts |= BGPD_OPT_VERBOSE2; 151 cmd_opts |= BGPD_OPT_VERBOSE; 152 break; 153 case 'R': 154 rflag = 1; 155 break; 156 case 'S': 157 sflag = 1; 158 break; 159 default: 160 usage(); 161 /* NOTREACHED */ 162 } 163 } 164 165 argc -= optind; 166 argv += optind; 167 if (argc > 0 || (sflag && rflag)) 168 usage(); 169 170 if (cmd_opts & BGPD_OPT_NOACTION) { 171 if ((conf = parse_config(conffile, NULL)) == NULL) 172 exit(1); 173 174 if (cmd_opts & BGPD_OPT_VERBOSE) 175 print_config(conf, &ribnames); 176 else 177 fprintf(stderr, "configuration OK\n"); 178 179 while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { 180 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 181 free(rr); 182 } 183 free_config(conf); 184 exit(0); 185 } 186 187 if (rflag) 188 rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE); 189 else if (sflag) 190 session_main(debug, cmd_opts & BGPD_OPT_VERBOSE); 191 192 if (geteuid()) 193 errx(1, "need root privileges"); 194 195 if (getpwnam(BGPD_USER) == NULL) 196 errx(1, "unknown user %s", BGPD_USER); 197 198 log_init(debug, LOG_DAEMON); 199 log_setverbose(cmd_opts & BGPD_OPT_VERBOSE); 200 201 if (!debug) 202 daemon(1, 0); 203 204 log_info("startup"); 205 206 getsockpair(pipe_m2s); 207 getsockpair(pipe_m2r); 208 209 /* fork children */ 210 rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug, 211 cmd_opts & BGPD_OPT_VERBOSE); 212 se_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug, 213 cmd_opts & BGPD_OPT_VERBOSE); 214 215 signal(SIGTERM, sighdlr); 216 signal(SIGINT, sighdlr); 217 signal(SIGHUP, sighdlr); 218 signal(SIGALRM, sighdlr); 219 signal(SIGUSR1, sighdlr); 220 signal(SIGPIPE, SIG_IGN); 221 222 if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL || 223 (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL) 224 fatal(NULL); 225 imsg_init(ibuf_se, pipe_m2s[0]); 226 imsg_init(ibuf_rde, pipe_m2r[0]); 227 mrt_init(ibuf_rde, ibuf_se); 228 if ((rfd = kr_init()) == -1) 229 quit = 1; 230 keyfd = pfkey_init(); 231 232 /* 233 * rpath, read config file 234 * cpath, unlink control socket 235 * fattr, chmod on control socket 236 * wpath, needed if we are doing mrt dumps 237 * 238 * pledge placed here because kr_init() does a setsockopt on the 239 * routing socket thats not allowed at all. 240 */ 241#if 0 242 /* 243 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR 244 * this needs some redesign of bgpd to be fixed. 245 */ 246BROKEN if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd", 247 NULL) == -1) 248 fatal("pledge"); 249#endif 250 251 if (imsg_send_sockets(ibuf_se, ibuf_rde)) 252 fatal("could not establish imsg links"); 253 conf = new_config(); 254 quit = reconfigure(conffile, conf); 255 if (pftable_clear_all() != 0) 256 quit = 1; 257 258 while (quit == 0) { 259 bzero(pfd, sizeof(pfd)); 260 261 timeout = mrt_timeout(conf->mrt); 262 263 pfd[PFD_SOCK_ROUTE].fd = rfd; 264 pfd[PFD_SOCK_ROUTE].events = POLLIN; 265 266 pfd[PFD_SOCK_PFKEY].fd = keyfd; 267 pfd[PFD_SOCK_PFKEY].events = POLLIN; 268 269 set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se); 270 set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde); 271 272 if (timeout < 0 || timeout > MAX_TIMEOUT) 273 timeout = MAX_TIMEOUT; 274 if (poll(pfd, POLL_MAX, timeout * 1000) == -1) 275 if (errno != EINTR) { 276 log_warn("poll error"); 277 quit = 1; 278 } 279 280 if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) { 281 log_warnx("main: Lost connection to SE"); 282 msgbuf_clear(&ibuf_se->w); 283 free(ibuf_se); 284 ibuf_se = NULL; 285 quit = 1; 286 } else { 287 if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) == 288 -1) 289 quit = 1; 290 } 291 292 if (handle_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde) == -1) { 293 log_warnx("main: Lost connection to RDE"); 294 msgbuf_clear(&ibuf_rde->w); 295 free(ibuf_rde); 296 ibuf_rde = NULL; 297 quit = 1; 298 } else { 299 if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, conf) == 300 -1) 301 quit = 1; 302 } 303 304 if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) { 305 if (kr_dispatch_msg(conf->default_tableid) == -1) 306 quit = 1; 307 } 308 309 if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) { 310 if (pfkey_read(keyfd, NULL) == -1) { 311 log_warnx("pfkey_read failed, exiting..."); 312 quit = 1; 313 } 314 } 315 316 if (reconfig) { 317 u_int error; 318 319 reconfig = 0; 320 switch (reconfigure(conffile, conf)) { 321 case -1: /* fatal error */ 322 quit = 1; 323 break; 324 case 0: /* all OK */ 325 error = 0; 326 break; 327 case 2: 328 error = CTL_RES_PENDING; 329 break; 330 default: /* parse error */ 331 error = CTL_RES_PARSE_ERROR; 332 break; 333 } 334 if (reconfpid != 0) { 335 send_imsg_session(IMSG_CTL_RESULT, reconfpid, 336 &error, sizeof(error)); 337 reconfpid = 0; 338 } 339 } 340 341 if (mrtdump) { 342 mrtdump = 0; 343 mrt_handler(conf->mrt); 344 } 345 } 346 347 /* close pipes */ 348 if (ibuf_se) { 349 msgbuf_clear(&ibuf_se->w); 350 close(ibuf_se->fd); 351 free(ibuf_se); 352 ibuf_se = NULL; 353 } 354 if (ibuf_rde) { 355 msgbuf_clear(&ibuf_rde->w); 356 close(ibuf_rde->fd); 357 free(ibuf_rde); 358 ibuf_rde = NULL; 359 } 360 361 /* cleanup kernel data structures */ 362 carp_demote_shutdown(); 363 kr_shutdown(conf->fib_priority, conf->default_tableid); 364 pftable_clear_all(); 365 366 RB_FOREACH(p, peer_head, &conf->peers) 367 pfkey_remove(p); 368 369 while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { 370 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 371 free(rr); 372 } 373 free_config(conf); 374 375 log_debug("waiting for children to terminate"); 376 do { 377 pid = wait(&status); 378 if (pid == -1) { 379 if (errno != EINTR && errno != ECHILD) 380 fatal("wait"); 381 } else if (WIFSIGNALED(status)) { 382 char *name = "unknown process"; 383 if (pid == rde_pid) 384 name = "route decision engine"; 385 else if (pid == se_pid) 386 name = "session engine"; 387 log_warnx("%s terminated; signal %d", name, 388 WTERMSIG(status)); 389 } 390 } while (pid != -1 || (pid == -1 && errno == EINTR)); 391 392 free(rcname); 393 free(cname); 394 395 log_info("terminating"); 396 return (0); 397} 398 399pid_t 400start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose) 401{ 402 char *argv[5]; 403 int argc = 0; 404 pid_t pid; 405 406 switch (pid = fork()) { 407 case -1: 408 fatal("cannot fork"); 409 case 0: 410 break; 411 default: 412 close(fd); 413 return (pid); 414 } 415 416 if (fd != 3) { 417 if (dup2(fd, 3) == -1) 418 fatal("cannot setup imsg fd"); 419 } else if (fcntl(fd, F_SETFD, 0) == -1) 420 fatal("cannot setup imsg fd"); 421 422 argv[argc++] = argv0; 423 switch (p) { 424 case PROC_MAIN: 425 fatalx("Can not start main process"); 426 case PROC_RDE: 427 argv[argc++] = "-R"; 428 break; 429 case PROC_SE: 430 argv[argc++] = "-S"; 431 break; 432 } 433 if (debug) 434 argv[argc++] = "-d"; 435 if (verbose) 436 argv[argc++] = "-v"; 437 argv[argc++] = NULL; 438 439 execvp(argv0, argv); 440 fatal("execvp"); 441} 442 443int 444send_filterset(struct imsgbuf *i, struct filter_set_head *set) 445{ 446 struct filter_set *s; 447 448 TAILQ_FOREACH(s, set, entry) 449 if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s, 450 sizeof(struct filter_set)) == -1) 451 return (-1); 452 return (0); 453} 454 455int 456reconfigure(char *conffile, struct bgpd_config *conf) 457{ 458 struct bgpd_config *new_conf; 459 struct peer *p; 460 struct filter_rule *r; 461 struct listen_addr *la; 462 struct rde_rib *rr; 463 struct l3vpn *vpn; 464 struct as_set *aset; 465 struct prefixset *ps; 466 struct prefixset_item *psi, *npsi; 467 468 if (reconfpending) { 469 log_info("previous reload still running"); 470 return (2); 471 } 472 reconfpending = 2; /* one per child */ 473 474 log_info("rereading config"); 475 if ((new_conf = parse_config(conffile, &conf->peers)) == NULL) { 476 log_warnx("config file %s has errors, not reloading", 477 conffile); 478 reconfpending = 0; 479 return (1); 480 } 481 merge_config(conf, new_conf); 482 483 if (prepare_listeners(conf) == -1) { 484 reconfpending = 0; 485 return (1); 486 } 487 488 if (control_setup(conf) == -1) { 489 reconfpending = 0; 490 return (1); 491 } 492 493 expand_networks(conf); 494 495 cflags = conf->flags; 496 497 /* start reconfiguration */ 498 if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1, 499 conf, sizeof(*conf)) == -1) 500 return (-1); 501 if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1, 502 conf, sizeof(*conf)) == -1) 503 return (-1); 504 505 TAILQ_FOREACH(la, conf->listen_addrs, entry) { 506 if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd, 507 la, sizeof(*la)) == -1) 508 return (-1); 509 la->fd = -1; 510 } 511 512 /* adjust fib syncing on reload */ 513 ktable_preload(); 514 515 /* RIBs for the RDE */ 516 while ((rr = SIMPLEQ_FIRST(&ribnames))) { 517 SIMPLEQ_REMOVE_HEAD(&ribnames, entry); 518 if (ktable_update(rr->rtableid, rr->name, rr->flags, 519 conf->fib_priority) == -1) { 520 log_warnx("failed to load rdomain %d", 521 rr->rtableid); 522 return (-1); 523 } 524 if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1, 525 rr, sizeof(*rr)) == -1) 526 return (-1); 527 free(rr); 528 } 529 530 /* send peer list to the SE */ 531 RB_FOREACH(p, peer_head, &conf->peers) { 532 if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1, 533 &p->conf, sizeof(p->conf)) == -1) 534 return (-1); 535 536 if (p->reconf_action == RECONF_REINIT) 537 if (pfkey_establish(p) == -1) 538 log_peer_warnx(&p->conf, "pfkey setup failed"); 539 } 540 541 /* networks go via kroute to the RDE */ 542 kr_net_reload(conf->default_tableid, 0, &conf->networks); 543 544 /* prefixsets for filters in the RDE */ 545 while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) { 546 SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry); 547 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET, 0, 0, -1, 548 ps->name, sizeof(ps->name)) == -1) 549 return (-1); 550 RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) { 551 RB_REMOVE(prefixset_tree, &ps->psitems, psi); 552 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM, 553 0, 0, -1, psi, sizeof(*psi)) == -1) 554 return (-1); 555 set_free(psi->set); 556 free(psi); 557 } 558 free(ps); 559 } 560 561 /* originsets for filters in the RDE */ 562 while ((ps = SIMPLEQ_FIRST(&conf->originsets)) != NULL) { 563 SIMPLEQ_REMOVE_HEAD(&conf->originsets, entry); 564 if (imsg_compose(ibuf_rde, IMSG_RECONF_ORIGIN_SET, 0, 0, -1, 565 ps->name, sizeof(ps->name)) == -1) 566 return (-1); 567 RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) { 568 struct roa_set *rs; 569 size_t i, l, n; 570 RB_REMOVE(prefixset_tree, &ps->psitems, psi); 571 rs = set_get(psi->set, &n); 572 for (i = 0; i < n; i += l) { 573 l = (n - i > 1024 ? 1024 : n - i); 574 if (imsg_compose(ibuf_rde, 575 IMSG_RECONF_ROA_SET_ITEMS, 576 0, 0, -1, rs + i, l * sizeof(*rs)) == -1) 577 return -1; 578 } 579 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM, 580 0, 0, -1, psi, sizeof(*psi)) == -1) 581 return (-1); 582 set_free(psi->set); 583 free(psi); 584 } 585 free(ps); 586 } 587 588 if (!RB_EMPTY(&conf->roa)) { 589 if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_SET, 0, 0, -1, 590 NULL, 0) == -1) 591 return (-1); 592 RB_FOREACH_SAFE(psi, prefixset_tree, &conf->roa, npsi) { 593 struct roa_set *rs; 594 size_t i, l, n; 595 RB_REMOVE(prefixset_tree, &conf->roa, psi); 596 rs = set_get(psi->set, &n); 597 for (i = 0; i < n; i += l) { 598 l = (n - i > 1024 ? 1024 : n - i); 599 if (imsg_compose(ibuf_rde, 600 IMSG_RECONF_ROA_SET_ITEMS, 601 0, 0, -1, rs + i, l * sizeof(*rs)) == -1) 602 return -1; 603 } 604 if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM, 605 0, 0, -1, psi, sizeof(*psi)) == -1) 606 return (-1); 607 set_free(psi->set); 608 free(psi); 609 } 610 } 611 612 /* as-sets for filters in the RDE */ 613 while ((aset = SIMPLEQ_FIRST(&conf->as_sets)) != NULL) { 614 struct ibuf *wbuf; 615 u_int32_t *as; 616 size_t i, l, n; 617 618 SIMPLEQ_REMOVE_HEAD(&conf->as_sets, entry); 619 620 as = set_get(aset->set, &n); 621 if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0, 622 sizeof(n) + sizeof(aset->name))) == NULL) 623 return -1; 624 if (imsg_add(wbuf, &n, sizeof(n)) == -1 || 625 imsg_add(wbuf, aset->name, sizeof(aset->name)) == -1) 626 return -1; 627 imsg_close(ibuf_rde, wbuf); 628 629 for (i = 0; i < n; i += l) { 630 l = (n - i > 1024 ? 1024 : n - i); 631 if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_ITEMS, 632 0, 0, -1, as + i, l * sizeof(*as)) == -1) 633 return -1; 634 } 635 636 if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_DONE, 0, 0, -1, 637 NULL, 0) == -1) 638 return -1; 639 640 set_free(aset->set); 641 free(aset); 642 } 643 644 /* filters for the RDE */ 645 while ((r = TAILQ_FIRST(conf->filters)) != NULL) { 646 TAILQ_REMOVE(conf->filters, r, entry); 647 if (send_filterset(ibuf_rde, &r->set) == -1) 648 return (-1); 649 if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1, 650 r, sizeof(struct filter_rule)) == -1) 651 return (-1); 652 filterset_free(&r->set); 653 free(r); 654 } 655 656 while ((vpn = SIMPLEQ_FIRST(&conf->l3vpns)) != NULL) { 657 SIMPLEQ_REMOVE_HEAD(&conf->l3vpns, entry); 658 if (ktable_update(vpn->rtableid, vpn->descr, vpn->flags, 659 conf->fib_priority) == -1) { 660 log_warnx("failed to load rdomain %d", 661 vpn->rtableid); 662 return (-1); 663 } 664 /* networks go via kroute to the RDE */ 665 kr_net_reload(vpn->rtableid, vpn->rd, &vpn->net_l); 666 667 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN, 0, 0, -1, 668 vpn, sizeof(*vpn)) == -1) 669 return (-1); 670 671 /* export targets */ 672 if (send_filterset(ibuf_rde, &vpn->export) == -1) 673 return (-1); 674 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_EXPORT, 0, 0, 675 -1, NULL, 0) == -1) 676 return (-1); 677 filterset_free(&vpn->export); 678 679 /* import targets */ 680 if (send_filterset(ibuf_rde, &vpn->import) == -1) 681 return (-1); 682 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_IMPORT, 0, 0, 683 -1, NULL, 0) == -1) 684 return (-1); 685 filterset_free(&vpn->import); 686 687 if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_DONE, 0, 0, 688 -1, NULL, 0) == -1) 689 return (-1); 690 691 free(vpn); 692 } 693 694 /* send a drain message to know when all messages where processed */ 695 if (imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1) 696 return (-1); 697 if (imsg_compose(ibuf_rde, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1) 698 return (-1); 699 700 /* mrt changes can be sent out of bound */ 701 mrt_reconfigure(conf->mrt); 702 return (0); 703} 704 705int 706dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf) 707{ 708 struct imsg imsg; 709 struct peer *p; 710 ssize_t n; 711 int rv, verbose; 712 713 rv = 0; 714 while (ibuf) { 715 if ((n = imsg_get(ibuf, &imsg)) == -1) 716 return (-1); 717 718 if (n == 0) 719 break; 720 721 switch (imsg.hdr.type) { 722 case IMSG_KROUTE_CHANGE: 723 if (idx != PFD_PIPE_ROUTE) 724 log_warnx("route request not from RDE"); 725 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 726 sizeof(struct kroute_full)) 727 log_warnx("wrong imsg len"); 728 else if (kr_change(imsg.hdr.peerid, imsg.data, 729 conf->fib_priority)) 730 rv = -1; 731 break; 732 case IMSG_KROUTE_DELETE: 733 if (idx != PFD_PIPE_ROUTE) 734 log_warnx("route request not from RDE"); 735 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 736 sizeof(struct kroute_full)) 737 log_warnx("wrong imsg len"); 738 else if (kr_delete(imsg.hdr.peerid, imsg.data, 739 conf->fib_priority)) 740 rv = -1; 741 break; 742 case IMSG_KROUTE_FLUSH: 743 if (idx != PFD_PIPE_ROUTE) 744 log_warnx("route request not from RDE"); 745 else if (imsg.hdr.len != IMSG_HEADER_SIZE) 746 log_warnx("wrong imsg len"); 747 else if (kr_flush(imsg.hdr.peerid)) 748 rv = -1; 749 break; 750 case IMSG_NEXTHOP_ADD: 751 if (idx != PFD_PIPE_ROUTE) 752 log_warnx("nexthop request not from RDE"); 753 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 754 sizeof(struct bgpd_addr)) 755 log_warnx("wrong imsg len"); 756 else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data, 757 conf) == -1) 758 rv = -1; 759 break; 760 case IMSG_NEXTHOP_REMOVE: 761 if (idx != PFD_PIPE_ROUTE) 762 log_warnx("nexthop request not from RDE"); 763 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 764 sizeof(struct bgpd_addr)) 765 log_warnx("wrong imsg len"); 766 else 767 kr_nexthop_delete(imsg.hdr.peerid, imsg.data, 768 conf); 769 break; 770 case IMSG_PFTABLE_ADD: 771 if (idx != PFD_PIPE_ROUTE) 772 log_warnx("pftable request not from RDE"); 773 else 774 if (imsg.hdr.len != IMSG_HEADER_SIZE + 775 sizeof(struct pftable_msg)) 776 log_warnx("wrong imsg len"); 777 else if (pftable_addr_add(imsg.data) != 0) 778 rv = -1; 779 break; 780 case IMSG_PFTABLE_REMOVE: 781 if (idx != PFD_PIPE_ROUTE) 782 log_warnx("pftable request not from RDE"); 783 else 784 if (imsg.hdr.len != IMSG_HEADER_SIZE + 785 sizeof(struct pftable_msg)) 786 log_warnx("wrong imsg len"); 787 else if (pftable_addr_remove(imsg.data) != 0) 788 rv = -1; 789 break; 790 case IMSG_PFTABLE_COMMIT: 791 if (idx != PFD_PIPE_ROUTE) 792 log_warnx("pftable request not from RDE"); 793 else if (imsg.hdr.len != IMSG_HEADER_SIZE) 794 log_warnx("wrong imsg len"); 795 else if (pftable_commit() != 0) 796 rv = -1; 797 break; 798 case IMSG_PFKEY_RELOAD: 799 if (idx != PFD_PIPE_SESSION) 800 log_warnx("pfkey reload request not from SE"); 801 else if ((p = getpeerbyid(conf, imsg.hdr.peerid)) == 802 NULL) 803 log_warnx("pfkey reload: no such peer: id=%u", 804 imsg.hdr.peerid); 805 else { 806 if (pfkey_establish(p) == -1) 807 log_peer_warnx(&p->conf, 808 "pfkey setup failed"); 809 } 810 break; 811 case IMSG_CTL_RELOAD: 812 if (idx != PFD_PIPE_SESSION) 813 log_warnx("reload request not from SE"); 814 else { 815 reconfig = 1; 816 reconfpid = imsg.hdr.pid; 817 } 818 break; 819 case IMSG_CTL_FIB_COUPLE: 820 if (idx != PFD_PIPE_SESSION) 821 log_warnx("couple request not from SE"); 822 else 823 kr_fib_couple(imsg.hdr.peerid, 824 conf->fib_priority); 825 break; 826 case IMSG_CTL_FIB_DECOUPLE: 827 if (idx != PFD_PIPE_SESSION) 828 log_warnx("decouple request not from SE"); 829 else 830 kr_fib_decouple(imsg.hdr.peerid, 831 conf->fib_priority); 832 break; 833 case IMSG_CTL_KROUTE: 834 case IMSG_CTL_KROUTE_ADDR: 835 case IMSG_CTL_SHOW_NEXTHOP: 836 case IMSG_CTL_SHOW_INTERFACE: 837 case IMSG_CTL_SHOW_FIB_TABLES: 838 if (idx != PFD_PIPE_SESSION) 839 log_warnx("kroute request not from SE"); 840 else 841 kr_show_route(&imsg); 842 break; 843 case IMSG_IFINFO: 844 if (idx != PFD_PIPE_SESSION) 845 log_warnx("IFINFO request not from SE"); 846 else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ) 847 log_warnx("IFINFO request with wrong len"); 848 else 849 kr_ifinfo(imsg.data); 850 break; 851 case IMSG_DEMOTE: 852 if (idx != PFD_PIPE_SESSION) 853 log_warnx("demote request not from SE"); 854 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 855 sizeof(struct demote_msg)) 856 log_warnx("DEMOTE request with wrong len"); 857 else { 858 struct demote_msg *msg; 859 860 msg = imsg.data; 861 carp_demote_set(msg->demote_group, msg->level); 862 } 863 break; 864 case IMSG_CTL_LOG_VERBOSE: 865 /* already checked by SE */ 866 memcpy(&verbose, imsg.data, sizeof(verbose)); 867 log_setverbose(verbose); 868 break; 869 case IMSG_RECONF_DONE: 870 if (reconfpending == 0) { 871 log_warnx("unexpected RECONF_DONE received"); 872 break; 873 } 874 if (idx == PFD_PIPE_SESSION) { 875 imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 876 0, -1, NULL, 0); 877 878 /* finally fix kroute information */ 879 ktable_postload(conf->fib_priority); 880 881 /* redistribute list needs to be reloaded too */ 882 kr_reload(); 883 } 884 reconfpending--; 885 break; 886 case IMSG_RECONF_DRAIN: 887 if (reconfpending == 0) { 888 log_warnx("unexpected RECONF_DRAIN received"); 889 break; 890 } 891 reconfpending--; 892 if (reconfpending == 0) { 893 /* 894 * SE goes first to bring templated neighbors 895 * in sync. 896 */ 897 imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 898 0, -1, NULL, 0); 899 reconfpending = 2; /* expecting 2 DONE msg */ 900 } 901 break; 902 default: 903 break; 904 } 905 imsg_free(&imsg); 906 if (rv != 0) 907 return (rv); 908 } 909 return (0); 910} 911 912void 913send_nexthop_update(struct kroute_nexthop *msg) 914{ 915 char *gw = NULL; 916 917 if (msg->gateway.aid) 918 if (asprintf(&gw, ": via %s", 919 log_addr(&msg->gateway)) == -1) { 920 log_warn("send_nexthop_update"); 921 quit = 1; 922 } 923 924 log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop), 925 msg->valid ? "valid" : "invalid", 926 msg->connected ? ": directly connected" : "", 927 msg->gateway.aid ? gw : ""); 928 929 free(gw); 930 931 if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1, 932 msg, sizeof(struct kroute_nexthop)) == -1) 933 quit = 1; 934} 935 936void 937send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen) 938{ 939 imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen); 940} 941 942int 943send_network(int type, struct network_config *net, struct filter_set_head *h) 944{ 945 if (quit) 946 return (0); 947 if (imsg_compose(ibuf_rde, type, 0, 0, -1, net, 948 sizeof(struct network_config)) == -1) 949 return (-1); 950 /* networks that get deleted don't need to send the filter set */ 951 if (type == IMSG_NETWORK_REMOVE) 952 return (0); 953 if (send_filterset(ibuf_rde, h) == -1) 954 return (-1); 955 if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1) 956 return (-1); 957 958 return (0); 959} 960 961int 962bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6) 963{ 964 /* kernel routes are never filtered */ 965 if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0) 966 return (0); 967 if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0) 968 return (0); 969 970 if (cflags & BGPD_FLAG_NEXTHOP_BGP) { 971 if (kr && kr->flags & F_BGPD_INSERTED) 972 return (0); 973 if (kr6 && kr6->flags & F_BGPD_INSERTED) 974 return (0); 975 } 976 977 if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) { 978 if (kr && kr->prefixlen == 0) 979 return (0); 980 if (kr6 && kr6->prefixlen == 0) 981 return (0); 982 } 983 984 return (1); 985} 986 987int 988control_setup(struct bgpd_config *conf) 989{ 990 int fd, restricted; 991 992 /* control socket is outside chroot */ 993 if (!cname || strcmp(cname, conf->csock)) { 994 if (cname) { 995 free(cname); 996 } 997 if ((cname = strdup(conf->csock)) == NULL) 998 fatal("strdup"); 999 if (control_check(cname) == -1) 1000 return (-1); 1001 if ((fd = control_init(0, cname)) == -1) 1002 fatalx("control socket setup failed"); 1003 if (control_listen(fd) == -1) 1004 fatalx("control socket setup failed"); 1005 restricted = 0; 1006 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 1007 &restricted, sizeof(restricted)) == -1) 1008 return (-1); 1009 } 1010 if (!conf->rcsock) { 1011 /* remove restricted socket */ 1012 free(rcname); 1013 rcname = NULL; 1014 } else if (!rcname || strcmp(rcname, conf->rcsock)) { 1015 if (rcname) { 1016 free(rcname); 1017 } 1018 if ((rcname = strdup(conf->rcsock)) == NULL) 1019 fatal("strdup"); 1020 if (control_check(rcname) == -1) 1021 return (-1); 1022 if ((fd = control_init(1, rcname)) == -1) 1023 fatalx("control socket setup failed"); 1024 if (control_listen(fd) == -1) 1025 fatalx("control socket setup failed"); 1026 restricted = 1; 1027 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 1028 &restricted, sizeof(restricted)) == -1) 1029 return (-1); 1030 } 1031 return (0); 1032} 1033 1034void 1035set_pollfd(struct pollfd *pfd, struct imsgbuf *i) 1036{ 1037 if (i == NULL || i->fd == -1) { 1038 pfd->fd = -1; 1039 return; 1040 } 1041 pfd->fd = i->fd; 1042 pfd->events = POLLIN; 1043 if (i->w.queued > 0) 1044 pfd->events |= POLLOUT; 1045} 1046 1047int 1048handle_pollfd(struct pollfd *pfd, struct imsgbuf *i) 1049{ 1050 ssize_t n; 1051 1052 if (i == NULL) 1053 return (0); 1054 1055 if (pfd->revents & POLLOUT) 1056 if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) { 1057 log_warn("imsg write error"); 1058 close(i->fd); 1059 i->fd = -1; 1060 return (-1); 1061 } 1062 1063 if (pfd->revents & POLLIN) { 1064 if ((n = imsg_read(i)) == -1 && errno != EAGAIN) { 1065 log_warn("imsg read error"); 1066 close(i->fd); 1067 i->fd = -1; 1068 return (-1); 1069 } 1070 if (n == 0) { 1071 log_warnx("peer closed imsg connection"); 1072 close(i->fd); 1073 i->fd = -1; 1074 return (-1); 1075 } 1076 } 1077 return (0); 1078} 1079 1080static void 1081getsockpair(int pipe[2]) 1082{ 1083 int bsize, i; 1084 1085 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 1086 PF_UNSPEC, pipe) == -1) 1087 fatal("socketpair"); 1088 1089 for (i = 0; i < 2; i++) { 1090 for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) { 1091 if (setsockopt(pipe[i], SOL_SOCKET, SO_RCVBUF, 1092 &bsize, sizeof(bsize)) == -1) { 1093 if (errno != ENOBUFS) 1094 fatal("setsockopt(SO_RCVBUF, %d)", 1095 bsize); 1096 log_warn("setsockopt(SO_RCVBUF, %d)", bsize); 1097 continue; 1098 } 1099 break; 1100 } 1101 } 1102 for (i = 0; i < 2; i++) { 1103 for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) { 1104 if (setsockopt(pipe[i], SOL_SOCKET, SO_SNDBUF, 1105 &bsize, sizeof(bsize)) == -1) { 1106 if (errno != ENOBUFS) 1107 fatal("setsockopt(SO_SNDBUF, %d)", 1108 bsize); 1109 log_warn("setsockopt(SO_SNDBUF, %d)", bsize); 1110 continue; 1111 } 1112 break; 1113 } 1114 } 1115} 1116 1117int 1118imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde) 1119{ 1120 int pipe_s2r[2]; 1121 int pipe_s2r_ctl[2]; 1122 1123 getsockpair(pipe_s2r); 1124 getsockpair(pipe_s2r_ctl); 1125 1126 if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0], 1127 NULL, 0) == -1) 1128 return (-1); 1129 if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1], 1130 NULL, 0) == -1) 1131 return (-1); 1132 1133 if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0], 1134 NULL, 0) == -1) 1135 return (-1); 1136 if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1], 1137 NULL, 0) == -1) 1138 return (-1); 1139 1140 return (0); 1141} 1142