bgpd.c revision 1.197
1/* $OpenBSD: bgpd.c,v 1.197 2018/09/07 10:59:16 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 "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->name, sizeof(ps->name)) == -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 /* as-sets for filters in the RDE */ 523 if (as_sets_send(ibuf_rde, conf->as_sets) == -1) 524 return (-1); 525 as_sets_free(conf->as_sets); 526 conf->as_sets = NULL; 527 528 /* filters for the RDE */ 529 while ((r = TAILQ_FIRST(conf->filters)) != NULL) { 530 TAILQ_REMOVE(conf->filters, r, entry); 531 if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1, 532 r, sizeof(struct filter_rule)) == -1) 533 return (-1); 534 if (send_filterset(ibuf_rde, &r->set) == -1) 535 return (-1); 536 filterset_free(&r->set); 537 free(r); 538 } 539 540 while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) { 541 SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry); 542 if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe, 543 rd->flags, conf->fib_priority) == -1) { 544 log_warnx("failed to load rdomain %d", 545 rd->rtableid); 546 return (-1); 547 } 548 /* networks go via kroute to the RDE */ 549 if (kr_net_reload(rd->rtableid, &rd->net_l)) 550 return (-1); 551 552 if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN, 0, 0, -1, 553 rd, sizeof(*rd)) == -1) 554 return (-1); 555 556 /* export targets */ 557 if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_EXPORT, 0, 0, 558 -1, NULL, 0) == -1) 559 return (-1); 560 if (send_filterset(ibuf_rde, &rd->export) == -1) 561 return (-1); 562 filterset_free(&rd->export); 563 564 /* import targets */ 565 if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_IMPORT, 0, 0, 566 -1, NULL, 0) == -1) 567 return (-1); 568 if (send_filterset(ibuf_rde, &rd->import) == -1) 569 return (-1); 570 filterset_free(&rd->import); 571 572 if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_DONE, 0, 0, 573 -1, NULL, 0) == -1) 574 return (-1); 575 576 free(rd); 577 } 578 579 /* signal the SE first then the RDE to activate the new config */ 580 if (imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1) 581 return (-1); 582 583 /* mrt changes can be sent out of bound */ 584 mrt_reconfigure(conf->mrt); 585 return (0); 586} 587 588int 589dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf) 590{ 591 struct imsg imsg; 592 ssize_t n; 593 int rv, verbose; 594 595 rv = 0; 596 while (ibuf) { 597 if ((n = imsg_get(ibuf, &imsg)) == -1) 598 return (-1); 599 600 if (n == 0) 601 break; 602 603 switch (imsg.hdr.type) { 604 case IMSG_KROUTE_CHANGE: 605 if (idx != PFD_PIPE_ROUTE) 606 log_warnx("route request not from RDE"); 607 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 608 sizeof(struct kroute_full)) 609 log_warnx("wrong imsg len"); 610 else if (kr_change(imsg.hdr.peerid, imsg.data, 611 conf->fib_priority)) 612 rv = -1; 613 break; 614 case IMSG_KROUTE_DELETE: 615 if (idx != PFD_PIPE_ROUTE) 616 log_warnx("route request not from RDE"); 617 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 618 sizeof(struct kroute_full)) 619 log_warnx("wrong imsg len"); 620 else if (kr_delete(imsg.hdr.peerid, imsg.data, 621 conf->fib_priority)) 622 rv = -1; 623 break; 624 case IMSG_NEXTHOP_ADD: 625 if (idx != PFD_PIPE_ROUTE) 626 log_warnx("nexthop request not from RDE"); 627 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 628 sizeof(struct bgpd_addr)) 629 log_warnx("wrong imsg len"); 630 else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data, 631 conf) == -1) 632 rv = -1; 633 break; 634 case IMSG_NEXTHOP_REMOVE: 635 if (idx != PFD_PIPE_ROUTE) 636 log_warnx("nexthop request not from RDE"); 637 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 638 sizeof(struct bgpd_addr)) 639 log_warnx("wrong imsg len"); 640 else 641 kr_nexthop_delete(imsg.hdr.peerid, imsg.data, 642 conf); 643 break; 644 case IMSG_PFTABLE_ADD: 645 if (idx != PFD_PIPE_ROUTE) 646 log_warnx("pftable request not from RDE"); 647 else 648 if (imsg.hdr.len != IMSG_HEADER_SIZE + 649 sizeof(struct pftable_msg)) 650 log_warnx("wrong imsg len"); 651 else if (pftable_addr_add(imsg.data) != 0) 652 rv = -1; 653 break; 654 case IMSG_PFTABLE_REMOVE: 655 if (idx != PFD_PIPE_ROUTE) 656 log_warnx("pftable request not from RDE"); 657 else 658 if (imsg.hdr.len != IMSG_HEADER_SIZE + 659 sizeof(struct pftable_msg)) 660 log_warnx("wrong imsg len"); 661 else if (pftable_addr_remove(imsg.data) != 0) 662 rv = -1; 663 break; 664 case IMSG_PFTABLE_COMMIT: 665 if (idx != PFD_PIPE_ROUTE) 666 log_warnx("pftable request not from RDE"); 667 else 668 if (imsg.hdr.len != IMSG_HEADER_SIZE) 669 log_warnx("wrong imsg len"); 670 else if (pftable_commit() != 0) 671 rv = -1; 672 break; 673 case IMSG_CTL_RELOAD: 674 if (idx != PFD_PIPE_SESSION) 675 log_warnx("reload request not from SE"); 676 else { 677 reconfig = 1; 678 reconfpid = imsg.hdr.pid; 679 } 680 break; 681 case IMSG_CTL_FIB_COUPLE: 682 if (idx != PFD_PIPE_SESSION) 683 log_warnx("couple request not from SE"); 684 else 685 kr_fib_couple(imsg.hdr.peerid, 686 conf->fib_priority); 687 break; 688 case IMSG_CTL_FIB_DECOUPLE: 689 if (idx != PFD_PIPE_SESSION) 690 log_warnx("decouple request not from SE"); 691 else 692 kr_fib_decouple(imsg.hdr.peerid, 693 conf->fib_priority); 694 break; 695 case IMSG_CTL_KROUTE: 696 case IMSG_CTL_KROUTE_ADDR: 697 case IMSG_CTL_SHOW_NEXTHOP: 698 case IMSG_CTL_SHOW_INTERFACE: 699 case IMSG_CTL_SHOW_FIB_TABLES: 700 if (idx != PFD_PIPE_SESSION) 701 log_warnx("kroute request not from SE"); 702 else 703 kr_show_route(&imsg); 704 break; 705 case IMSG_IFINFO: 706 if (idx != PFD_PIPE_SESSION) 707 log_warnx("IFINFO request not from SE"); 708 else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ) 709 log_warnx("IFINFO request with wrong len"); 710 else 711 kr_ifinfo(imsg.data); 712 break; 713 case IMSG_DEMOTE: 714 if (idx != PFD_PIPE_SESSION) 715 log_warnx("demote request not from SE"); 716 else if (imsg.hdr.len != IMSG_HEADER_SIZE + 717 sizeof(struct demote_msg)) 718 log_warnx("DEMOTE request with wrong len"); 719 else { 720 struct demote_msg *msg; 721 722 msg = imsg.data; 723 carp_demote_set(msg->demote_group, msg->level); 724 } 725 break; 726 case IMSG_CTL_LOG_VERBOSE: 727 /* already checked by SE */ 728 memcpy(&verbose, imsg.data, sizeof(verbose)); 729 log_setverbose(verbose); 730 break; 731 case IMSG_RECONF_DONE: 732 if (reconfpending == 0) 733 log_warnx("unexpected RECONF_DONE received"); 734 else if (reconfpending == 2) { 735 imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 736 0, -1, NULL, 0); 737 738 /* finally fix kroute information */ 739 ktable_postload(conf->fib_priority); 740 741 /* redistribute list needs to be reloaded too */ 742 kr_reload(); 743 } 744 reconfpending--; 745 break; 746 default: 747 break; 748 } 749 imsg_free(&imsg); 750 if (rv != 0) 751 return (rv); 752 } 753 return (0); 754} 755 756void 757send_nexthop_update(struct kroute_nexthop *msg) 758{ 759 char *gw = NULL; 760 761 if (msg->gateway.aid) 762 if (asprintf(&gw, ": via %s", 763 log_addr(&msg->gateway)) == -1) { 764 log_warn("send_nexthop_update"); 765 quit = 1; 766 } 767 768 log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop), 769 msg->valid ? "valid" : "invalid", 770 msg->connected ? ": directly connected" : "", 771 msg->gateway.aid ? gw : ""); 772 773 free(gw); 774 775 if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1, 776 msg, sizeof(struct kroute_nexthop)) == -1) 777 quit = 1; 778} 779 780void 781send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen) 782{ 783 imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen); 784} 785 786int 787send_network(int type, struct network_config *net, struct filter_set_head *h) 788{ 789 if (imsg_compose(ibuf_rde, type, 0, 0, -1, net, 790 sizeof(struct network_config)) == -1) 791 return (-1); 792 /* networks that get deleted don't need to send the filter set */ 793 if (type == IMSG_NETWORK_REMOVE) 794 return (0); 795 if (send_filterset(ibuf_rde, h) == -1) 796 return (-1); 797 if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1) 798 return (-1); 799 800 return (0); 801} 802 803int 804bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6) 805{ 806 /* kernel routes are never filtered */ 807 if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0) 808 return (0); 809 if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0) 810 return (0); 811 812 if (cflags & BGPD_FLAG_NEXTHOP_BGP) { 813 if (kr && kr->flags & F_BGPD_INSERTED) 814 return (0); 815 if (kr6 && kr6->flags & F_BGPD_INSERTED) 816 return (0); 817 } 818 819 if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) { 820 if (kr && kr->prefixlen == 0) 821 return (0); 822 if (kr6 && kr6->prefixlen == 0) 823 return (0); 824 } 825 826 return (1); 827} 828 829int 830control_setup(struct bgpd_config *conf) 831{ 832 int fd, restricted; 833 834 /* control socket is outside chroot */ 835 if (!cname || strcmp(cname, conf->csock)) { 836 if (cname) { 837 control_cleanup(cname); 838 free(cname); 839 } 840 if ((cname = strdup(conf->csock)) == NULL) 841 fatal("strdup"); 842 if ((fd = control_init(0, cname)) == -1) 843 fatalx("control socket setup failed"); 844 if (control_listen(fd) == -1) 845 fatalx("control socket setup failed"); 846 restricted = 0; 847 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 848 &restricted, sizeof(restricted)) == -1) 849 return (-1); 850 } 851 if (!conf->rcsock) { 852 /* remove restricted socket */ 853 control_cleanup(rcname); 854 free(rcname); 855 rcname = NULL; 856 } else if (!rcname || strcmp(rcname, conf->rcsock)) { 857 if (rcname) { 858 control_cleanup(rcname); 859 free(rcname); 860 } 861 if ((rcname = strdup(conf->rcsock)) == NULL) 862 fatal("strdup"); 863 if ((fd = control_init(1, rcname)) == -1) 864 fatalx("control socket setup failed"); 865 if (control_listen(fd) == -1) 866 fatalx("control socket setup failed"); 867 restricted = 1; 868 if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd, 869 &restricted, sizeof(restricted)) == -1) 870 return (-1); 871 } 872 return (0); 873} 874 875void 876set_pollfd(struct pollfd *pfd, struct imsgbuf *i) 877{ 878 if (i == NULL || i->fd == -1) { 879 pfd->fd = -1; 880 return; 881 } 882 pfd->fd = i->fd; 883 pfd->events = POLLIN; 884 if (i->w.queued > 0) 885 pfd->events |= POLLOUT; 886} 887 888int 889handle_pollfd(struct pollfd *pfd, struct imsgbuf *i) 890{ 891 ssize_t n; 892 893 if (i == NULL) 894 return (0); 895 896 if (pfd->revents & POLLOUT) 897 if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) { 898 log_warn("imsg write error"); 899 close(i->fd); 900 i->fd = -1; 901 return (-1); 902 } 903 904 if (pfd->revents & POLLIN) { 905 if ((n = imsg_read(i)) == -1 && errno != EAGAIN) { 906 log_warn("imsg read error"); 907 close(i->fd); 908 i->fd = -1; 909 return (-1); 910 } 911 if (n == 0) { 912 log_warnx("peer closed imsg connection"); 913 close(i->fd); 914 i->fd = -1; 915 return (-1); 916 } 917 } 918 return (0); 919} 920 921int 922imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde) 923{ 924 int pipe_s2r[2]; 925 int pipe_s2r_ctl[2]; 926 927 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 928 PF_UNSPEC, pipe_s2r) == -1) 929 return (-1); 930 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 931 PF_UNSPEC, pipe_s2r_ctl) == -1) 932 return (-1); 933 934 if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0], 935 NULL, 0) == -1) 936 return (-1); 937 if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1], 938 NULL, 0) == -1) 939 return (-1); 940 941 if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0], 942 NULL, 0) == -1) 943 return (-1); 944 if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1], 945 NULL, 0) == -1) 946 return (-1); 947 948 return (0); 949} 950