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