1 /* $OpenBSD: ospfe.c,v 1.83 2011/07/04 04:34:14 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 #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 (msgbuf_write(&ibuf->w) == -1) 283 fatal("msgbuf_write"); 284 } 285 286 for (;;) { 287 if ((n = imsg_get(ibuf, &imsg)) == -1) 288 fatal("ospfe_dispatch_main: imsg_read error"); 289 if (n == 0) 290 break; 291 292 switch (imsg.hdr.type) { 293 case IMSG_IFINFO: 294 if (imsg.hdr.len != IMSG_HEADER_SIZE + 295 sizeof(struct kif)) 296 fatalx("IFINFO imsg with wrong len"); 297 kif = imsg.data; 298 link_ok = (kif->flags & IFF_UP) && 299 LINK_STATE_IS_UP(kif->link_state); 300 301 LIST_FOREACH(area, &oeconf->area_list, entry) { 302 LIST_FOREACH(iface, &area->iface_list, entry) { 303 if (kif->ifindex == iface->ifindex && 304 iface->type != 305 IF_TYPE_VIRTUALLINK) { 306 iface->flags = kif->flags; 307 iface->linkstate = 308 kif->link_state; 309 310 if (link_ok) { 311 if_fsm(iface, 312 IF_EVT_UP); 313 log_warnx("interface %s" 314 " up", iface->name); 315 } else { 316 if_fsm(iface, 317 IF_EVT_DOWN); 318 log_warnx("interface %s" 319 " down", 320 iface->name); 321 } 322 } 323 } 324 } 325 break; 326 case IMSG_IFADDRDEL: 327 if (imsg.hdr.len != IMSG_HEADER_SIZE + 328 sizeof(struct ifaddrdel)) 329 fatalx("IFADDRDEL imsg with wrong len"); 330 ifc = imsg.data; 331 332 LIST_FOREACH(area, &oeconf->area_list, entry) { 333 LIST_FOREACH(iface, &area->iface_list, entry) { 334 if (ifc->ifindex == iface->ifindex && 335 ifc->addr.s_addr == 336 iface->addr.s_addr) { 337 if_fsm(iface, IF_EVT_DOWN); 338 log_warnx("interface %s:%s " 339 "gone", iface->name, 340 inet_ntoa(iface->addr)); 341 break; 342 } 343 } 344 } 345 break; 346 case IMSG_RECONF_CONF: 347 if ((nconf = malloc(sizeof(struct ospfd_conf))) == 348 NULL) 349 fatal(NULL); 350 memcpy(nconf, imsg.data, sizeof(struct ospfd_conf)); 351 352 LIST_INIT(&nconf->area_list); 353 LIST_INIT(&nconf->cand_list); 354 break; 355 case IMSG_RECONF_AREA: 356 if ((narea = area_new()) == NULL) 357 fatal(NULL); 358 memcpy(narea, imsg.data, sizeof(struct area)); 359 360 LIST_INIT(&narea->iface_list); 361 LIST_INIT(&narea->nbr_list); 362 RB_INIT(&narea->lsa_tree); 363 SIMPLEQ_INIT(&narea->redist_list); 364 365 LIST_INSERT_HEAD(&nconf->area_list, narea, entry); 366 break; 367 case IMSG_RECONF_IFACE: 368 if ((niface = malloc(sizeof(struct iface))) == NULL) 369 fatal(NULL); 370 memcpy(niface, imsg.data, sizeof(struct iface)); 371 372 LIST_INIT(&niface->nbr_list); 373 TAILQ_INIT(&niface->ls_ack_list); 374 TAILQ_INIT(&niface->auth_md_list); 375 RB_INIT(&niface->lsa_tree); 376 377 niface->area = narea; 378 LIST_INSERT_HEAD(&narea->iface_list, niface, entry); 379 break; 380 case IMSG_RECONF_AUTHMD: 381 memcpy(&md, imsg.data, sizeof(struct auth_md)); 382 md_list_add(&niface->auth_md_list, md.keyid, md.key); 383 break; 384 case IMSG_RECONF_END: 385 if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER) != 386 (nconf->flags & OSPFD_FLAG_STUB_ROUTER)) 387 stub_changed = 1; 388 else 389 stub_changed = 0; 390 merge_config(oeconf, nconf); 391 nconf = NULL; 392 if (stub_changed) 393 orig_rtr_lsa_all(NULL); 394 break; 395 case IMSG_CTL_KROUTE: 396 case IMSG_CTL_KROUTE_ADDR: 397 case IMSG_CTL_IFINFO: 398 case IMSG_CTL_END: 399 control_imsg_relay(&imsg); 400 break; 401 default: 402 log_debug("ospfe_dispatch_main: error handling imsg %d", 403 imsg.hdr.type); 404 break; 405 } 406 imsg_free(&imsg); 407 } 408 if (!shut) 409 imsg_event_add(iev); 410 else { 411 /* this pipe is dead, so remove the event handler */ 412 event_del(&iev->ev); 413 event_loopexit(NULL); 414 } 415 } 416 417 /* ARGSUSED */ 418 void 419 ospfe_dispatch_rde(int fd, short event, void *bula) 420 { 421 struct lsa_hdr lsa_hdr; 422 struct imsgev *iev = bula; 423 struct imsgbuf *ibuf = &iev->ibuf; 424 struct nbr *nbr; 425 struct lsa_hdr *lhp; 426 struct lsa_ref *ref; 427 struct area *area; 428 struct iface *iface; 429 struct lsa_entry *le; 430 struct imsg imsg; 431 struct abr_rtr ar; 432 int n, noack = 0, shut = 0; 433 u_int16_t l, age; 434 435 if (event & EV_READ) { 436 if ((n = imsg_read(ibuf)) == -1) 437 fatal("imsg_read error"); 438 if (n == 0) /* connection closed */ 439 shut = 1; 440 } 441 if (event & EV_WRITE) { 442 if (msgbuf_write(&ibuf->w) == -1) 443 fatal("msgbuf_write"); 444 } 445 446 for (;;) { 447 if ((n = imsg_get(ibuf, &imsg)) == -1) 448 fatal("ospfe_dispatch_rde: imsg_read error"); 449 if (n == 0) 450 break; 451 452 switch (imsg.hdr.type) { 453 case IMSG_DD: 454 nbr = nbr_find_peerid(imsg.hdr.peerid); 455 if (nbr == NULL) 456 break; 457 458 /* 459 * Ignore imsg when in the wrong state because a 460 * NBR_EVT_SEQ_NUM_MIS may have been issued in between. 461 * Luckily regetting the DB snapshot acts as a barrier 462 * for both state and process synchronisation. 463 */ 464 if ((nbr->state & NBR_STA_FLOOD) == 0) 465 break; 466 467 /* put these on my ls_req_list for retrieval */ 468 lhp = lsa_hdr_new(); 469 memcpy(lhp, imsg.data, sizeof(*lhp)); 470 ls_req_list_add(nbr, lhp); 471 break; 472 case IMSG_DD_END: 473 nbr = nbr_find_peerid(imsg.hdr.peerid); 474 if (nbr == NULL) 475 break; 476 477 /* see above */ 478 if ((nbr->state & NBR_STA_FLOOD) == 0) 479 break; 480 481 nbr->dd_pending--; 482 if (nbr->dd_pending == 0 && nbr->state & NBR_STA_LOAD) { 483 if (ls_req_list_empty(nbr)) 484 nbr_fsm(nbr, NBR_EVT_LOAD_DONE); 485 else 486 start_ls_req_tx_timer(nbr); 487 } 488 break; 489 case IMSG_DD_BADLSA: 490 nbr = nbr_find_peerid(imsg.hdr.peerid); 491 if (nbr == NULL) 492 break; 493 494 if (nbr->iface->self == nbr) 495 fatalx("ospfe_dispatch_rde: " 496 "dummy neighbor got BADREQ"); 497 498 nbr_fsm(nbr, NBR_EVT_SEQ_NUM_MIS); 499 break; 500 case IMSG_DB_SNAPSHOT: 501 nbr = nbr_find_peerid(imsg.hdr.peerid); 502 if (nbr == NULL) 503 break; 504 505 /* add LSA header to the neighbor db_sum_list */ 506 lhp = lsa_hdr_new(); 507 memcpy(lhp, imsg.data, sizeof(*lhp)); 508 db_sum_list_add(nbr, lhp); 509 break; 510 case IMSG_DB_END: 511 nbr = nbr_find_peerid(imsg.hdr.peerid); 512 if (nbr == NULL) 513 break; 514 515 /* snapshot done, start tx of dd packets */ 516 nbr_fsm(nbr, NBR_EVT_SNAP_DONE); 517 break; 518 case IMSG_LS_FLOOD: 519 nbr = nbr_find_peerid(imsg.hdr.peerid); 520 if (nbr == NULL) 521 break; 522 523 l = imsg.hdr.len - IMSG_HEADER_SIZE; 524 if (l < sizeof(lsa_hdr)) 525 fatalx("ospfe_dispatch_rde: " 526 "bad imsg size"); 527 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr)); 528 529 ref = lsa_cache_add(imsg.data, l); 530 531 if (lsa_hdr.type == LSA_TYPE_EXTERNAL) { 532 /* 533 * flood on all areas but stub areas and 534 * virtual links 535 */ 536 LIST_FOREACH(area, &oeconf->area_list, entry) { 537 if (area->stub) 538 continue; 539 LIST_FOREACH(iface, &area->iface_list, 540 entry) { 541 noack += lsa_flood(iface, nbr, 542 &lsa_hdr, imsg.data); 543 } 544 } 545 } else if (lsa_hdr.type == LSA_TYPE_LINK_OPAQ) { 546 /* 547 * Flood on interface only 548 */ 549 noack += lsa_flood(nbr->iface, nbr, 550 &lsa_hdr, imsg.data); 551 } else { 552 /* 553 * Flood on all area interfaces. For 554 * area 0.0.0.0 include the virtual links. 555 */ 556 area = nbr->iface->area; 557 LIST_FOREACH(iface, &area->iface_list, entry) { 558 noack += lsa_flood(iface, nbr, 559 &lsa_hdr, imsg.data); 560 } 561 /* XXX virtual links */ 562 } 563 564 /* remove from ls_req_list */ 565 le = ls_req_list_get(nbr, &lsa_hdr); 566 if (!(nbr->state & NBR_STA_FULL) && le != NULL) { 567 ls_req_list_free(nbr, le); 568 /* 569 * XXX no need to ack requested lsa 570 * the problem is that the RFC is very 571 * unclear about this. 572 */ 573 noack = 1; 574 } 575 576 if (!noack && nbr->iface != NULL && 577 nbr->iface->self != nbr) { 578 if (!(nbr->iface->state & IF_STA_BACKUP) || 579 nbr->iface->dr == nbr) { 580 /* delayed ack */ 581 lhp = lsa_hdr_new(); 582 memcpy(lhp, &lsa_hdr, sizeof(*lhp)); 583 ls_ack_list_add(nbr->iface, lhp); 584 } 585 } 586 587 lsa_cache_put(ref, nbr); 588 break; 589 case IMSG_LS_UPD: 590 /* 591 * IMSG_LS_UPD is used in three cases: 592 * 1. as response to ls requests 593 * 2. as response to ls updates where the DB 594 * is newer then the sent LSA 595 * 3. in EXSTART when the LSA has age MaxAge 596 */ 597 l = imsg.hdr.len - IMSG_HEADER_SIZE; 598 if (l < sizeof(lsa_hdr)) 599 fatalx("ospfe_dispatch_rde: " 600 "bad imsg size"); 601 602 nbr = nbr_find_peerid(imsg.hdr.peerid); 603 if (nbr == NULL) 604 break; 605 606 if (nbr->iface->self == nbr) 607 break; 608 609 memcpy(&age, imsg.data, sizeof(age)); 610 ref = lsa_cache_add(imsg.data, l); 611 if (ntohs(age) >= MAX_AGE) 612 /* add to retransmit list */ 613 ls_retrans_list_add(nbr, imsg.data, 0, 0); 614 else 615 ls_retrans_list_add(nbr, imsg.data, 0, 1); 616 617 lsa_cache_put(ref, nbr); 618 break; 619 case IMSG_LS_ACK: 620 /* 621 * IMSG_LS_ACK is used in two cases: 622 * 1. LSA was a duplicate 623 * 2. LS age is MaxAge and there is no current 624 * instance in the DB plus no neighbor in state 625 * Exchange or Loading 626 */ 627 nbr = nbr_find_peerid(imsg.hdr.peerid); 628 if (nbr == NULL) 629 break; 630 631 if (nbr->iface->self == nbr) 632 break; 633 634 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lsa_hdr)) 635 fatalx("ospfe_dispatch_rde: bad imsg size"); 636 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr)); 637 638 /* for case one check for implied acks */ 639 if (nbr->iface->state & IF_STA_DROTHER) 640 if (ls_retrans_list_del(nbr->iface->self, 641 &lsa_hdr) == 0) 642 break; 643 if (ls_retrans_list_del(nbr, &lsa_hdr) == 0) 644 break; 645 646 /* send a direct acknowledgement */ 647 send_direct_ack(nbr->iface, nbr->addr, imsg.data, 648 imsg.hdr.len - IMSG_HEADER_SIZE); 649 650 break; 651 case IMSG_LS_BADREQ: 652 nbr = nbr_find_peerid(imsg.hdr.peerid); 653 if (nbr == NULL) 654 break; 655 656 if (nbr->iface->self == nbr) 657 fatalx("ospfe_dispatch_rde: " 658 "dummy neighbor got BADREQ"); 659 660 nbr_fsm(nbr, NBR_EVT_BAD_LS_REQ); 661 break; 662 case IMSG_ABR_UP: 663 memcpy(&ar, imsg.data, sizeof(ar)); 664 665 if ((iface = find_vlink(&ar)) != NULL && 666 iface->state == IF_STA_DOWN) 667 if (if_fsm(iface, IF_EVT_UP)) { 668 log_debug("error starting interface %s", 669 iface->name); 670 } 671 break; 672 case IMSG_ABR_DOWN: 673 memcpy(&ar, imsg.data, sizeof(ar)); 674 675 if ((iface = find_vlink(&ar)) != NULL && 676 iface->state == IF_STA_POINTTOPOINT) 677 if (if_fsm(iface, IF_EVT_DOWN)) { 678 log_debug("error stopping interface %s", 679 iface->name); 680 } 681 break; 682 case IMSG_CTL_AREA: 683 case IMSG_CTL_IFACE: 684 case IMSG_CTL_END: 685 case IMSG_CTL_SHOW_DATABASE: 686 case IMSG_CTL_SHOW_DB_EXT: 687 case IMSG_CTL_SHOW_DB_NET: 688 case IMSG_CTL_SHOW_DB_RTR: 689 case IMSG_CTL_SHOW_DB_SELF: 690 case IMSG_CTL_SHOW_DB_SUM: 691 case IMSG_CTL_SHOW_DB_ASBR: 692 case IMSG_CTL_SHOW_DB_OPAQ: 693 case IMSG_CTL_SHOW_RIB: 694 case IMSG_CTL_SHOW_SUM: 695 case IMSG_CTL_SHOW_SUM_AREA: 696 control_imsg_relay(&imsg); 697 break; 698 default: 699 log_debug("ospfe_dispatch_rde: error handling imsg %d", 700 imsg.hdr.type); 701 break; 702 } 703 imsg_free(&imsg); 704 } 705 if (!shut) 706 imsg_event_add(iev); 707 else { 708 /* this pipe is dead, so remove the event handler */ 709 event_del(&iev->ev); 710 event_loopexit(NULL); 711 } 712 } 713 714 struct iface * 715 find_vlink(struct abr_rtr *ar) 716 { 717 struct area *area; 718 struct iface *iface = NULL; 719 720 LIST_FOREACH(area, &oeconf->area_list, entry) 721 LIST_FOREACH(iface, &area->iface_list, entry) 722 if (iface->abr_id.s_addr == ar->abr_id.s_addr && 723 iface->type == IF_TYPE_VIRTUALLINK && 724 iface->area->id.s_addr == ar->area.s_addr) { 725 iface->dst.s_addr = ar->dst_ip.s_addr; 726 iface->addr.s_addr = ar->addr.s_addr; 727 iface->metric = ar->metric; 728 729 return (iface); 730 } 731 732 return (iface); 733 } 734 735 void 736 orig_rtr_lsa_all(struct area *area) 737 { 738 struct area *a; 739 740 /* 741 * update all router LSA in all areas except area itself, 742 * as this update is already running. 743 */ 744 LIST_FOREACH(a, &oeconf->area_list, entry) 745 if (a != area) 746 orig_rtr_lsa(a); 747 } 748 749 void 750 orig_rtr_lsa(struct area *area) 751 { 752 struct lsa_hdr lsa_hdr; 753 struct lsa_rtr lsa_rtr; 754 struct lsa_rtr_link rtr_link; 755 struct iface *iface; 756 struct ibuf *buf; 757 struct nbr *nbr, *self = NULL; 758 u_int16_t num_links = 0; 759 u_int16_t chksum; 760 u_int8_t border, virtual = 0; 761 762 log_debug("orig_rtr_lsa: area %s", inet_ntoa(area->id)); 763 764 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), 765 IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) - 766 sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL) 767 fatal("orig_rtr_lsa"); 768 769 /* reserve space for LSA header and LSA Router header */ 770 if (ibuf_reserve(buf, sizeof(lsa_hdr)) == NULL) 771 fatal("orig_rtr_lsa: ibuf_reserve failed"); 772 773 if (ibuf_reserve(buf, sizeof(lsa_rtr)) == NULL) 774 fatal("orig_rtr_lsa: ibuf_reserve failed"); 775 776 /* links */ 777 LIST_FOREACH(iface, &area->iface_list, entry) { 778 if (self == NULL && iface->self != NULL) 779 self = iface->self; 780 781 bzero(&rtr_link, sizeof(rtr_link)); 782 783 if (iface->state & IF_STA_LOOPBACK) { 784 rtr_link.id = iface->addr.s_addr; 785 rtr_link.data = 0xffffffff; 786 rtr_link.type = LINK_TYPE_STUB_NET; 787 rtr_link.metric = htons(iface->metric); 788 num_links++; 789 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 790 fatalx("orig_rtr_lsa: ibuf_add failed"); 791 continue; 792 } 793 794 switch (iface->type) { 795 case IF_TYPE_POINTOPOINT: 796 LIST_FOREACH(nbr, &iface->nbr_list, entry) 797 if (nbr != iface->self && 798 nbr->state & NBR_STA_FULL) 799 break; 800 if (nbr) { 801 log_debug("orig_rtr_lsa: point-to-point, " 802 "interface %s", iface->name); 803 rtr_link.id = nbr->id.s_addr; 804 rtr_link.data = iface->addr.s_addr; 805 rtr_link.type = LINK_TYPE_POINTTOPOINT; 806 /* RFC 3137: stub router support */ 807 if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER || 808 oe_nofib) 809 rtr_link.metric = MAX_METRIC; 810 else 811 rtr_link.metric = htons(iface->metric); 812 num_links++; 813 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 814 fatalx("orig_rtr_lsa: ibuf_add failed"); 815 } 816 if (iface->state & IF_STA_POINTTOPOINT) { 817 log_debug("orig_rtr_lsa: stub net, " 818 "interface %s", iface->name); 819 bzero(&rtr_link, sizeof(rtr_link)); 820 if (nbr) { 821 rtr_link.id = nbr->addr.s_addr; 822 rtr_link.data = 0xffffffff; 823 } else { 824 rtr_link.id = iface->addr.s_addr; 825 rtr_link.data = iface->mask.s_addr; 826 } 827 rtr_link.type = LINK_TYPE_STUB_NET; 828 rtr_link.metric = htons(iface->metric); 829 num_links++; 830 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 831 fatalx("orig_rtr_lsa: ibuf_add failed"); 832 } 833 continue; 834 case IF_TYPE_BROADCAST: 835 case IF_TYPE_NBMA: 836 if ((iface->state & IF_STA_MULTI)) { 837 if (iface->dr == iface->self) { 838 LIST_FOREACH(nbr, &iface->nbr_list, 839 entry) 840 if (nbr != iface->self && 841 nbr->state & NBR_STA_FULL) 842 break; 843 } else 844 nbr = iface->dr; 845 846 if (nbr && nbr->state & NBR_STA_FULL) { 847 log_debug("orig_rtr_lsa: transit net, " 848 "interface %s", iface->name); 849 850 rtr_link.id = iface->dr->addr.s_addr; 851 rtr_link.data = iface->addr.s_addr; 852 rtr_link.type = LINK_TYPE_TRANSIT_NET; 853 break; 854 } 855 } 856 857 /* 858 * do not add a stub net LSA for interfaces that are: 859 * - down 860 * - have a linkstate which is down 861 */ 862 if (!(iface->flags & IFF_UP) || 863 !LINK_STATE_IS_UP(iface->linkstate)) 864 continue; 865 log_debug("orig_rtr_lsa: stub net, " 866 "interface %s", iface->name); 867 868 rtr_link.id = 869 iface->addr.s_addr & iface->mask.s_addr; 870 rtr_link.data = iface->mask.s_addr; 871 rtr_link.type = LINK_TYPE_STUB_NET; 872 873 rtr_link.num_tos = 0; 874 /* 875 * backup carp interfaces are anounced with high metric 876 * for faster failover. 877 */ 878 if (iface->media_type == IFT_CARP && 879 iface->linkstate == LINK_STATE_DOWN) 880 rtr_link.metric = MAX_METRIC; 881 else 882 rtr_link.metric = htons(iface->metric); 883 num_links++; 884 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 885 fatalx("orig_rtr_lsa: ibuf_add failed"); 886 continue; 887 case IF_TYPE_VIRTUALLINK: 888 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 889 if (nbr != iface->self && 890 nbr->state & NBR_STA_FULL) 891 break; 892 } 893 if (nbr) { 894 rtr_link.id = nbr->id.s_addr; 895 rtr_link.data = iface->addr.s_addr; 896 rtr_link.type = LINK_TYPE_VIRTUAL; 897 /* RFC 3137: stub router support */ 898 if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER || 899 oe_nofib) 900 rtr_link.metric = MAX_METRIC; 901 else 902 rtr_link.metric = htons(iface->metric); 903 num_links++; 904 virtual = 1; 905 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 906 fatalx("orig_rtr_lsa: ibuf_add failed"); 907 908 log_debug("orig_rtr_lsa: virtual link, " 909 "interface %s", iface->name); 910 } 911 continue; 912 case IF_TYPE_POINTOMULTIPOINT: 913 log_debug("orig_rtr_lsa: stub net, " 914 "interface %s", iface->name); 915 rtr_link.id = iface->addr.s_addr; 916 rtr_link.data = 0xffffffff; 917 rtr_link.type = LINK_TYPE_STUB_NET; 918 rtr_link.metric = htons(iface->metric); 919 num_links++; 920 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 921 fatalx("orig_rtr_lsa: ibuf_add failed"); 922 923 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 924 if (nbr != iface->self && 925 nbr->state & NBR_STA_FULL) { 926 bzero(&rtr_link, sizeof(rtr_link)); 927 log_debug("orig_rtr_lsa: " 928 "point-to-multipoint, interface %s", 929 iface->name); 930 rtr_link.id = nbr->addr.s_addr; 931 rtr_link.data = iface->addr.s_addr; 932 rtr_link.type = LINK_TYPE_POINTTOPOINT; 933 /* RFC 3137: stub router support */ 934 if (oe_nofib || oeconf->flags & 935 OSPFD_FLAG_STUB_ROUTER) 936 rtr_link.metric = MAX_METRIC; 937 else 938 rtr_link.metric = 939 htons(iface->metric); 940 num_links++; 941 if (ibuf_add(buf, &rtr_link, 942 sizeof(rtr_link))) 943 fatalx("orig_rtr_lsa: " 944 "ibuf_add failed"); 945 } 946 } 947 continue; 948 default: 949 fatalx("orig_rtr_lsa: unknown interface type"); 950 } 951 952 rtr_link.num_tos = 0; 953 /* RFC 3137: stub router support */ 954 if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER || oe_nofib) && 955 rtr_link.type != LINK_TYPE_STUB_NET) 956 rtr_link.metric = MAX_METRIC; 957 else 958 rtr_link.metric = htons(iface->metric); 959 num_links++; 960 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link))) 961 fatalx("orig_rtr_lsa: ibuf_add failed"); 962 } 963 964 /* LSA router header */ 965 lsa_rtr.flags = 0; 966 /* 967 * Set the E bit as soon as an as-ext lsa may be redistributed, only 968 * setting it in case we redistribute something is not worth the fuss. 969 * Do not set the E bit in case of a stub area. 970 */ 971 if (oeconf->redistribute && !area->stub) 972 lsa_rtr.flags |= OSPF_RTR_E; 973 974 border = (area_border_router(oeconf) != 0); 975 if (border != oeconf->border) { 976 oeconf->border = border; 977 orig_rtr_lsa_all(area); 978 } 979 980 if (oeconf->border) 981 lsa_rtr.flags |= OSPF_RTR_B; 982 /* TODO set V flag if a active virtual link ends here and the 983 * area is the transit area for this link. */ 984 if (virtual) 985 lsa_rtr.flags |= OSPF_RTR_V; 986 987 lsa_rtr.dummy = 0; 988 lsa_rtr.nlinks = htons(num_links); 989 memcpy(ibuf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_rtr)), 990 &lsa_rtr, sizeof(lsa_rtr)); 991 992 /* LSA header */ 993 lsa_hdr.age = htons(DEFAULT_AGE); 994 lsa_hdr.opts = area_ospf_options(area); 995 lsa_hdr.type = LSA_TYPE_ROUTER; 996 lsa_hdr.ls_id = oeconf->rtr_id.s_addr; 997 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr; 998 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); 999 lsa_hdr.len = htons(ibuf_size(buf)); 1000 lsa_hdr.ls_chksum = 0; /* updated later */ 1001 memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); 1002 1003 chksum = htons(iso_cksum(buf->buf, ibuf_size(buf), LS_CKSUM_OFFSET)); 1004 memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), 1005 &chksum, sizeof(chksum)); 1006 1007 if (self) 1008 imsg_compose_event(iev_rde, IMSG_LS_UPD, self->peerid, 0, 1009 -1, buf->buf, ibuf_size(buf)); 1010 else 1011 log_warnx("orig_rtr_lsa: empty area %s", 1012 inet_ntoa(area->id)); 1013 1014 ibuf_free(buf); 1015 } 1016 1017 void 1018 orig_net_lsa(struct iface *iface) 1019 { 1020 struct lsa_hdr lsa_hdr; 1021 struct nbr *nbr; 1022 struct ibuf *buf; 1023 int num_rtr = 0; 1024 u_int16_t chksum; 1025 1026 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), 1027 IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) - 1028 sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL) 1029 fatal("orig_net_lsa"); 1030 1031 /* reserve space for LSA header and LSA Router header */ 1032 if (ibuf_reserve(buf, sizeof(lsa_hdr)) == NULL) 1033 fatal("orig_net_lsa: ibuf_reserve failed"); 1034 1035 /* LSA net mask and then all fully adjacent routers */ 1036 if (ibuf_add(buf, &iface->mask, sizeof(iface->mask))) 1037 fatal("orig_net_lsa: ibuf_add failed"); 1038 1039 /* fully adjacent neighbors + self */ 1040 LIST_FOREACH(nbr, &iface->nbr_list, entry) 1041 if (nbr->state & NBR_STA_FULL) { 1042 if (ibuf_add(buf, &nbr->id, sizeof(nbr->id))) 1043 fatal("orig_net_lsa: ibuf_add failed"); 1044 num_rtr++; 1045 } 1046 1047 if (num_rtr == 1) { 1048 /* non transit net therefore no need to generate a net lsa */ 1049 ibuf_free(buf); 1050 return; 1051 } 1052 1053 /* LSA header */ 1054 if (iface->state & IF_STA_DR) 1055 lsa_hdr.age = htons(DEFAULT_AGE); 1056 else 1057 lsa_hdr.age = htons(MAX_AGE); 1058 1059 lsa_hdr.opts = area_ospf_options(iface->area); 1060 lsa_hdr.type = LSA_TYPE_NETWORK; 1061 lsa_hdr.ls_id = iface->addr.s_addr; 1062 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr; 1063 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM); 1064 lsa_hdr.len = htons(ibuf_size(buf)); 1065 lsa_hdr.ls_chksum = 0; /* updated later */ 1066 memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr)); 1067 1068 chksum = htons(iso_cksum(buf->buf, ibuf_size(buf), LS_CKSUM_OFFSET)); 1069 memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), 1070 &chksum, sizeof(chksum)); 1071 1072 imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0, 1073 -1, buf->buf, ibuf_size(buf)); 1074 1075 ibuf_free(buf); 1076 } 1077 1078 u_int32_t 1079 ospfe_router_id(void) 1080 { 1081 return (oeconf->rtr_id.s_addr); 1082 } 1083 1084 void 1085 ospfe_fib_update(int type) 1086 { 1087 int old = oe_nofib; 1088 1089 if (type == IMSG_CTL_FIB_COUPLE) 1090 oe_nofib = 0; 1091 if (type == IMSG_CTL_FIB_DECOUPLE) 1092 oe_nofib = 1; 1093 if (old != oe_nofib) 1094 orig_rtr_lsa_all(NULL); 1095 } 1096 1097 void 1098 ospfe_iface_ctl(struct ctl_conn *c, unsigned int idx) 1099 { 1100 struct area *area; 1101 struct iface *iface; 1102 struct ctl_iface *ictl; 1103 1104 LIST_FOREACH(area, &oeconf->area_list, entry) 1105 LIST_FOREACH(iface, &area->iface_list, entry) 1106 if (idx == 0 || idx == iface->ifindex) { 1107 ictl = if_to_ctl(iface); 1108 imsg_compose_event(&c->iev, 1109 IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, 1110 ictl, sizeof(struct ctl_iface)); 1111 } 1112 } 1113 1114 void 1115 ospfe_nbr_ctl(struct ctl_conn *c) 1116 { 1117 struct area *area; 1118 struct iface *iface; 1119 struct nbr *nbr; 1120 struct ctl_nbr *nctl; 1121 1122 LIST_FOREACH(area, &oeconf->area_list, entry) 1123 LIST_FOREACH(iface, &area->iface_list, entry) 1124 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 1125 if (iface->self != nbr) { 1126 nctl = nbr_to_ctl(nbr); 1127 imsg_compose_event(&c->iev, 1128 IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, 1129 sizeof(struct ctl_nbr)); 1130 } 1131 } 1132 1133 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); 1134 } 1135 1136 void 1137 ospfe_demote_area(struct area *area, int active) 1138 { 1139 struct demote_msg dmsg; 1140 1141 if (ospfd_process != PROC_OSPF_ENGINE || 1142 area->demote_group[0] == '\0') 1143 return; 1144 1145 bzero(&dmsg, sizeof(dmsg)); 1146 strlcpy(dmsg.demote_group, area->demote_group, 1147 sizeof(dmsg.demote_group)); 1148 dmsg.level = area->demote_level; 1149 if (active) 1150 dmsg.level = -dmsg.level; 1151 1152 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg)); 1153 } 1154 1155 void 1156 ospfe_demote_iface(struct iface *iface, int active) 1157 { 1158 struct demote_msg dmsg; 1159 1160 if (ospfd_process != PROC_OSPF_ENGINE || 1161 iface->demote_group[0] == '\0') 1162 return; 1163 1164 bzero(&dmsg, sizeof(dmsg)); 1165 strlcpy(dmsg.demote_group, iface->demote_group, 1166 sizeof(dmsg.demote_group)); 1167 if (active) 1168 dmsg.level = -1; 1169 else 1170 dmsg.level = 1; 1171 1172 log_warnx("ospfe_demote_iface: group %s level %d", dmsg.demote_group, 1173 dmsg.level); 1174 1175 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg)); 1176 } 1177