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