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