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