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