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