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