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