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