1 /* $OpenBSD: ripd.c,v 1.21 2011/08/20 19:02:28 sthen Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 #include <sys/queue.h> 25 #include <sys/time.h> 26 #include <sys/stat.h> 27 #include <sys/wait.h> 28 #include <sys/param.h> 29 #include <sys/sysctl.h> 30 31 #include <netinet/in.h> 32 #include <arpa/inet.h> 33 34 #include <event.h> 35 #include <err.h> 36 #include <errno.h> 37 #include <pwd.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <signal.h> 42 #include <unistd.h> 43 44 #include "rip.h" 45 #include "ripd.h" 46 #include "ripe.h" 47 #include "log.h" 48 #include "control.h" 49 #include "rde.h" 50 51 __dead void usage(void); 52 int check_child(pid_t, const char *); 53 void main_sig_handler(int, short, void *); 54 void ripd_shutdown(void); 55 void main_dispatch_ripe(int, short, void *); 56 void main_dispatch_rde(int, short, void *); 57 58 int pipe_parent2ripe[2]; 59 int pipe_parent2rde[2]; 60 int pipe_ripe2rde[2]; 61 62 struct ripd_conf *conf = NULL; 63 struct imsgev *iev_ripe; 64 struct imsgev *iev_rde; 65 66 pid_t ripe_pid = 0; 67 pid_t rde_pid = 0; 68 69 __dead void 70 usage(void) 71 { 72 extern char *__progname; 73 74 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 75 __progname); 76 exit(1); 77 } 78 79 /* ARGSUSED */ 80 void 81 main_sig_handler(int sig, short event, void *arg) 82 { 83 /* 84 * signal handler rules don't apply, libevent decouples for us 85 */ 86 87 int die = 0; 88 89 switch (sig) { 90 case SIGTERM: 91 case SIGINT: 92 die = 1; 93 /* FALLTHROUGH */ 94 case SIGCHLD: 95 if (check_child(ripe_pid, "rip engine")) { 96 ripe_pid = 0; 97 die = 1; 98 } 99 if (check_child(rde_pid, "route decision engine")) { 100 rde_pid = 0; 101 die = 1; 102 } 103 if (die) 104 ripd_shutdown(); 105 break; 106 case SIGHUP: 107 /* reconfigure */ 108 /* ... */ 109 break; 110 default: 111 fatalx("unexpected signal"); 112 /* NOTREACHED */ 113 } 114 } 115 116 int 117 main(int argc, char *argv[]) 118 { 119 struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; 120 int mib[4]; 121 int debug = 0; 122 int ipforwarding; 123 int ch; 124 int opts = 0; 125 char *conffile; 126 size_t len; 127 128 conffile = CONF_FILE; 129 ripd_process = PROC_MAIN; 130 131 log_init(1); /* log to stderr until daemonized */ 132 log_verbose(1); 133 134 while ((ch = getopt(argc, argv, "cdD:f:nv")) != -1) { 135 switch (ch) { 136 case 'c': 137 opts |= RIPD_OPT_FORCE_DEMOTE; 138 break; 139 case 'd': 140 debug = 1; 141 break; 142 case 'D': 143 if (cmdline_symset(optarg) < 0) 144 log_warnx("could not parse macro definition %s", 145 optarg); 146 break; 147 case 'f': 148 conffile = optarg; 149 break; 150 case 'n': 151 opts |= RIPD_OPT_NOACTION; 152 break; 153 case 'v': 154 if (opts & RIPD_OPT_VERBOSE) 155 opts |= RIPD_OPT_VERBOSE2; 156 opts |= RIPD_OPT_VERBOSE; 157 break; 158 default: 159 usage(); 160 /* NOTREACHED */ 161 } 162 } 163 164 argc -= optind; 165 argv += optind; 166 if (argc > 0) 167 usage(); 168 169 mib[0] = CTL_NET; 170 mib[1] = PF_INET; 171 mib[2] = IPPROTO_IP; 172 mib[3] = IPCTL_FORWARDING; 173 len = sizeof(ipforwarding); 174 if (sysctl(mib, 4, &ipforwarding, &len, NULL, 0) == -1) 175 err(1, "sysctl"); 176 177 if (!ipforwarding) 178 log_warnx("WARNING: IP forwarding NOT enabled"); 179 180 /* fetch interfaces early */ 181 kif_init(); 182 183 /* parse config file */ 184 if ((conf = parse_config(conffile, opts)) == NULL ) 185 exit(1); 186 187 if (conf->opts & RIPD_OPT_NOACTION) { 188 if (conf->opts & RIPD_OPT_VERBOSE) 189 print_config(conf); 190 else 191 fprintf(stderr, "configuration OK\n"); 192 exit(0); 193 } 194 195 /* check for root privileges */ 196 if (geteuid()) 197 errx(1, "need root privileges"); 198 199 /* check for ripd user */ 200 if (getpwnam(RIPD_USER) == NULL) 201 errx(1, "unknown user %s", RIPD_USER); 202 203 log_init(debug); 204 log_verbose(conf->opts & RIPD_OPT_VERBOSE); 205 206 if (!debug) 207 daemon(1, 0); 208 209 log_info("startup"); 210 211 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, 212 pipe_parent2ripe) == -1) 213 fatal("socketpair"); 214 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2rde) == -1) 215 fatal("socketpair"); 216 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_ripe2rde) == -1) 217 fatal("socketpair"); 218 session_socket_blockmode(pipe_parent2ripe[0], BM_NONBLOCK); 219 session_socket_blockmode(pipe_parent2ripe[1], BM_NONBLOCK); 220 session_socket_blockmode(pipe_parent2rde[0], BM_NONBLOCK); 221 session_socket_blockmode(pipe_parent2rde[1], BM_NONBLOCK); 222 session_socket_blockmode(pipe_ripe2rde[0], BM_NONBLOCK); 223 session_socket_blockmode(pipe_ripe2rde[1], BM_NONBLOCK); 224 225 /* start children */ 226 rde_pid = rde(conf, pipe_parent2rde, pipe_ripe2rde, pipe_parent2ripe); 227 ripe_pid = ripe(conf, pipe_parent2ripe, pipe_ripe2rde, pipe_parent2rde); 228 229 /* show who we are */ 230 setproctitle("parent"); 231 232 event_init(); 233 234 /* setup signal handler */ 235 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 236 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 237 signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL); 238 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 239 signal_add(&ev_sigint, NULL); 240 signal_add(&ev_sigterm, NULL); 241 signal_add(&ev_sigchld, NULL); 242 signal_add(&ev_sighup, NULL); 243 signal(SIGPIPE, SIG_IGN); 244 245 /* setup pipes to children */ 246 close(pipe_parent2ripe[1]); 247 close(pipe_parent2rde[1]); 248 close(pipe_ripe2rde[0]); 249 close(pipe_ripe2rde[1]); 250 251 if ((iev_ripe = malloc(sizeof(struct imsgev))) == NULL || 252 (iev_rde = malloc(sizeof(struct imsgev))) == NULL) 253 fatal(NULL); 254 imsg_init(&iev_ripe->ibuf, pipe_parent2ripe[0]); 255 iev_ripe->handler = main_dispatch_ripe; 256 imsg_init(&iev_rde->ibuf, pipe_parent2rde[0]); 257 iev_rde->handler = main_dispatch_rde; 258 259 /* setup event handler */ 260 iev_ripe->events = EV_READ; 261 event_set(&iev_ripe->ev, iev_ripe->ibuf.fd, iev_ripe->events, 262 iev_ripe->handler, iev_ripe); 263 event_add(&iev_ripe->ev, NULL); 264 265 iev_rde->events = EV_READ; 266 event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events, 267 iev_rde->handler, iev_rde); 268 event_add(&iev_rde->ev, NULL); 269 270 if (kr_init(!(conf->flags & RIPD_FLAG_NO_FIB_UPDATE), 271 conf->rdomain) == -1) 272 fatalx("kr_init failed"); 273 274 event_dispatch(); 275 276 ripd_shutdown(); 277 /* NOTREACHED */ 278 return (0); 279 } 280 281 void 282 ripd_shutdown(void) 283 { 284 struct iface *i; 285 pid_t pid; 286 287 if (ripe_pid) 288 kill(ripe_pid, SIGTERM); 289 290 if (rde_pid) 291 kill(rde_pid, SIGTERM); 292 293 while ((i = LIST_FIRST(&conf->iface_list)) != NULL) { 294 LIST_REMOVE(i, entry); 295 if_del(i); 296 } 297 298 control_cleanup(); 299 kr_shutdown(); 300 301 do { 302 if ((pid = wait(NULL)) == -1 && 303 errno != EINTR && errno != ECHILD) 304 fatal("wait"); 305 } while (pid != -1 || (pid == -1 && errno == EINTR)); 306 307 msgbuf_clear(&iev_ripe->ibuf.w); 308 free(iev_ripe); 309 msgbuf_clear(&iev_rde->ibuf.w); 310 free(iev_rde); 311 free(conf); 312 313 log_info("terminating"); 314 exit(0); 315 } 316 317 int 318 check_child(pid_t pid, const char *pname) 319 { 320 int status; 321 322 if (waitpid(pid, &status, WNOHANG) > 0) { 323 if (WIFEXITED(status)) { 324 log_warnx("lost child: %s exited", pname); 325 return (1); 326 } 327 if (WIFSIGNALED(status)) { 328 log_warnx("lost child: %s terminated; signal %d", 329 pname, WTERMSIG(status)); 330 return (1); 331 } 332 } 333 334 return (0); 335 } 336 337 /* imsg handling */ 338 /* ARGSUSED */ 339 void 340 main_dispatch_ripe(int fd, short event, void *bula) 341 { 342 struct imsgev *iev = bula; 343 struct imsgbuf *ibuf = &iev->ibuf; 344 struct imsg imsg; 345 struct demote_msg dmsg; 346 ssize_t n; 347 int shut = 0, verbose; 348 349 if (event & EV_READ) { 350 if ((n = imsg_read(ibuf)) == -1) 351 fatal("imsg_read error"); 352 if (n == 0) /* connection closed */ 353 shut = 1; 354 } 355 if (event & EV_WRITE) { 356 if (msgbuf_write(&ibuf->w) == -1) 357 fatal("msgbuf_write"); 358 } 359 360 for (;;) { 361 if ((n = imsg_get(ibuf, &imsg)) == -1) 362 fatal("imsg_get"); 363 364 if (n == 0) 365 break; 366 367 switch (imsg.hdr.type) { 368 case IMSG_CTL_RELOAD: 369 /* XXX reconfig */ 370 break; 371 case IMSG_CTL_FIB_COUPLE: 372 kr_fib_couple(); 373 break; 374 case IMSG_CTL_FIB_DECOUPLE: 375 kr_fib_decouple(); 376 break; 377 case IMSG_CTL_KROUTE: 378 case IMSG_CTL_KROUTE_ADDR: 379 kr_show_route(&imsg); 380 break; 381 case IMSG_CTL_IFINFO: 382 if (imsg.hdr.len == IMSG_HEADER_SIZE) 383 kr_ifinfo(NULL, imsg.hdr.pid); 384 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 385 kr_ifinfo(imsg.data, imsg.hdr.pid); 386 else 387 log_warnx("IFINFO request with wrong len"); 388 break; 389 case IMSG_DEMOTE: 390 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(dmsg)) 391 fatalx("invalid size of OE request"); 392 memcpy(&dmsg, imsg.data, sizeof(dmsg)); 393 carp_demote_set(dmsg.demote_group, dmsg.level); 394 break; 395 case IMSG_CTL_LOG_VERBOSE: 396 /* already checked by ripe */ 397 memcpy(&verbose, imsg.data, sizeof(verbose)); 398 log_verbose(verbose); 399 break; 400 default: 401 log_debug("main_dispatch_ripe: error handling imsg %d", 402 imsg.hdr.type); 403 break; 404 } 405 imsg_free(&imsg); 406 } 407 if (!shut) 408 imsg_event_add(iev); 409 else { 410 /* this pipe is dead, so remove the event handler */ 411 event_del(&iev->ev); 412 event_loopexit(NULL); 413 } 414 } 415 416 /* ARGSUSED */ 417 void 418 main_dispatch_rde(int fd, short event, void *bula) 419 { 420 struct imsgev *iev = bula; 421 struct imsgbuf *ibuf = &iev->ibuf; 422 struct imsg imsg; 423 ssize_t n; 424 int shut = 0; 425 426 if (event & EV_READ) { 427 if ((n = imsg_read(ibuf)) == -1) 428 fatal("imsg_read error"); 429 if (n == 0) /* connection closed */ 430 shut = 1; 431 } 432 if (event & EV_WRITE) { 433 if (msgbuf_write(&ibuf->w) == -1) 434 fatal("msgbuf_write"); 435 } 436 437 for (;;) { 438 if ((n = imsg_get(ibuf, &imsg)) == -1) 439 fatal("imsg_get"); 440 441 if (n == 0) 442 break; 443 444 switch (imsg.hdr.type) { 445 case IMSG_KROUTE_CHANGE: 446 if (kr_change(imsg.data)) 447 log_warn("main_dispatch_rde: error changing " 448 "route"); 449 break; 450 case IMSG_KROUTE_DELETE: 451 if (kr_delete(imsg.data)) 452 log_warn("main_dispatch_rde: error deleting " 453 "route"); 454 break; 455 default: 456 log_debug("main_dispatch_rde: error handling imsg %d", 457 imsg.hdr.type); 458 break; 459 } 460 imsg_free(&imsg); 461 } 462 if (!shut) 463 imsg_event_add(iev); 464 else { 465 /* this pipe is dead, so remove the event handler */ 466 event_del(&iev->ev); 467 event_loopexit(NULL); 468 } 469 } 470 471 void 472 main_imsg_compose_ripe(int type, pid_t pid, void *data, u_int16_t datalen) 473 { 474 imsg_compose_event(iev_ripe, type, 0, pid, -1, data, datalen); 475 } 476 477 void 478 main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) 479 { 480 imsg_compose_event(iev_rde, type, 0, pid, -1, data, datalen); 481 } 482 483 int 484 rip_redistribute(struct kroute *kr) 485 { 486 struct redistribute *r; 487 u_int8_t is_default = 0; 488 489 if (kr->flags & F_RIPD_INSERTED) 490 return (1); 491 492 /* only allow 0.0.0.0/0 via REDIST_DEFAULT */ 493 if (kr->prefix.s_addr == INADDR_ANY && kr->netmask.s_addr == INADDR_ANY) 494 is_default = 1; 495 496 SIMPLEQ_FOREACH(r, &conf->redist_list, entry) { 497 switch (r->type & ~REDIST_NO) { 498 case REDIST_LABEL: 499 if (kr->rtlabel == r->label) 500 return (r->type & REDIST_NO ? 0 : 1); 501 break; 502 case REDIST_STATIC: 503 /* 504 * Dynamic routes are not redistributable. Placed here 505 * so that link local addresses can be redistributed 506 * via a rtlabel. 507 */ 508 if (is_default) 509 continue; 510 if (kr->flags & F_DYNAMIC) 511 continue; 512 if (kr->flags & F_STATIC) 513 return (r->type & REDIST_NO ? 0 : 1); 514 break; 515 case REDIST_CONNECTED: 516 if (is_default) 517 continue; 518 if (kr->flags & F_DYNAMIC) 519 continue; 520 if (kr->flags & F_CONNECTED) 521 return (r->type & REDIST_NO ? 0 : 1); 522 break; 523 case REDIST_ADDR: 524 if (kr->flags & F_DYNAMIC) 525 continue; 526 527 if (r->addr.s_addr == INADDR_ANY && 528 r->mask.s_addr == INADDR_ANY) { 529 if (is_default) 530 return (r->type & REDIST_NO? 0 : 1); 531 else 532 return (0); 533 } 534 535 if ((kr->prefix.s_addr & r->mask.s_addr) == 536 (r->addr.s_addr & r->mask.s_addr) && 537 (kr->netmask.s_addr & r->mask.s_addr) == 538 r->mask.s_addr) 539 return (r->type & REDIST_NO? 0 : 1); 540 break; 541 case REDIST_DEFAULT: 542 if (is_default) 543 return (r->type & REDIST_NO? 0 : 1); 544 break; 545 } 546 } 547 548 return (0); 549 } 550 551 void 552 imsg_event_add(struct imsgev *iev) 553 { 554 if (iev->handler == NULL) { 555 imsg_flush(&iev->ibuf); 556 return; 557 } 558 559 iev->events = EV_READ; 560 if (iev->ibuf.w.queued) 561 iev->events |= EV_WRITE; 562 563 event_del(&iev->ev); 564 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 565 event_add(&iev->ev, NULL); 566 } 567 568 int 569 imsg_compose_event(struct imsgev *iev, u_int16_t type, 570 u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) 571 { 572 int ret; 573 574 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 575 pid, fd, data, datalen)) != -1) 576 imsg_event_add(iev); 577 return (ret); 578 } 579