1 /* $OpenBSD: ospfe.c,v 1.120 2024/11/21 13:38:14 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 6 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/types.h> 22 #include <sys/socket.h> 23 #include <sys/queue.h> 24 #include <netinet/in.h> 25 #include <arpa/inet.h> 26 #include <net/if_types.h> 27 #include <stdlib.h> 28 #include <signal.h> 29 #include <string.h> 30 #include <fcntl.h> 31 #include <pwd.h> 32 #include <unistd.h> 33 #include <event.h> 34 #include <err.h> 35 #include <errno.h> 36 #include <stdio.h> 37 38 #include "ospf.h" 39 #include "ospfd.h" 40 #include "ospfe.h" 41 #include "rde.h" 42 #include "control.h" 43 #include "log.h" 44 45 void ospfe_sig_handler(int, short, void *); 46 __dead void ospfe_shutdown(void); 47 void orig_rtr_lsa_all(struct area *); 48 struct iface *find_vlink(struct abr_rtr *); 49 50 struct ospfd_conf *oeconf = NULL, *noeconf; 51 static struct imsgev *iev_main; 52 static struct imsgev *iev_rde; 53 int oe_nofib; 54 55 void 56 ospfe_sig_handler(int sig, short event, void *bula) 57 { 58 switch (sig) { 59 case SIGINT: 60 case SIGTERM: 61 ospfe_shutdown(); 62 /* NOTREACHED */ 63 default: 64 fatalx("unexpected signal"); 65 } 66 } 67 68 /* ospf engine */ 69 pid_t 70 ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], 71 int pipe_parent2rde[2]) 72 { 73 struct area *area; 74 struct iface *iface; 75 struct redistribute *r; 76 struct passwd *pw; 77 struct event ev_sigint, ev_sigterm; 78 pid_t pid; 79 80 switch (pid = fork()) { 81 case -1: 82 fatal("cannot fork"); 83 case 0: 84 break; 85 default: 86 return (pid); 87 } 88 89 /* cleanup a bit */ 90 kif_clear(); 91 92 /* create the raw ip socket */ 93 if ((xconf->ospf_socket = socket(AF_INET, 94 SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 95 IPPROTO_OSPF)) == -1) 96 fatal("error creating raw socket"); 97 98 /* set some defaults */ 99 if (if_set_mcast_loop(xconf->ospf_socket) == -1) 100 fatal("if_set_mcast_loop"); 101 if (if_set_ip_hdrincl(xconf->ospf_socket) == -1) 102 fatal("if_set_ip_hdrincl"); 103 if (if_set_recvif(xconf->ospf_socket, 1) == -1) 104 fatal("if_set_recvif"); 105 if_set_sockbuf(xconf->ospf_socket); 106 107 oeconf = xconf; 108 if (oeconf->flags & OSPFD_FLAG_NO_FIB_UPDATE) 109 oe_nofib = 1; 110 111 if ((pw = getpwnam(OSPFD_USER)) == NULL) 112 fatal("getpwnam"); 113 114 if (chroot(pw->pw_dir) == -1) 115 fatal("chroot"); 116 if (chdir("/") == -1) 117 fatal("chdir(\"/\")"); 118 119 setproctitle("ospf engine"); 120 /* 121 * XXX needed with fork+exec 122 * log_init(debug, LOG_DAEMON); 123 * log_setverbose(verbose); 124 */ 125 126 ospfd_process = PROC_OSPF_ENGINE; 127 log_procinit(log_procnames[ospfd_process]); 128 129 if (setgroups(1, &pw->pw_gid) || 130 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 131 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 132 fatal("can't drop privileges"); 133 134 if (pledge("stdio inet mcast recvfd", NULL) == -1) 135 fatal("pledge"); 136 137 event_init(); 138 nbr_init(NBR_HASHSIZE); 139 lsa_cache_init(LSA_HASHSIZE); 140 141 /* setup signal handler */ 142 signal_set(&ev_sigint, SIGINT, ospfe_sig_handler, NULL); 143 signal_set(&ev_sigterm, SIGTERM, ospfe_sig_handler, NULL); 144 signal_add(&ev_sigint, NULL); 145 signal_add(&ev_sigterm, NULL); 146 signal(SIGPIPE, SIG_IGN); 147 signal(SIGHUP, SIG_IGN); 148 149 /* setup pipes */ 150 close(pipe_parent2ospfe[0]); 151 close(pipe_ospfe2rde[1]); 152 close(pipe_parent2rde[0]); 153 close(pipe_parent2rde[1]); 154 155 if ((iev_rde = malloc(sizeof(struct imsgev))) == NULL || 156 (iev_main = malloc(sizeof(struct imsgev))) == NULL) 157 fatal(NULL); 158 if (imsgbuf_init(&iev_rde->ibuf, pipe_ospfe2rde[0]) == -1) 159 fatal(NULL); 160 iev_rde->handler = ospfe_dispatch_rde; 161 if (imsgbuf_init(&iev_main->ibuf, pipe_parent2ospfe[1]) == -1) 162 fatal(NULL); 163 imsgbuf_allow_fdpass(&iev_main->ibuf); 164 iev_main->handler = ospfe_dispatch_main; 165 166 /* setup event handler */ 167 iev_rde->events = EV_READ; 168 event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events, 169 iev_rde->handler, iev_rde); 170 event_add(&iev_rde->ev, NULL); 171 172 iev_main->events = EV_READ; 173 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 174 iev_main->handler, iev_main); 175 event_add(&iev_main->ev, NULL); 176 177 event_set(&oeconf->ev, oeconf->ospf_socket, EV_READ|EV_PERSIST, 178 recv_packet, oeconf); 179 event_add(&oeconf->ev, NULL); 180 181 /* remove unneeded config stuff */ 182 conf_clear_redist_list(&oeconf->redist_list); 183 LIST_FOREACH(area, &oeconf->area_list, entry) { 184 while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) { 185 SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry); 186 free(r); 187 } 188 } 189 190 /* start interfaces */ 191 LIST_FOREACH(area, &oeconf->area_list, entry) { 192 ospfe_demote_area(area, 0); 193 LIST_FOREACH(iface, &area->iface_list, entry) { 194 if_init(xconf, iface); 195 if (if_fsm(iface, IF_EVT_UP)) { 196 log_debug("error starting interface %s", 197 iface->name); 198 } 199 } 200 } 201 202 event_dispatch(); 203 204 ospfe_shutdown(); 205 /* NOTREACHED */ 206 return (0); 207 } 208 209 __dead void 210 ospfe_shutdown(void) 211 { 212 struct area *area; 213 struct iface *iface; 214 215 /* close pipes */ 216 imsgbuf_write(&iev_rde->ibuf); 217 imsgbuf_clear(&iev_rde->ibuf); 218 close(iev_rde->ibuf.fd); 219 imsgbuf_write(&iev_main->ibuf); 220 imsgbuf_clear(&iev_main->ibuf); 221 close(iev_main->ibuf.fd); 222 223 /* stop all interfaces and remove all areas */ 224 while ((area = LIST_FIRST(&oeconf->area_list)) != NULL) { 225 LIST_FOREACH(iface, &area->iface_list, entry) { 226 if (if_fsm(iface, IF_EVT_DOWN)) { 227 log_debug("error stopping interface %s", 228 iface->name); 229 } 230 } 231 LIST_REMOVE(area, entry); 232 area_del(area); 233 } 234 235 nbr_del(nbr_find_peerid(NBR_IDSELF)); 236 close(oeconf->ospf_socket); 237 238 /* clean up */ 239 free(iev_rde); 240 free(iev_main); 241 free(oeconf); 242 243 log_info("ospf engine exiting"); 244 _exit(0); 245 } 246 247 /* imesg */ 248 int 249 ospfe_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen) 250 { 251 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); 252 } 253 254 int 255 ospfe_imsg_compose_rde(int type, u_int32_t peerid, pid_t pid, 256 void *data, u_int16_t datalen) 257 { 258 return (imsg_compose_event(iev_rde, type, peerid, pid, -1, 259 data, datalen)); 260 } 261 262 void 263 ospfe_dispatch_main(int fd, short event, void *bula) 264 { 265 static struct area *narea; 266 static struct iface *niface; 267 struct ifaddrchange *ifc; 268 struct imsg imsg; 269 struct imsgev *iev = bula; 270 struct imsgbuf *ibuf = &iev->ibuf; 271 struct area *area = NULL; 272 struct iface *iface = NULL; 273 struct kif *kif; 274 struct auth_md md; 275 int n, link_ok, stub_changed, shut = 0; 276 277 if (event & EV_READ) { 278 if ((n = imsgbuf_read(ibuf)) == -1) 279 fatal("imsgbuf_read error"); 280 if (n == 0) /* connection closed */ 281 shut = 1; 282 } 283 if (event & EV_WRITE) { 284 if (imsgbuf_write(ibuf) == -1) { 285 if (errno == EPIPE) /* connection closed */ 286 shut = 1; 287 else 288 fatal("imsgbuf_write"); 289 } 290 } 291 292 for (;;) { 293 if ((n = imsg_get(ibuf, &imsg)) == -1) 294 fatal("ospfe_dispatch_main: imsg_get error"); 295 if (n == 0) 296 break; 297 298 switch (imsg.hdr.type) { 299 case IMSG_IFINFO: 300 if (imsg.hdr.len != IMSG_HEADER_SIZE + 301 sizeof(struct kif)) 302 fatalx("IFINFO imsg with wrong len"); 303 kif = imsg.data; 304 link_ok = (kif->flags & IFF_UP) && 305 LINK_STATE_IS_UP(kif->link_state); 306 307 LIST_FOREACH(area, &oeconf->area_list, entry) { 308 LIST_FOREACH(iface, &area->iface_list, entry) { 309 if (kif->ifindex == iface->ifindex && 310 iface->type != 311 IF_TYPE_VIRTUALLINK) { 312 int prev_link_state = 313 (iface->flags & IFF_UP) && 314 LINK_STATE_IS_UP(iface->linkstate); 315 316 iface->flags = kif->flags; 317 iface->linkstate = 318 kif->link_state; 319 iface->mtu = kif->mtu; 320 321 if (link_ok == prev_link_state) 322 break; 323 324 if (link_ok) { 325 if_fsm(iface, 326 IF_EVT_UP); 327 log_warnx("interface %s" 328 " up", iface->name); 329 } else { 330 if_fsm(iface, 331 IF_EVT_DOWN); 332 log_warnx("interface %s" 333 " down", 334 iface->name); 335 } 336 } 337 if (strcmp(kif->ifname, 338 iface->dependon) == 0) { 339 log_warnx("interface %s" 340 " changed state, %s" 341 " depends on it", 342 kif->ifname, 343 iface->name); 344 iface->depend_ok = 345 ifstate_is_up(kif); 346 347 if ((iface->flags & 348 IFF_UP) && 349 LINK_STATE_IS_UP(iface->linkstate)) 350 orig_rtr_lsa(iface->area); 351 } 352 } 353 } 354 break; 355 case IMSG_IFADDRADD: 356 if (imsg.hdr.len != IMSG_HEADER_SIZE + 357 sizeof(struct ifaddrchange)) 358 fatalx("IFADDRADD imsg with wrong len"); 359 ifc = imsg.data; 360 361 LIST_FOREACH(area, &oeconf->area_list, entry) { 362 LIST_FOREACH(iface, &area->iface_list, entry) { 363 if (ifc->ifindex == iface->ifindex && 364 ifc->addr.s_addr == 365 iface->addr.s_addr) { 366 iface->mask = ifc->mask; 367 iface->dst = ifc->dst; 368 /* 369 * Previous down event might 370 * have failed if the address 371 * was not present at that 372 * time. 373 */ 374 if_fsm(iface, IF_EVT_DOWN); 375 if_fsm(iface, IF_EVT_UP); 376 log_warnx("interface %s:%s " 377 "returned", iface->name, 378 inet_ntoa(iface->addr)); 379 break; 380 } 381 } 382 } 383 break; 384 case IMSG_IFADDRDEL: 385 if (imsg.hdr.len != IMSG_HEADER_SIZE + 386 sizeof(struct ifaddrchange)) 387 fatalx("IFADDRDEL imsg with wrong len"); 388 ifc = imsg.data; 389 390 LIST_FOREACH(area, &oeconf->area_list, entry) { 391 LIST_FOREACH(iface, &area->iface_list, entry) { 392 if (ifc->ifindex == iface->ifindex && 393 ifc->addr.s_addr == 394 iface->addr.s_addr) { 395 if_fsm(iface, IF_EVT_DOWN); 396 log_warnx("interface %s:%s " 397 "gone", iface->name, 398 inet_ntoa(iface->addr)); 399 break; 400 } 401 } 402 } 403 break; 404 case IMSG_RECONF_CONF: 405 if ((noeconf = malloc(sizeof(struct ospfd_conf))) == 406 NULL) 407 fatal(NULL); 408 memcpy(noeconf, imsg.data, sizeof(struct ospfd_conf)); 409 410 LIST_INIT(&noeconf->area_list); 411 LIST_INIT(&noeconf->cand_list); 412 break; 413 case IMSG_RECONF_AREA: 414 if ((narea = area_new()) == NULL) 415 fatal(NULL); 416 memcpy(narea, imsg.data, sizeof(struct area)); 417 418 LIST_INIT(&narea->iface_list); 419 LIST_INIT(&narea->nbr_list); 420 RB_INIT(&narea->lsa_tree); 421 SIMPLEQ_INIT(&narea->redist_list); 422 423 LIST_INSERT_HEAD(&noeconf->area_list, narea, entry); 424 break; 425 case IMSG_RECONF_IFACE: 426 if ((niface = malloc(sizeof(struct iface))) == NULL) 427 fatal(NULL); 428 memcpy(niface, imsg.data, sizeof(struct iface)); 429 430 LIST_INIT(&niface->nbr_list); 431 TAILQ_INIT(&niface->ls_ack_list); 432 TAILQ_INIT(&niface->auth_md_list); 433 RB_INIT(&niface->lsa_tree); 434 435 niface->area = narea; 436 LIST_INSERT_HEAD(&narea->iface_list, niface, entry); 437 break; 438 case IMSG_RECONF_AUTHMD: 439 memcpy(&md, imsg.data, sizeof(struct auth_md)); 440 md_list_add(&niface->auth_md_list, md.keyid, md.key); 441 break; 442 case IMSG_RECONF_END: 443 if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER) != 444 (noeconf->flags & OSPFD_FLAG_STUB_ROUTER)) 445 stub_changed = 1; 446 else 447 stub_changed = 0; 448 merge_config(oeconf, noeconf); 449 noeconf = NULL; 450 if (stub_changed) 451 orig_rtr_lsa_all(NULL); 452 break; 453 case IMSG_CTL_KROUTE: 454 case IMSG_CTL_KROUTE_ADDR: 455 case IMSG_CTL_IFINFO: 456 case IMSG_CTL_END: 457 control_imsg_relay(&imsg); 458 break; 459 case IMSG_CONTROLFD: 460 if ((fd = imsg_get_fd(&imsg)) == -1) 461 fatalx("%s: expected to receive imsg control" 462 "fd but didn't receive any", __func__); 463 /* Listen on control socket. */ 464 control_listen(fd); 465 if (pledge("stdio inet mcast", NULL) == -1) 466 fatal("pledge"); 467 break; 468 default: 469 log_debug("ospfe_dispatch_main: error handling imsg %d", 470 imsg.hdr.type); 471 break; 472 } 473 imsg_free(&imsg); 474 } 475 if (!shut) 476 imsg_event_add(iev); 477 else { 478 /* this pipe is dead, so remove the event handler */ 479 event_del(&iev->ev); 480 event_loopexit(NULL); 481 } 482 } 483 484 void 485 ospfe_dispatch_rde(int fd, short event, void *bula) 486 { 487 struct lsa_hdr lsa_hdr; 488 struct imsgev *iev = bula; 489 struct imsgbuf *ibuf = &iev->ibuf; 490 struct nbr *nbr; 491 struct lsa_hdr *lhp; 492 struct lsa_ref *ref; 493 struct area *area; 494 struct iface *iface; 495 struct lsa_entry *le; 496 struct imsg imsg; 497 struct abr_rtr ar; 498 int n, noack = 0, shut = 0; 499 u_int16_t l, age; 500 501 if (event & EV_READ) { 502 if ((n = imsgbuf_read(ibuf)) == -1) 503 fatal("imsgbuf_read error"); 504 if (n == 0) /* connection closed */ 505 shut = 1; 506 } 507 if (event & EV_WRITE) { 508 if (imsgbuf_write(ibuf) == -1) { 509 if (errno == EPIPE) /* connection closed */ 510 shut = 1; 511 else 512 fatal("imsgbuf_write"); 513 } 514 } 515 516 for (;;) { 517 if ((n = imsg_get(ibuf, &imsg)) == -1) 518 fatal("ospfe_dispatch_rde: imsg_get error"); 519 if (n == 0) 520 break; 521 522 switch (imsg.hdr.type) { 523 case IMSG_DD: 524 nbr = nbr_find_peerid(imsg.hdr.peerid); 525 if (nbr == NULL) 526 break; 527 528 /* 529 * Ignore imsg when in the wrong state because a 530 * NBR_EVT_SEQ_NUM_MIS may have been issued in between. 531 * Luckily regetting the DB snapshot acts as a barrier 532 * for both state and process synchronisation. 533 */ 534 if ((nbr->state & NBR_STA_FLOOD) == 0) 535 break; 536 537 /* put these on my ls_req_list for retrieval */ 538 lhp = lsa_hdr_new(); 539 memcpy(lhp, imsg.data, sizeof(*lhp)); 540 ls_req_list_add(nbr, lhp); 541 break; 542 case IMSG_DD_END: 543 nbr = nbr_find_peerid(imsg.hdr.peerid); 544 if (nbr == NULL) 545 break; 546 547 /* see above */ 548 if ((nbr->state & NBR_STA_FLOOD) == 0) 549 break; 550 551 nbr->dd_pending--; 552 if (nbr->dd_pending == 0 && nbr->state & NBR_STA_LOAD) { 553 if (ls_req_list_empty(nbr)) 554 nbr_fsm(nbr, NBR_EVT_LOAD_DONE); 555 else 556 start_ls_req_tx_timer(nbr); 557 } 558 break; 559 case IMSG_DD_BADLSA: 560 nbr = nbr_find_peerid(imsg.hdr.peerid); 561 if (nbr == NULL) 562 break; 563 564 if (nbr->iface->self == nbr) 565 fatalx("ospfe_dispatch_rde: " 566 "dummy neighbor got BADREQ"); 567 568 nbr_fsm(nbr, NBR_EVT_SEQ_NUM_MIS); 569 break; 570 case IMSG_DB_SNAPSHOT: 571 nbr = nbr_find_peerid(imsg.hdr.peerid); 572 if (nbr == NULL) 573 break; 574 if (nbr->state != NBR_STA_SNAP) /* discard */ 575 break; 576 577 /* add LSA header to the neighbor db_sum_list */ 578 lhp = lsa_hdr_new(); 579 memcpy(lhp, imsg.data, sizeof(*lhp)); 580 db_sum_list_add(nbr, lhp); 581 break; 582 case IMSG_DB_END: 583 nbr = nbr_find_peerid(imsg.hdr.peerid); 584 if (nbr == NULL) 585 break; 586 587 nbr->dd_snapshot = 0; 588 if (nbr->state != NBR_STA_SNAP) 589 break; 590 591 /* snapshot done, start tx of dd packets */ 592 nbr_fsm(nbr, NBR_EVT_SNAP_DONE); 593 break; 594 case IMSG_LS_FLOOD: 595 nbr = nbr_find_peerid(imsg.hdr.peerid); 596 if (nbr == NULL) 597 break; 598 599 l = imsg.hdr.len - IMSG_HEADER_SIZE; 600 if (l < sizeof(lsa_hdr)) 601 fatalx("ospfe_dispatch_rde: " 602 "bad imsg size"); 603 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr)); 604 605 ref = lsa_cache_add(imsg.data, l); 606 607 if (lsa_hdr.type == LSA_TYPE_EXTERNAL) { 608 /* 609 * flood on all areas but stub areas and 610 * virtual links 611 */ 612 LIST_FOREACH(area, &oeconf->area_list, entry) { 613 if (area->stub) 614 continue; 615 LIST_FOREACH(iface, &area->iface_list, 616 entry) { 617 noack += lsa_flood(iface, nbr, 618 &lsa_hdr, imsg.data); 619 } 620 } 621 } else if (lsa_hdr.type == LSA_TYPE_LINK_OPAQ) { 622 /* 623 * Flood on interface only 624 */ 625 noack += lsa_flood(nbr->iface, nbr, 626 &lsa_hdr, imsg.data); 627 } else { 628 /* 629 * Flood on all area interfaces. For 630 * area 0.0.0.0 include the virtual links. 631 */ 632 area = nbr->iface->area; 633 LIST_FOREACH(iface, &area->iface_list, entry) { 634 noack += lsa_flood(iface, nbr, 635 &lsa_hdr, imsg.data); 636 } 637 /* XXX virtual links */ 638 } 639 640 /* remove from ls_req_list */ 641 le = ls_req_list_get(nbr, &lsa_hdr); 642 if (!(nbr->state & NBR_STA_FULL) && le != NULL) { 643 ls_req_list_free(nbr, le); 644 /* 645 * XXX no need to ack requested lsa 646 * the problem is that the RFC is very 647 * unclear about this. 648 */ 649 noack = 1; 650 } 651 652 if (!noack && nbr->iface != NULL && 653 nbr->iface->self != nbr) { 654 if (!(nbr->iface->state & IF_STA_BACKUP) || 655 nbr->iface->dr == nbr) { 656 /* delayed ack */ 657 lhp = lsa_hdr_new(); 658 memcpy(lhp, &lsa_hdr, sizeof(*lhp)); 659 ls_ack_list_add(nbr->iface, lhp); 660 } 661 } 662 663 lsa_cache_put(ref, nbr); 664 break; 665 case IMSG_LS_UPD: 666 case IMSG_LS_SNAP: 667 /* 668 * IMSG_LS_UPD is used in two cases: 669 * 1. as response to ls requests 670 * 2. as response to ls updates where the DB 671 * is newer then the sent LSA 672 * IMSG_LS_SNAP is used in one case: 673 * in EXSTART when the LSA has age MaxAge 674 */ 675 l = imsg.hdr.len - IMSG_HEADER_SIZE; 676 if (l < sizeof(lsa_hdr)) 677 fatalx("ospfe_dispatch_rde: " 678 "bad imsg size"); 679 680 nbr = nbr_find_peerid(imsg.hdr.peerid); 681 if (nbr == NULL) 682 break; 683 684 if (nbr->iface->self == nbr) 685 break; 686 687 if (imsg.hdr.type == IMSG_LS_SNAP && 688 nbr->state != NBR_STA_SNAP) 689 break; 690 691 memcpy(&age, imsg.data, sizeof(age)); 692 ref = lsa_cache_add(imsg.data, l); 693 if (ntohs(age) >= MAX_AGE) 694 /* add to retransmit list */ 695 ls_retrans_list_add(nbr, imsg.data, 0, 0); 696 else 697 ls_retrans_list_add(nbr, imsg.data, 0, 1); 698 699 lsa_cache_put(ref, nbr); 700 break; 701 case IMSG_LS_ACK: 702 /* 703 * IMSG_LS_ACK is used in two cases: 704 * 1. LSA was a duplicate 705 * 2. LS age is MaxAge and there is no current 706 * instance in the DB plus no neighbor in state 707 * Exchange or Loading 708 */ 709 nbr = nbr_find_peerid(imsg.hdr.peerid); 710 if (nbr == NULL) 711 break; 712 713 if (nbr->iface->self == nbr) 714 break; 715 716 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lsa_hdr)) 717 fatalx("ospfe_dispatch_rde: bad imsg size"); 718 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr)); 719 720 /* for case one check for implied acks */ 721 if (nbr->iface->state & IF_STA_DROTHER) 722 if (ls_retrans_list_del(nbr->iface->self, 723 &lsa_hdr) == 0) 724 break; 725 if (ls_retrans_list_del(nbr, &lsa_hdr) == 0) 726 break; 727 728 /* send a direct acknowledgement */ 729 send_direct_ack(nbr->iface, nbr->addr, imsg.data, 730 imsg.hdr.len - IMSG_HEADER_SIZE); 731 732 break; 733 case IMSG_LS_BADREQ: 734 nbr = nbr_find_peerid(imsg.hdr.peerid); 735 if (nbr == NULL) 736 break; 737 738 if (nbr->iface->self == nbr) 739 fatalx("ospfe_dispatch_rde: " 740 "dummy neighbor got BADREQ"); 741 742 nbr_fsm(nbr, NBR_EVT_BAD_LS_REQ); 743 break; 744 case IMSG_ABR_UP: 745 memcpy(&ar, imsg.data, sizeof(ar)); 746 747 if ((iface = find_vlink(&ar)) != NULL && 748 iface->state == IF_STA_DOWN) 749 if (if_fsm(iface, IF_EVT_UP)) { 750 log_debug("error starting interface %s", 751 iface->name); 752 } 753 break; 754 case IMSG_ABR_DOWN: 755 memcpy(&ar, imsg.data, sizeof(ar)); 756 757 if ((iface = find_vlink(&ar)) != NULL && 758 iface->state == IF_STA_POINTTOPOINT) 759 if (if_fsm(iface, IF_EVT_DOWN)) { 760 log_debug("error stopping interface %s", 761 iface->name); 762 } 763 break; 764 case IMSG_CTL_AREA: 765 case IMSG_CTL_IFACE: 766 case IMSG_CTL_END: 767 case IMSG_CTL_SHOW_DATABASE: 768 case IMSG_CTL_SHOW_DB_EXT: 769 case IMSG_CTL_SHOW_DB_NET: 770 case IMSG_CTL_SHOW_DB_RTR: 771 case IMSG_CTL_SHOW_DB_SELF: 772 case IMSG_CTL_SHOW_DB_SUM: 773 case IMSG_CTL_SHOW_DB_ASBR: 774 case IMSG_CTL_SHOW_DB_OPAQ: 775 case IMSG_CTL_SHOW_RIB: 776 case IMSG_CTL_SHOW_SUM: 777 case IMSG_CTL_SHOW_SUM_AREA: 778 control_imsg_relay(&imsg); 779 break; 780 default: 781 log_debug("ospfe_dispatch_rde: error handling imsg %d", 782 imsg.hdr.type); 783 break; 784 } 785 imsg_free(&imsg); 786 } 787 if (!shut) 788 imsg_event_add(iev); 789 else { 790 /* this pipe is dead, so remove the event handler */ 791 event_del(&iev->ev); 792 event_loopexit(NULL); 793 } 794 } 795 796 struct iface * 797 find_vlink(struct abr_rtr *ar) 798 { 799 struct area *area; 800 struct iface *iface = NULL; 801 802 LIST_FOREACH(area, &oeconf->area_list, entry) 803 LIST_FOREACH(iface, &area->iface_list, entry) 804 if (iface->abr_id.s_addr == ar->abr_id.s_addr && 805 iface->type == IF_TYPE_VIRTUALLINK && 806 iface->area->id.s_addr == ar->area.s_addr) { 807 iface->dst.s_addr = ar->dst_ip.s_addr; 808 iface->addr.s_addr = ar->addr.s_addr; 809 iface->metric = ar->metric; 810 811 return (iface); 812 } 813 814 return (iface); 815 } 816 817 void 818 orig_rtr_lsa_all(struct area *area) 819 { 820 struct area *a; 821 822 /* 823 * update all router LSA in all areas except area itself, 824 * as this update is already running. 825 */ 826 LIST_FOREACH(a, &oeconf->area_list, entry) 827 if (a != area) 828 orig_rtr_lsa(a); 829 } 830 831 void 832 orig_rtr_lsa(struct area *area) 833 { 834 struct lsa_hdr lsa_hdr; 835 struct lsa_rtr lsa_rtr; 836 struct lsa_rtr_link rtr_link; 837 struct iface *iface; 838 struct ibuf *buf; 839 struct nbr *nbr, *self = NULL; 840 u_int16_t num_links = 0; 841 u_int16_t chksum; 842 u_int8_t border, virtual = 0; 843 844 log_debug("orig_rtr_lsa: area %s", inet_ntoa(area->id)); 845 846 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), 847 IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) - 848 sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL) 849 fatal("orig_rtr_lsa"); 850 851 /* reserve space for LSA header and LSA Router header */ 852 if (ibuf_add_zero(buf, sizeof(lsa_hdr)) == -1) 853 fatal("orig_rtr_lsa: ibuf_add_zero failed"); 854 855 if (ibuf_add_zero(buf, sizeof(lsa_rtr)) == -1) 856 fatal("orig_rtr_lsa: ibuf_add_zero failed"); 857 858 /* links */ 859 LIST_FOREACH(iface, &area->iface_list, entry) { 860 if (self == NULL && iface->self != NULL) 861 self = iface->self; 862 863 bzero(&rtr_link, sizeof(rtr_link)); 864 865 if (iface->state & IF_STA_LOOPBACK) { 866 rtr_link.id = iface->addr.s_addr; 867 rtr_link.data = 0xffffffff; 868 rtr_link.type = LINK_TYPE_STUB_NET; 869 rtr_link.metric = htons(iface->metric); 870 num_links++; 871 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 872 fatalx("orig_rtr_lsa: ibuf_add failed"); 873 continue; 874 } 875 876 switch (iface->type) { 877 case IF_TYPE_POINTOPOINT: 878 LIST_FOREACH(nbr, &iface->nbr_list, entry) 879 if (nbr != iface->self && 880 nbr->state & NBR_STA_FULL) 881 break; 882 if (nbr) { 883 log_debug("orig_rtr_lsa: point-to-point, " 884 "interface %s", iface->name); 885 rtr_link.id = nbr->id.s_addr; 886 rtr_link.data = iface->addr.s_addr; 887 rtr_link.type = LINK_TYPE_POINTTOPOINT; 888 /* RFC 3137: stub router support */ 889 if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER || 890 oe_nofib) 891 rtr_link.metric = MAX_METRIC; 892 else if (iface->dependon[0] != '\0' && 893 iface->depend_ok == 0) 894 rtr_link.metric = MAX_METRIC; 895 else 896 rtr_link.metric = htons(iface->metric); 897 num_links++; 898 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 899 fatalx("orig_rtr_lsa: ibuf_add failed"); 900 } 901 if ((iface->flags & IFF_UP) && 902 LINK_STATE_IS_UP(iface->linkstate)) { 903 log_debug("orig_rtr_lsa: stub net, " 904 "interface %s", iface->name); 905 bzero(&rtr_link, sizeof(rtr_link)); 906 if (nbr) { 907 rtr_link.id = nbr->addr.s_addr; 908 rtr_link.data = 0xffffffff; 909 } else { 910 rtr_link.id = iface->addr.s_addr & 911 iface->mask.s_addr; 912 rtr_link.data = iface->mask.s_addr; 913 } 914 rtr_link.type = LINK_TYPE_STUB_NET; 915 if (iface->dependon[0] != '\0' && 916 iface->depend_ok == 0) 917 rtr_link.metric = MAX_METRIC; 918 else 919 rtr_link.metric = htons(iface->metric); 920 num_links++; 921 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 922 fatalx("orig_rtr_lsa: ibuf_add failed"); 923 } 924 continue; 925 case IF_TYPE_BROADCAST: 926 case IF_TYPE_NBMA: 927 if ((iface->state & IF_STA_MULTI)) { 928 if (iface->dr == iface->self) { 929 LIST_FOREACH(nbr, &iface->nbr_list, 930 entry) 931 if (nbr != iface->self && 932 nbr->state & NBR_STA_FULL) 933 break; 934 } else 935 nbr = iface->dr; 936 937 if (nbr && nbr->state & NBR_STA_FULL) { 938 log_debug("orig_rtr_lsa: transit net, " 939 "interface %s", iface->name); 940 941 rtr_link.id = iface->dr->addr.s_addr; 942 rtr_link.data = iface->addr.s_addr; 943 rtr_link.type = LINK_TYPE_TRANSIT_NET; 944 break; 945 } 946 } 947 948 /* 949 * do not add a stub net LSA for interfaces that are: 950 * - down 951 * - have a linkstate which is down, apart from carp: 952 * backup carp interfaces have linkstate down, but 953 * we still announce them. 954 */ 955 if (!(iface->flags & IFF_UP) || 956 (!LINK_STATE_IS_UP(iface->linkstate) && 957 !(iface->if_type == IFT_CARP && 958 iface->linkstate == LINK_STATE_DOWN))) 959 continue; 960 log_debug("orig_rtr_lsa: stub net, " 961 "interface %s", iface->name); 962 963 rtr_link.id = 964 iface->addr.s_addr & iface->mask.s_addr; 965 rtr_link.data = iface->mask.s_addr; 966 rtr_link.type = LINK_TYPE_STUB_NET; 967 968 rtr_link.num_tos = 0; 969 /* 970 * backup carp interfaces and interfaces that depend 971 * on an interface that is down are announced with 972 * high metric for faster failover. 973 */ 974 if (iface->if_type == IFT_CARP && 975 iface->linkstate == LINK_STATE_DOWN) 976 rtr_link.metric = MAX_METRIC; 977 else if (iface->dependon[0] != '\0' && 978 iface->depend_ok == 0) 979 rtr_link.metric = MAX_METRIC; 980 else 981 rtr_link.metric = htons(iface->metric); 982 num_links++; 983 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 984 fatalx("orig_rtr_lsa: ibuf_add failed"); 985 continue; 986 case IF_TYPE_VIRTUALLINK: 987 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 988 if (nbr != iface->self && 989 nbr->state & NBR_STA_FULL) 990 break; 991 } 992 if (nbr) { 993 rtr_link.id = nbr->id.s_addr; 994 rtr_link.data = iface->addr.s_addr; 995 rtr_link.type = LINK_TYPE_VIRTUAL; 996 /* RFC 3137: stub router support */ 997 if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER || 998 oe_nofib) 999 rtr_link.metric = MAX_METRIC; 1000 else 1001 rtr_link.metric = htons(iface->metric); 1002 num_links++; 1003 virtual = 1; 1004 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 1005 fatalx("orig_rtr_lsa: ibuf_add failed"); 1006 1007 log_debug("orig_rtr_lsa: virtual link, " 1008 "interface %s", iface->name); 1009 } 1010 continue; 1011 case IF_TYPE_POINTOMULTIPOINT: 1012 log_debug("orig_rtr_lsa: stub net, " 1013 "interface %s", iface->name); 1014 rtr_link.id = iface->addr.s_addr; 1015 rtr_link.data = 0xffffffff; 1016 rtr_link.type = LINK_TYPE_STUB_NET; 1017 rtr_link.metric = htons(iface->metric); 1018 num_links++; 1019 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 1020 fatalx("orig_rtr_lsa: ibuf_add failed"); 1021 1022 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 1023 if (nbr != iface->self && 1024 nbr->state & NBR_STA_FULL) { 1025 bzero(&rtr_link, sizeof(rtr_link)); 1026 log_debug("orig_rtr_lsa: " 1027 "point-to-multipoint, interface %s", 1028 iface->name); 1029 rtr_link.id = nbr->addr.s_addr; 1030 rtr_link.data = iface->addr.s_addr; 1031 rtr_link.type = LINK_TYPE_POINTTOPOINT; 1032 /* RFC 3137: stub router support */ 1033 if (oe_nofib || oeconf->flags & 1034 OSPFD_FLAG_STUB_ROUTER) 1035 rtr_link.metric = MAX_METRIC; 1036 else if (iface->dependon[0] != '\0' && 1037 iface->depend_ok == 0) 1038 rtr_link.metric = MAX_METRIC; 1039 else 1040 rtr_link.metric = 1041 htons(iface->metric); 1042 num_links++; 1043 if (ibuf_add(buf, &rtr_link, 1044 sizeof(rtr_link))) 1045 fatalx("orig_rtr_lsa: " 1046 "ibuf_add failed"); 1047 } 1048 } 1049 continue; 1050 default: 1051 fatalx("orig_rtr_lsa: unknown interface type"); 1052 } 1053 1054 rtr_link.num_tos = 0; 1055 /* RFC 3137: stub router support */ 1056 if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER || oe_nofib) && 1057 rtr_link.type != LINK_TYPE_STUB_NET) 1058 rtr_link.metric = MAX_METRIC; 1059 else if (iface->dependon[0] != '\0' && iface->depend_ok == 0) 1060 rtr_link.metric = MAX_METRIC; 1061 else 1062 rtr_link.metric = htons(iface->metric); 1063 num_links++; 1064 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 1065 fatalx("orig_rtr_lsa: ibuf_add failed"); 1066 } 1067 1068 /* LSA router header */ 1069 lsa_rtr.flags = 0; 1070 /* 1071 * Set the E bit as soon as an as-ext lsa may be redistributed, only 1072 * setting it in case we redistribute something is not worth the fuss. 1073 * Do not set the E bit in case of a stub area. 1074 */ 1075 if (oeconf->redistribute && !area->stub) 1076 lsa_rtr.flags |= OSPF_RTR_E; 1077 1078 border = (area_border_router(oeconf) != 0); 1079 if (border != oeconf->border) { 1080 oeconf->border = border; 1081 orig_rtr_lsa_all(area); 1082 } 1083 if (oeconf->border) 1084 lsa_rtr.flags |= OSPF_RTR_B; 1085 1086 /* TODO set V flag if a active virtual link ends here and the 1087 * area is the transit area for this link. */ 1088 if (virtual) 1089 lsa_rtr.flags |= OSPF_RTR_V; 1090 1091 lsa_rtr.dummy = 0; 1092 lsa_rtr.nlinks = htons(num_links); 1093 if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_rtr, sizeof(lsa_rtr)) == 1094 -1) 1095 fatal("orig_rtr_lsa: ibuf_set failed"); 1096 1097 /* LSA header */ 1098 lsa_hdr.age = htons(DEFAULT_AGE); 1099 lsa_hdr.opts = area_ospf_options(area); 1100 lsa_hdr.type = LSA_TYPE_ROUTER; 1101 lsa_hdr.ls_id = oeconf->rtr_id.s_addr; 1102 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr; 1103 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); 1104 lsa_hdr.len = htons(ibuf_size(buf)); 1105 lsa_hdr.ls_chksum = 0; /* updated later */ 1106 if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1) 1107 fatal("orig_rtr_lsa: ibuf_set failed"); 1108 1109 chksum = iso_cksum(ibuf_data(buf), ibuf_size(buf), LS_CKSUM_OFFSET); 1110 if (ibuf_set_n16(buf, LS_CKSUM_OFFSET, chksum) == -1) 1111 fatal("orig_rtr_lsa: ibuf_set_n16 failed"); 1112 1113 if (self && num_links) 1114 imsg_compose_event(iev_rde, IMSG_LS_UPD, self->peerid, 0, 1115 -1, ibuf_data(buf), ibuf_size(buf)); 1116 else 1117 log_warnx("orig_rtr_lsa: empty area %s", 1118 inet_ntoa(area->id)); 1119 1120 ibuf_free(buf); 1121 } 1122 1123 void 1124 orig_net_lsa(struct iface *iface) 1125 { 1126 struct lsa_hdr lsa_hdr; 1127 struct nbr *nbr; 1128 struct ibuf *buf; 1129 int num_rtr = 0; 1130 u_int16_t chksum; 1131 1132 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), 1133 IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) - 1134 sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL) 1135 fatal("orig_net_lsa"); 1136 1137 /* reserve space for LSA header and LSA Router header */ 1138 if (ibuf_add_zero(buf, sizeof(lsa_hdr)) == -1) 1139 fatal("orig_net_lsa: ibuf_add_zero failed"); 1140 1141 /* LSA net mask and then all fully adjacent routers */ 1142 if (ibuf_add(buf, &iface->mask, sizeof(iface->mask))) 1143 fatal("orig_net_lsa: ibuf_add failed"); 1144 1145 /* fully adjacent neighbors + self */ 1146 LIST_FOREACH(nbr, &iface->nbr_list, entry) 1147 if (nbr->state & NBR_STA_FULL) { 1148 if (ibuf_add(buf, &nbr->id, sizeof(nbr->id))) 1149 fatal("orig_net_lsa: ibuf_add failed"); 1150 num_rtr++; 1151 } 1152 1153 if (num_rtr == 1) { 1154 /* non transit net therefore no need to generate a net lsa */ 1155 ibuf_free(buf); 1156 return; 1157 } 1158 1159 /* LSA header */ 1160 if (iface->state & IF_STA_DR) 1161 lsa_hdr.age = htons(DEFAULT_AGE); 1162 else 1163 lsa_hdr.age = htons(MAX_AGE); 1164 1165 lsa_hdr.opts = area_ospf_options(iface->area); 1166 lsa_hdr.type = LSA_TYPE_NETWORK; 1167 lsa_hdr.ls_id = iface->addr.s_addr; 1168 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr; 1169 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); 1170 lsa_hdr.len = htons(ibuf_size(buf)); 1171 lsa_hdr.ls_chksum = 0; /* updated later */ 1172 if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1) 1173 fatal("orig_net_lsa: ibuf_set failed"); 1174 1175 chksum = iso_cksum(ibuf_data(buf), ibuf_size(buf), LS_CKSUM_OFFSET); 1176 if (ibuf_set_n16(buf, LS_CKSUM_OFFSET, chksum) == -1) 1177 fatal("orig_net_lsa: ibuf_set_n16 failed"); 1178 1179 imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0, 1180 -1, ibuf_data(buf), ibuf_size(buf)); 1181 1182 ibuf_free(buf); 1183 } 1184 1185 u_int32_t 1186 ospfe_router_id(void) 1187 { 1188 return (oeconf->rtr_id.s_addr); 1189 } 1190 1191 void 1192 ospfe_fib_update(int type) 1193 { 1194 int old = oe_nofib; 1195 1196 if (type == IMSG_CTL_FIB_COUPLE) 1197 oe_nofib = 0; 1198 if (type == IMSG_CTL_FIB_DECOUPLE) 1199 oe_nofib = 1; 1200 if (old != oe_nofib) 1201 orig_rtr_lsa_all(NULL); 1202 } 1203 1204 void 1205 ospfe_iface_ctl(struct ctl_conn *c, unsigned int idx) 1206 { 1207 struct area *area; 1208 struct iface *iface; 1209 struct ctl_iface *ictl; 1210 1211 LIST_FOREACH(area, &oeconf->area_list, entry) 1212 LIST_FOREACH(iface, &area->iface_list, entry) 1213 if (idx == 0 || idx == iface->ifindex) { 1214 ictl = if_to_ctl(iface); 1215 imsg_compose_event(&c->iev, 1216 IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 1217 ictl, sizeof(struct ctl_iface)); 1218 } 1219 } 1220 1221 void 1222 ospfe_nbr_ctl(struct ctl_conn *c) 1223 { 1224 struct area *area; 1225 struct iface *iface; 1226 struct nbr *nbr; 1227 struct ctl_nbr *nctl; 1228 1229 LIST_FOREACH(area, &oeconf->area_list, entry) 1230 LIST_FOREACH(iface, &area->iface_list, entry) 1231 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 1232 if (iface->self != nbr) { 1233 nctl = nbr_to_ctl(nbr); 1234 imsg_compose_event(&c->iev, 1235 IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, 1236 sizeof(struct ctl_nbr)); 1237 } 1238 } 1239 1240 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); 1241 } 1242 1243 void 1244 ospfe_demote_area(struct area *area, int active) 1245 { 1246 struct demote_msg dmsg; 1247 1248 if (ospfd_process != PROC_OSPF_ENGINE || 1249 area->demote_group[0] == '\0') 1250 return; 1251 1252 bzero(&dmsg, sizeof(dmsg)); 1253 strlcpy(dmsg.demote_group, area->demote_group, 1254 sizeof(dmsg.demote_group)); 1255 dmsg.level = area->demote_level; 1256 if (active) 1257 dmsg.level = -dmsg.level; 1258 1259 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg)); 1260 } 1261 1262 void 1263 ospfe_demote_iface(struct iface *iface, int active) 1264 { 1265 struct demote_msg dmsg; 1266 1267 if (ospfd_process != PROC_OSPF_ENGINE || 1268 iface->demote_group[0] == '\0') 1269 return; 1270 1271 bzero(&dmsg, sizeof(dmsg)); 1272 strlcpy(dmsg.demote_group, iface->demote_group, 1273 sizeof(dmsg.demote_group)); 1274 if (active) 1275 dmsg.level = -1; 1276 else 1277 dmsg.level = 1; 1278 1279 log_warnx("ospfe_demote_iface: group %s level %d", dmsg.demote_group, 1280 dmsg.level); 1281 1282 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg)); 1283 } 1284