1 /* $OpenBSD: ripd.c,v 1.23 2014/07/12 20:16:38 krw 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 ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 357 fatal("msgbuf_write"); 358 if (n == 0) /* connection closed */ 359 shut = 1; 360 } 361 362 for (;;) { 363 if ((n = imsg_get(ibuf, &imsg)) == -1) 364 fatal("imsg_get"); 365 366 if (n == 0) 367 break; 368 369 switch (imsg.hdr.type) { 370 case IMSG_CTL_RELOAD: 371 /* XXX reconfig */ 372 break; 373 case IMSG_CTL_FIB_COUPLE: 374 kr_fib_couple(); 375 break; 376 case IMSG_CTL_FIB_DECOUPLE: 377 kr_fib_decouple(); 378 break; 379 case IMSG_CTL_KROUTE: 380 case IMSG_CTL_KROUTE_ADDR: 381 kr_show_route(&imsg); 382 break; 383 case IMSG_CTL_IFINFO: 384 if (imsg.hdr.len == IMSG_HEADER_SIZE) 385 kr_ifinfo(NULL, imsg.hdr.pid); 386 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 387 kr_ifinfo(imsg.data, imsg.hdr.pid); 388 else 389 log_warnx("IFINFO request with wrong len"); 390 break; 391 case IMSG_DEMOTE: 392 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(dmsg)) 393 fatalx("invalid size of OE request"); 394 memcpy(&dmsg, imsg.data, sizeof(dmsg)); 395 carp_demote_set(dmsg.demote_group, dmsg.level); 396 break; 397 case IMSG_CTL_LOG_VERBOSE: 398 /* already checked by ripe */ 399 memcpy(&verbose, imsg.data, sizeof(verbose)); 400 log_verbose(verbose); 401 break; 402 default: 403 log_debug("main_dispatch_ripe: error handling imsg %d", 404 imsg.hdr.type); 405 break; 406 } 407 imsg_free(&imsg); 408 } 409 if (!shut) 410 imsg_event_add(iev); 411 else { 412 /* this pipe is dead, so remove the event handler */ 413 event_del(&iev->ev); 414 event_loopexit(NULL); 415 } 416 } 417 418 /* ARGSUSED */ 419 void 420 main_dispatch_rde(int fd, short event, void *bula) 421 { 422 struct imsgev *iev = bula; 423 struct imsgbuf *ibuf = &iev->ibuf; 424 struct imsg imsg; 425 ssize_t n; 426 int shut = 0; 427 428 if (event & EV_READ) { 429 if ((n = imsg_read(ibuf)) == -1) 430 fatal("imsg_read error"); 431 if (n == 0) /* connection closed */ 432 shut = 1; 433 } 434 if (event & EV_WRITE) { 435 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 436 fatal("msgbuf_write"); 437 if (n == 0) /* connection closed */ 438 shut = 1; 439 } 440 441 for (;;) { 442 if ((n = imsg_get(ibuf, &imsg)) == -1) 443 fatal("imsg_get"); 444 445 if (n == 0) 446 break; 447 448 switch (imsg.hdr.type) { 449 case IMSG_KROUTE_CHANGE: 450 if (kr_change(imsg.data)) 451 log_warn("main_dispatch_rde: error changing " 452 "route"); 453 break; 454 case IMSG_KROUTE_DELETE: 455 if (kr_delete(imsg.data)) 456 log_warn("main_dispatch_rde: error deleting " 457 "route"); 458 break; 459 default: 460 log_debug("main_dispatch_rde: error handling imsg %d", 461 imsg.hdr.type); 462 break; 463 } 464 imsg_free(&imsg); 465 } 466 if (!shut) 467 imsg_event_add(iev); 468 else { 469 /* this pipe is dead, so remove the event handler */ 470 event_del(&iev->ev); 471 event_loopexit(NULL); 472 } 473 } 474 475 void 476 main_imsg_compose_ripe(int type, pid_t pid, void *data, u_int16_t datalen) 477 { 478 imsg_compose_event(iev_ripe, type, 0, pid, -1, data, datalen); 479 } 480 481 void 482 main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) 483 { 484 imsg_compose_event(iev_rde, type, 0, pid, -1, data, datalen); 485 } 486 487 int 488 rip_redistribute(struct kroute *kr) 489 { 490 struct redistribute *r; 491 u_int8_t is_default = 0; 492 493 if (kr->flags & F_RIPD_INSERTED) 494 return (1); 495 496 /* only allow 0.0.0.0/0 via REDIST_DEFAULT */ 497 if (kr->prefix.s_addr == INADDR_ANY && kr->netmask.s_addr == INADDR_ANY) 498 is_default = 1; 499 500 SIMPLEQ_FOREACH(r, &conf->redist_list, entry) { 501 switch (r->type & ~REDIST_NO) { 502 case REDIST_LABEL: 503 if (kr->rtlabel == r->label) 504 return (r->type & REDIST_NO ? 0 : 1); 505 break; 506 case REDIST_STATIC: 507 /* 508 * Dynamic routes are not redistributable. Placed here 509 * so that link local addresses can be redistributed 510 * via a rtlabel. 511 */ 512 if (is_default) 513 continue; 514 if (kr->flags & F_DYNAMIC) 515 continue; 516 if (kr->flags & F_STATIC) 517 return (r->type & REDIST_NO ? 0 : 1); 518 break; 519 case REDIST_CONNECTED: 520 if (is_default) 521 continue; 522 if (kr->flags & F_DYNAMIC) 523 continue; 524 if (kr->flags & F_CONNECTED) 525 return (r->type & REDIST_NO ? 0 : 1); 526 break; 527 case REDIST_ADDR: 528 if (kr->flags & F_DYNAMIC) 529 continue; 530 531 if (r->addr.s_addr == INADDR_ANY && 532 r->mask.s_addr == INADDR_ANY) { 533 if (is_default) 534 return (r->type & REDIST_NO? 0 : 1); 535 else 536 return (0); 537 } 538 539 if ((kr->prefix.s_addr & r->mask.s_addr) == 540 (r->addr.s_addr & r->mask.s_addr) && 541 (kr->netmask.s_addr & r->mask.s_addr) == 542 r->mask.s_addr) 543 return (r->type & REDIST_NO? 0 : 1); 544 break; 545 case REDIST_DEFAULT: 546 if (is_default) 547 return (r->type & REDIST_NO? 0 : 1); 548 break; 549 } 550 } 551 552 return (0); 553 } 554 555 void 556 imsg_event_add(struct imsgev *iev) 557 { 558 if (iev->handler == NULL) { 559 imsg_flush(&iev->ibuf); 560 return; 561 } 562 563 iev->events = EV_READ; 564 if (iev->ibuf.w.queued) 565 iev->events |= EV_WRITE; 566 567 event_del(&iev->ev); 568 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 569 event_add(&iev->ev, NULL); 570 } 571 572 int 573 imsg_compose_event(struct imsgev *iev, u_int16_t type, 574 u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) 575 { 576 int ret; 577 578 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 579 pid, fd, data, datalen)) != -1) 580 imsg_event_add(iev); 581 return (ret); 582 } 583