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