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