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