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