1 /* $OpenBSD: ripe.c,v 1.31 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 <netinet/in.h> 26 #include <arpa/inet.h> 27 #include <net/if_types.h> 28 #include <stdlib.h> 29 #include <signal.h> 30 #include <string.h> 31 #include <fcntl.h> 32 #include <pwd.h> 33 #include <unistd.h> 34 #include <event.h> 35 #include <err.h> 36 #include <errno.h> 37 #include <stdio.h> 38 39 #include "ripd.h" 40 #include "rip.h" 41 #include "ripe.h" 42 #include "log.h" 43 #include "control.h" 44 45 void ripe_sig_handler(int, short, void *); 46 __dead void ripe_shutdown(void); 47 48 struct ripd_conf *oeconf = NULL; 49 static struct imsgev *iev_main; 50 static struct imsgev *iev_rde; 51 52 void 53 ripe_sig_handler(int sig, short event, void *bula) 54 { 55 switch (sig) { 56 case SIGINT: 57 case SIGTERM: 58 ripe_shutdown(); 59 /* NOTREACHED */ 60 default: 61 fatalx("unexpected signal"); 62 } 63 } 64 65 /* rip engine */ 66 pid_t 67 ripe(struct ripd_conf *xconf, int pipe_parent2ripe[2], int pipe_ripe2rde[2], 68 int pipe_parent2rde[2]) 69 { 70 struct event ev_sigint, ev_sigterm; 71 struct sockaddr_in addr; 72 struct iface *iface = NULL; 73 struct passwd *pw; 74 struct redistribute *r; 75 pid_t pid; 76 77 switch (pid = fork()) { 78 case -1: 79 fatal("cannot fork"); 80 case 0: 81 break; 82 default: 83 return (pid); 84 } 85 86 /* create ripd control socket outside chroot */ 87 if (control_init(xconf->csock) == -1) 88 fatalx("control socket setup failed"); 89 90 addr.sin_family = AF_INET; 91 addr.sin_port = htons(RIP_PORT); 92 addr.sin_addr.s_addr = INADDR_ANY; 93 94 if ((xconf->rip_socket = socket(AF_INET, 95 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 96 IPPROTO_UDP)) == -1) 97 fatalx("error creating socket"); 98 99 if (bind(xconf->rip_socket, (struct sockaddr *)&addr, 100 sizeof(addr)) == -1) 101 fatal("error binding socket"); 102 103 /* set some defaults */ 104 if (if_set_opt(xconf->rip_socket) == -1) 105 fatal("if_set_opt"); 106 107 if (if_set_mcast_ttl(xconf->rip_socket, IP_DEFAULT_MULTICAST_TTL) == -1) 108 fatal("if_set_mcast_ttl"); 109 110 if (if_set_mcast_loop(xconf->rip_socket) == -1) 111 fatal("if_set_mcast_loop"); 112 113 if (if_set_tos(xconf->rip_socket, IPTOS_PREC_INTERNETCONTROL) == -1) 114 fatal("if_set_tos"); 115 116 if_set_recvbuf(xconf->rip_socket); 117 118 oeconf = xconf; 119 120 if ((pw = getpwnam(RIPD_USER)) == NULL) 121 fatal("getpwnam"); 122 123 if (chroot(pw->pw_dir) == -1) 124 fatal("chroot"); 125 if (chdir("/") == -1) 126 fatal("chdir(\"/\")"); 127 128 setproctitle("rip engine"); 129 log_procname = "ripe"; 130 131 if (setgroups(1, &pw->pw_gid) || 132 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 133 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 134 fatal("can't drop privileges"); 135 136 event_init(); 137 nbr_init(NBR_HASHSIZE); 138 139 /* setup signal handler */ 140 signal_set(&ev_sigint, SIGINT, ripe_sig_handler, NULL); 141 signal_set(&ev_sigterm, SIGTERM, ripe_sig_handler, NULL); 142 signal_add(&ev_sigint, NULL); 143 signal_add(&ev_sigterm, NULL); 144 signal(SIGPIPE, SIG_IGN); 145 signal(SIGHUP, SIG_IGN); 146 147 /* setup pipes */ 148 close(pipe_parent2ripe[0]); 149 close(pipe_ripe2rde[1]); 150 close(pipe_parent2rde[0]); 151 close(pipe_parent2rde[1]); 152 153 if ((iev_rde = malloc(sizeof(struct imsgev))) == NULL || 154 (iev_main = malloc(sizeof(struct imsgev))) == NULL) 155 fatal(NULL); 156 imsg_init(&iev_rde->ibuf, pipe_ripe2rde[0]); 157 iev_rde->handler = ripe_dispatch_rde; 158 imsg_init(&iev_main->ibuf, pipe_parent2ripe[1]); 159 iev_main->handler = ripe_dispatch_main; 160 161 /* setup event handler */ 162 iev_rde->events = EV_READ; 163 event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events, 164 iev_rde->handler, iev_rde); 165 event_add(&iev_rde->ev, NULL); 166 167 iev_main->events = EV_READ; 168 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 169 iev_main->handler, iev_main); 170 event_add(&iev_main->ev, NULL); 171 172 event_set(&oeconf->ev, oeconf->rip_socket, EV_READ|EV_PERSIST, 173 recv_packet, oeconf); 174 event_add(&oeconf->ev, NULL); 175 176 /* remove unneeded config stuff */ 177 while ((r = SIMPLEQ_FIRST(&oeconf->redist_list)) != NULL) { 178 SIMPLEQ_REMOVE_HEAD(&oeconf->redist_list, entry); 179 free(r); 180 } 181 182 /* listen on ripd control socket */ 183 control_listen(); 184 185 /* start interfaces */ 186 LIST_FOREACH(iface, &xconf->iface_list, entry) { 187 if_init(xconf, iface); 188 if (if_fsm(iface, IF_EVT_UP)) 189 log_debug("ripe: error starting interface: %s", 190 iface->name); 191 } 192 193 if (pledge("stdio inet mcast", NULL) == -1) 194 fatal("pledge"); 195 196 evtimer_set(&oeconf->report_timer, report_timer, oeconf); 197 start_report_timer(); 198 199 ripe_imsg_compose_rde(IMSG_FULL_REQUEST, 0, 0, NULL, 0); 200 201 event_dispatch(); 202 203 ripe_shutdown(); 204 /* NOTREACHED */ 205 return (0); 206 } 207 208 int 209 ripe_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen) 210 { 211 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); 212 } 213 214 int 215 ripe_imsg_compose_rde(int type, u_int32_t peerid, pid_t pid, 216 void *data, u_int16_t datalen) 217 { 218 return (imsg_compose_event(iev_rde, type, peerid, pid, -1, 219 data, datalen)); 220 } 221 222 void 223 ripe_dispatch_main(int fd, short event, void *bula) 224 { 225 struct imsg imsg; 226 struct imsgev *iev = bula; 227 struct imsgbuf *ibuf = &iev->ibuf; 228 struct kif *kif; 229 struct iface *iface; 230 ssize_t n; 231 int link_ok, shut = 0; 232 233 if (event & EV_READ) { 234 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 235 fatal("imsg_read error"); 236 if (n == 0) /* connection closed */ 237 shut = 1; 238 } 239 if (event & EV_WRITE) { 240 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 241 fatal("msgbuf_write"); 242 if (n == 0) /* connection closed */ 243 shut = 1; 244 } 245 246 for (;;) { 247 if ((n = imsg_get(ibuf, &imsg)) == -1) 248 fatal("ripe_dispatch_main: imsg_get error"); 249 if (n == 0) 250 break; 251 252 switch (imsg.hdr.type) { 253 case IMSG_IFINFO: 254 if (imsg.hdr.len - IMSG_HEADER_SIZE != 255 sizeof(struct kif)) 256 fatalx("IFINFO imsg with wrong len"); 257 kif = imsg.data; 258 link_ok = (kif->flags & IFF_UP) && 259 LINK_STATE_IS_UP(kif->link_state); 260 261 LIST_FOREACH(iface, &oeconf->iface_list, entry) { 262 if (kif->ifindex == iface->ifindex) { 263 iface->flags = kif->flags; 264 iface->linkstate = kif->link_state; 265 266 if (link_ok) { 267 if_fsm(iface, IF_EVT_UP); 268 log_warnx("interface %s up", 269 iface->name); 270 } else { 271 if_fsm(iface, IF_EVT_DOWN); 272 log_warnx("interface %s down", 273 iface->name); 274 } 275 } 276 } 277 break; 278 case IMSG_CTL_IFINFO: 279 case IMSG_CTL_KROUTE: 280 case IMSG_CTL_KROUTE_ADDR: 281 case IMSG_CTL_END: 282 control_imsg_relay(&imsg); 283 break; 284 default: 285 log_debug("ripe_dispatch_main: error handling imsg %d", 286 imsg.hdr.type); 287 break; 288 } 289 imsg_free(&imsg); 290 } 291 if (!shut) 292 imsg_event_add(iev); 293 else { 294 /* this pipe is dead, so remove the event handler */ 295 event_del(&iev->ev); 296 event_loopexit(NULL); 297 } 298 } 299 300 void 301 ripe_dispatch_rde(int fd, short event, void *bula) 302 { 303 struct rip_route *rr; 304 struct imsg imsg; 305 struct imsgev *iev = bula; 306 struct imsgbuf *ibuf = &iev->ibuf; 307 struct iface *iface; 308 struct nbr *nbr; 309 ssize_t n; 310 int shut = 0; 311 312 if (event & EV_READ) { 313 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 314 fatal("imsg_read error"); 315 if (n == 0) /* connection closed */ 316 shut = 1; 317 } 318 if (event & EV_WRITE) { 319 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 320 fatal("msgbuf_write"); 321 if (n == 0) /* connection closed */ 322 shut = 1; 323 } 324 325 for (;;) { 326 if ((n = imsg_get(ibuf, &imsg)) == -1) 327 fatal("ripe_dispatch_rde: imsg_get error"); 328 if (n == 0) 329 break; 330 331 switch (imsg.hdr.type) { 332 case IMSG_REQUEST_ADD: 333 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(*rr)) 334 fatalx("invalid size of RDE request"); 335 336 if ((rr = malloc(sizeof(*rr))) == NULL) 337 fatal("ripe_dispatch_rde"); 338 339 memcpy(rr, imsg.data, sizeof(*rr)); 340 341 if (imsg.hdr.peerid != 0) { 342 if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == 343 NULL) { 344 log_debug("unknown neighbor id %u", 345 imsg.hdr.peerid); 346 free(rr); 347 break; 348 } 349 add_entry(&nbr->rq_list, rr); 350 break; 351 } 352 353 LIST_FOREACH(iface, &oeconf->iface_list, entry) { 354 add_entry(&iface->rq_list, rr); 355 } 356 break; 357 case IMSG_SEND_REQUEST: 358 if (imsg.hdr.peerid != 0) { 359 if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == 360 NULL) { 361 log_debug("unknown neighbor id %u", 362 imsg.hdr.peerid); 363 break; 364 } 365 send_request(&nbr->rq_list, NULL, nbr); 366 break; 367 } 368 369 LIST_FOREACH(iface, &oeconf->iface_list, entry) { 370 send_request(&iface->rq_list, iface, NULL); 371 } 372 break; 373 case IMSG_RESPONSE_ADD: 374 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(*rr)) 375 fatalx("invalid size of RDE request"); 376 377 if ((rr = malloc(sizeof(*rr))) == NULL) 378 fatal("ripe_dispatch_rde"); 379 380 memcpy(rr, imsg.data, sizeof(*rr)); 381 382 if (imsg.hdr.peerid == 0) { 383 LIST_FOREACH(iface, &oeconf->iface_list, entry) 384 add_entry(&iface->rp_list, rr); 385 386 break; 387 } 388 389 if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == NULL) { 390 log_debug("unknown neighbor id %u", 391 imsg.hdr.peerid); 392 free(rr); 393 break; 394 } 395 add_entry(&nbr->rp_list, rr); 396 397 break; 398 case IMSG_SEND_RESPONSE: 399 if (imsg.hdr.peerid == 0) { 400 LIST_FOREACH(iface, &oeconf->iface_list, 401 entry) { 402 send_response(&iface->rp_list, 403 iface, NULL); 404 } 405 break; 406 } 407 408 if ((nbr = nbr_find_peerid(imsg.hdr.peerid)) == NULL) { 409 log_debug("unknown neighbor id %u", 410 imsg.hdr.peerid); 411 break; 412 } 413 send_response(&nbr->rp_list, NULL, nbr); 414 nbr_fsm(nbr, NBR_EVT_RESPONSE_SENT); 415 break; 416 case IMSG_SEND_TRIGGERED_UPDATE: 417 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(struct 418 rip_route)) 419 fatalx("invalid size of RDE request"); 420 421 rr = imsg.data; 422 423 LIST_FOREACH(iface, &oeconf->iface_list, 424 entry) { 425 if (rr->ifindex != iface->ifindex) 426 send_triggered_update(iface, rr); 427 } 428 break; 429 case IMSG_CTL_END: 430 case IMSG_CTL_SHOW_RIB: 431 control_imsg_relay(&imsg); 432 break; 433 default: 434 log_debug("ripe_dispatch_rde: error handling imsg %d", 435 imsg.hdr.type); 436 break; 437 } 438 imsg_free(&imsg); 439 } 440 if (!shut) 441 imsg_event_add(iev); 442 else { 443 /* this pipe is dead, so remove the event handler */ 444 event_del(&iev->ev); 445 event_loopexit(NULL); 446 } 447 } 448 449 __dead void 450 ripe_shutdown(void) 451 { 452 struct iface *iface; 453 454 /* close pipes */ 455 msgbuf_write(&iev_rde->ibuf.w); 456 msgbuf_clear(&iev_rde->ibuf.w); 457 close(iev_rde->ibuf.fd); 458 msgbuf_write(&iev_main->ibuf.w); 459 msgbuf_clear(&iev_main->ibuf.w); 460 close(iev_main->ibuf.fd); 461 462 LIST_FOREACH(iface, &oeconf->iface_list, entry) { 463 if (if_fsm(iface, IF_EVT_DOWN)) { 464 log_debug("error stopping interface %s", 465 iface->name); 466 } 467 } 468 while ((iface = LIST_FIRST(&oeconf->iface_list)) != NULL) { 469 LIST_REMOVE(iface, entry); 470 471 /* revert the demotion when the interface is deleted */ 472 if (iface->state == IF_STA_DOWN) 473 ripe_demote_iface(iface, 1); 474 475 if_del(iface); 476 } 477 478 close(oeconf->rip_socket); 479 480 /* clean up */ 481 free(iev_rde); 482 free(iev_main); 483 free(oeconf); 484 485 log_info("rip engine exiting"); 486 _exit(0); 487 } 488 489 void 490 ripe_iface_ctl(struct ctl_conn *c, unsigned int idx) 491 { 492 struct iface *iface; 493 struct ctl_iface *ictl; 494 495 LIST_FOREACH(iface, &oeconf->iface_list, entry) { 496 if (idx == 0 || idx == iface->ifindex) { 497 ictl = if_to_ctl(iface); 498 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_IFACE, 499 0, 0, -1, ictl, sizeof(struct ctl_iface)); 500 } 501 } 502 } 503 504 void 505 ripe_nbr_ctl(struct ctl_conn *c) 506 { 507 struct iface *iface; 508 struct nbr *nbr; 509 struct ctl_nbr *nctl; 510 511 LIST_FOREACH(iface, &oeconf->iface_list, entry) 512 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 513 nctl = nbr_to_ctl(nbr); 514 imsg_compose_event(&c->iev, 515 IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, 516 sizeof(struct ctl_nbr)); 517 } 518 519 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); 520 } 521 522 void 523 ripe_demote_iface(struct iface *iface, int active) 524 { 525 struct demote_msg dmsg; 526 527 if (iface->demote_group[0] == '\0') 528 return; 529 530 bzero(&dmsg, sizeof(dmsg)); 531 strlcpy(dmsg.demote_group, iface->demote_group, 532 sizeof(dmsg.demote_group)); 533 if (active) 534 dmsg.level = -1; 535 else 536 dmsg.level = 1; 537 538 ripe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg)); 539 } 540