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