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