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