1 /* $OpenBSD: ospfd.c,v 1.107 2019/03/26 20:39:33 remi 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 <sys/time.h> 25 #include <sys/stat.h> 26 #include <sys/wait.h> 27 #include <sys/sysctl.h> 28 #include <syslog.h> 29 30 #include <netinet/in.h> 31 #include <arpa/inet.h> 32 #include <net/if_types.h> 33 34 #include <event.h> 35 #include <err.h> 36 #include <errno.h> 37 #include <pwd.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <signal.h> 42 #include <unistd.h> 43 44 #include "ospfd.h" 45 #include "ospf.h" 46 #include "ospfe.h" 47 #include "control.h" 48 #include "log.h" 49 #include "rde.h" 50 51 void main_sig_handler(int, short, void *); 52 __dead void usage(void); 53 __dead void ospfd_shutdown(void); 54 55 void main_dispatch_ospfe(int, short, void *); 56 void main_dispatch_rde(int, short, void *); 57 58 int ospf_reload(void); 59 int ospf_sendboth(enum imsg_type, void *, u_int16_t); 60 int merge_interfaces(struct area *, struct area *); 61 struct iface *iface_lookup(struct area *, struct iface *); 62 63 int pipe_parent2ospfe[2]; 64 int pipe_parent2rde[2]; 65 int pipe_ospfe2rde[2]; 66 67 struct ospfd_conf *ospfd_conf = NULL; 68 struct imsgev *iev_ospfe; 69 struct imsgev *iev_rde; 70 char *conffile; 71 72 pid_t ospfe_pid = 0; 73 pid_t rde_pid = 0; 74 75 /* ARGSUSED */ 76 void 77 main_sig_handler(int sig, short event, void *arg) 78 { 79 /* signal handler rules don't apply, libevent decouples for us */ 80 switch (sig) { 81 case SIGTERM: 82 case SIGINT: 83 ospfd_shutdown(); 84 /* NOTREACHED */ 85 case SIGHUP: 86 if (ospf_reload() == -1) 87 log_warnx("configuration reload failed"); 88 else 89 log_debug("configuration reloaded"); 90 break; 91 default: 92 fatalx("unexpected signal"); 93 /* NOTREACHED */ 94 } 95 } 96 97 __dead void 98 usage(void) 99 { 100 extern char *__progname; 101 102 fprintf(stderr, "usage: %s [-cdnv] [-D macro=value]" 103 " [-f file] [-s socket]\n", 104 __progname); 105 exit(1); 106 } 107 108 int 109 main(int argc, char *argv[]) 110 { 111 struct event ev_sigint, ev_sigterm, ev_sighup; 112 struct area *a; 113 int ch, opts = 0; 114 int debug = 0; 115 int ipforwarding; 116 int mib[4]; 117 size_t len; 118 char *sockname = NULL; 119 int control_fd; 120 121 conffile = CONF_FILE; 122 ospfd_process = PROC_MAIN; 123 124 log_init(1, LOG_DAEMON); /* log to stderr until daemonized */ 125 log_procinit(log_procnames[ospfd_process]); 126 127 while ((ch = getopt(argc, argv, "cdD:f:ns:v")) != -1) { 128 switch (ch) { 129 case 'c': 130 opts |= OSPFD_OPT_FORCE_DEMOTE; 131 break; 132 case 'd': 133 debug = 1; 134 break; 135 case 'D': 136 if (cmdline_symset(optarg) < 0) 137 log_warnx("could not parse macro definition %s", 138 optarg); 139 break; 140 case 'f': 141 conffile = optarg; 142 break; 143 case 'n': 144 opts |= OSPFD_OPT_NOACTION; 145 break; 146 case 's': 147 sockname = optarg; 148 break; 149 case 'v': 150 if (opts & OSPFD_OPT_VERBOSE) 151 opts |= OSPFD_OPT_VERBOSE2; 152 opts |= OSPFD_OPT_VERBOSE; 153 log_setverbose(1); 154 break; 155 default: 156 usage(); 157 /* NOTREACHED */ 158 } 159 } 160 161 argc -= optind; 162 argv += optind; 163 if (argc > 0) 164 usage(); 165 166 mib[0] = CTL_NET; 167 mib[1] = PF_INET; 168 mib[2] = IPPROTO_IP; 169 mib[3] = IPCTL_FORWARDING; 170 len = sizeof(ipforwarding); 171 if (sysctl(mib, 4, &ipforwarding, &len, NULL, 0) == -1) 172 err(1, "sysctl"); 173 174 if (ipforwarding != 1) { 175 log_warnx("WARNING: IP forwarding NOT enabled, " 176 "running as stub router"); 177 opts |= OSPFD_OPT_STUB_ROUTER; 178 } 179 180 /* fetch interfaces early */ 181 kif_init(); 182 183 /* parse config file */ 184 if ((ospfd_conf = parse_config(conffile, opts)) == NULL) { 185 kif_clear(); 186 exit(1); 187 } 188 189 if (sockname == NULL) { 190 if (asprintf(&sockname, "%s.%d", OSPFD_SOCKET, 191 ospfd_conf->rdomain) == -1) 192 err(1, "asprintf"); 193 } 194 195 ospfd_conf->csock = sockname; 196 197 if (ospfd_conf->opts & OSPFD_OPT_NOACTION) { 198 if (ospfd_conf->opts & OSPFD_OPT_VERBOSE) 199 print_config(ospfd_conf); 200 else 201 fprintf(stderr, "configuration OK\n"); 202 kif_clear(); 203 exit(0); 204 } 205 206 /* check for root privileges */ 207 if (geteuid()) 208 errx(1, "need root privileges"); 209 210 /* check for ospfd user */ 211 if (getpwnam(OSPFD_USER) == NULL) 212 errx(1, "unknown user %s", OSPFD_USER); 213 214 log_init(debug, LOG_DAEMON); 215 log_setverbose(ospfd_conf->opts & OSPFD_OPT_VERBOSE); 216 217 if ((control_check(ospfd_conf->csock)) == -1) 218 fatalx("ospfd already running"); 219 220 if (!debug) 221 daemon(1, 0); 222 223 log_info("startup"); 224 225 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 226 PF_UNSPEC, pipe_parent2ospfe) == -1) 227 fatal("socketpair"); 228 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 229 PF_UNSPEC, pipe_parent2rde) == -1) 230 fatal("socketpair"); 231 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 232 PF_UNSPEC, pipe_ospfe2rde) == -1) 233 fatal("socketpair"); 234 235 /* start children */ 236 rde_pid = rde(ospfd_conf, pipe_parent2rde, pipe_ospfe2rde, 237 pipe_parent2ospfe); 238 ospfe_pid = ospfe(ospfd_conf, pipe_parent2ospfe, pipe_ospfe2rde, 239 pipe_parent2rde); 240 241 event_init(); 242 243 /* setup signal handler */ 244 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 245 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 246 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 247 signal_add(&ev_sigint, NULL); 248 signal_add(&ev_sigterm, NULL); 249 signal_add(&ev_sighup, NULL); 250 signal(SIGPIPE, SIG_IGN); 251 252 /* setup pipes to children */ 253 close(pipe_parent2ospfe[1]); 254 close(pipe_parent2rde[1]); 255 close(pipe_ospfe2rde[0]); 256 close(pipe_ospfe2rde[1]); 257 258 if ((iev_ospfe = malloc(sizeof(struct imsgev))) == NULL || 259 (iev_rde = malloc(sizeof(struct imsgev))) == NULL) 260 fatal(NULL); 261 imsg_init(&iev_ospfe->ibuf, pipe_parent2ospfe[0]); 262 iev_ospfe->handler = main_dispatch_ospfe; 263 imsg_init(&iev_rde->ibuf, pipe_parent2rde[0]); 264 iev_rde->handler = main_dispatch_rde; 265 266 /* setup event handler */ 267 iev_ospfe->events = EV_READ; 268 event_set(&iev_ospfe->ev, iev_ospfe->ibuf.fd, iev_ospfe->events, 269 iev_ospfe->handler, iev_ospfe); 270 event_add(&iev_ospfe->ev, NULL); 271 272 iev_rde->events = EV_READ; 273 event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events, 274 iev_rde->handler, iev_rde); 275 event_add(&iev_rde->ev, NULL); 276 277 if ((control_fd = control_init(ospfd_conf->csock)) == -1) 278 fatalx("control socket setup failed"); 279 main_imsg_compose_ospfe_fd(IMSG_CONTROLFD, 0, control_fd); 280 281 if (unveil("/", "r") == -1) 282 fatal("unveil"); 283 if (unveil(ospfd_conf->csock, "c") == -1) 284 fatal("unveil"); 285 if (unveil(NULL, NULL) == -1) 286 fatal("unveil"); 287 288 if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE), 289 ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix, 290 ospfd_conf->fib_priority) == -1) 291 fatalx("kr_init failed"); 292 293 /* remove unneeded stuff from config */ 294 while ((a = LIST_FIRST(&ospfd_conf->area_list)) != NULL) { 295 LIST_REMOVE(a, entry); 296 area_del(a); 297 } 298 299 event_dispatch(); 300 301 ospfd_shutdown(); 302 /* NOTREACHED */ 303 return (0); 304 } 305 306 __dead void 307 ospfd_shutdown(void) 308 { 309 pid_t pid; 310 int status; 311 struct redistribute *r; 312 313 /* close pipes */ 314 msgbuf_clear(&iev_ospfe->ibuf.w); 315 close(iev_ospfe->ibuf.fd); 316 msgbuf_clear(&iev_rde->ibuf.w); 317 close(iev_rde->ibuf.fd); 318 319 control_cleanup(ospfd_conf->csock); 320 while ((r = SIMPLEQ_FIRST(&ospfd_conf->redist_list)) != NULL) { 321 SIMPLEQ_REMOVE_HEAD(&ospfd_conf->redist_list, entry); 322 free(r); 323 } 324 kr_shutdown(); 325 carp_demote_shutdown(); 326 327 log_debug("waiting for children to terminate"); 328 do { 329 pid = wait(&status); 330 if (pid == -1) { 331 if (errno != EINTR && errno != ECHILD) 332 fatal("wait"); 333 } else if (WIFSIGNALED(status)) 334 log_warnx("%s terminated; signal %d", 335 (pid == rde_pid) ? "route decision engine" : 336 "ospf engine", WTERMSIG(status)); 337 } while (pid != -1 || (pid == -1 && errno == EINTR)); 338 339 free(iev_ospfe); 340 free(iev_rde); 341 free(ospfd_conf); 342 343 log_info("terminating"); 344 exit(0); 345 } 346 347 /* imsg handling */ 348 /* ARGSUSED */ 349 void 350 main_dispatch_ospfe(int fd, short event, void *bula) 351 { 352 struct imsgev *iev = bula; 353 struct imsgbuf *ibuf; 354 struct imsg imsg; 355 struct demote_msg dmsg; 356 ssize_t n; 357 int shut = 0, verbose; 358 359 ibuf = &iev->ibuf; 360 361 if (event & EV_READ) { 362 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 363 fatal("imsg_read error"); 364 if (n == 0) /* connection closed */ 365 shut = 1; 366 } 367 if (event & EV_WRITE) { 368 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 369 fatal("msgbuf_write"); 370 if (n == 0) /* connection closed */ 371 shut = 1; 372 } 373 374 for (;;) { 375 if ((n = imsg_get(ibuf, &imsg)) == -1) 376 fatal("imsg_get"); 377 378 if (n == 0) 379 break; 380 381 switch (imsg.hdr.type) { 382 case IMSG_CTL_RELOAD: 383 if (ospf_reload() == -1) 384 log_warnx("configuration reload failed"); 385 else 386 log_debug("configuration reloaded"); 387 break; 388 case IMSG_CTL_FIB_COUPLE: 389 kr_fib_couple(); 390 break; 391 case IMSG_CTL_FIB_DECOUPLE: 392 kr_fib_decouple(); 393 break; 394 case IMSG_CTL_FIB_RELOAD: 395 kr_fib_reload(); 396 break; 397 case IMSG_CTL_KROUTE: 398 case IMSG_CTL_KROUTE_ADDR: 399 kr_show_route(&imsg); 400 break; 401 case IMSG_CTL_IFINFO: 402 if (imsg.hdr.len == IMSG_HEADER_SIZE) 403 kr_ifinfo(NULL, imsg.hdr.pid); 404 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 405 kr_ifinfo(imsg.data, imsg.hdr.pid); 406 else 407 log_warnx("IFINFO request with wrong len"); 408 break; 409 case IMSG_DEMOTE: 410 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(dmsg)) 411 fatalx("invalid size of OE request"); 412 memcpy(&dmsg, imsg.data, sizeof(dmsg)); 413 carp_demote_set(dmsg.demote_group, dmsg.level); 414 break; 415 case IMSG_CTL_LOG_VERBOSE: 416 /* already checked by ospfe */ 417 memcpy(&verbose, imsg.data, sizeof(verbose)); 418 log_setverbose(verbose); 419 break; 420 default: 421 log_debug("main_dispatch_ospfe: error handling imsg %d", 422 imsg.hdr.type); 423 break; 424 } 425 imsg_free(&imsg); 426 } 427 if (!shut) 428 imsg_event_add(iev); 429 else { 430 /* this pipe is dead, so remove the event handler */ 431 event_del(&iev->ev); 432 event_loopexit(NULL); 433 } 434 } 435 436 /* ARGSUSED */ 437 void 438 main_dispatch_rde(int fd, short event, void *bula) 439 { 440 struct imsgev *iev = bula; 441 struct imsgbuf *ibuf; 442 struct imsg imsg; 443 ssize_t n; 444 int count, shut = 0; 445 446 ibuf = &iev->ibuf; 447 448 if (event & EV_READ) { 449 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 450 fatal("imsg_read error"); 451 if (n == 0) /* connection closed */ 452 shut = 1; 453 } 454 if (event & EV_WRITE) { 455 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 456 fatal("msgbuf_write"); 457 if (n == 0) /* connection closed */ 458 shut = 1; 459 } 460 461 for (;;) { 462 if ((n = imsg_get(ibuf, &imsg)) == -1) 463 fatal("imsg_get"); 464 465 if (n == 0) 466 break; 467 468 switch (imsg.hdr.type) { 469 case IMSG_KROUTE_CHANGE: 470 count = (imsg.hdr.len - IMSG_HEADER_SIZE) / 471 sizeof(struct kroute); 472 if (kr_change(imsg.data, count)) 473 log_warn("main_dispatch_rde: error changing " 474 "route"); 475 break; 476 case IMSG_KROUTE_DELETE: 477 if (kr_delete(imsg.data)) 478 log_warn("main_dispatch_rde: error deleting " 479 "route"); 480 break; 481 default: 482 log_debug("main_dispatch_rde: error handling imsg %d", 483 imsg.hdr.type); 484 break; 485 } 486 imsg_free(&imsg); 487 } 488 if (!shut) 489 imsg_event_add(iev); 490 else { 491 /* this pipe is dead, so remove the event handler */ 492 event_del(&iev->ev); 493 event_loopexit(NULL); 494 } 495 } 496 497 void 498 main_imsg_compose_ospfe(int type, pid_t pid, void *data, u_int16_t datalen) 499 { 500 if (iev_ospfe) 501 imsg_compose_event(iev_ospfe, type, 0, pid, -1, data, datalen); 502 } 503 504 void 505 main_imsg_compose_ospfe_fd(int type, pid_t pid, int fd) 506 { 507 if (iev_ospfe) 508 imsg_compose_event(iev_ospfe, type, 0, pid, fd, NULL, 0); 509 } 510 511 void 512 main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) 513 { 514 if (iev_rde) 515 imsg_compose_event(iev_rde, type, 0, pid, -1, data, datalen); 516 } 517 518 void 519 imsg_event_add(struct imsgev *iev) 520 { 521 iev->events = EV_READ; 522 if (iev->ibuf.w.queued) 523 iev->events |= EV_WRITE; 524 525 event_del(&iev->ev); 526 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 527 event_add(&iev->ev, NULL); 528 } 529 530 int 531 imsg_compose_event(struct imsgev *iev, u_int16_t type, u_int32_t peerid, 532 pid_t pid, int fd, void *data, u_int16_t datalen) 533 { 534 int ret; 535 536 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 537 pid, fd, data, datalen)) != -1) 538 imsg_event_add(iev); 539 return (ret); 540 } 541 542 int 543 ospf_redistribute(struct kroute *kr, u_int32_t *metric) 544 { 545 struct in_addr addr; 546 struct kif *kif; 547 struct redistribute *r; 548 int is_default, depend_ok; 549 550 bzero(&addr, sizeof(addr)); 551 552 /* only allow 0.0.0.0/0 via REDIST_DEFAULT */ 553 is_default = (kr->prefix.s_addr == INADDR_ANY && kr->prefixlen == 0); 554 555 SIMPLEQ_FOREACH(r, &ospfd_conf->redist_list, entry) { 556 if (r->dependon[0] != '\0') { 557 if ((kif = kif_findname(r->dependon, addr, NULL))) 558 depend_ok = ifstate_is_up(kif); 559 else 560 depend_ok = 0; 561 } else 562 depend_ok = 1; 563 564 switch (r->type & ~REDIST_NO) { 565 case REDIST_LABEL: 566 if (kr->rtlabel == r->label) { 567 *metric = depend_ok ? r->metric : 568 r->metric | MAX_METRIC; 569 return (r->type & REDIST_NO ? 0 : 1); 570 } 571 break; 572 case REDIST_STATIC: 573 /* 574 * Dynamic routes are not redistributable. Placed here 575 * so that link local addresses can be redistributed 576 * via a rtlabel. 577 */ 578 if (is_default) 579 continue; 580 if (kr->flags & F_DYNAMIC) 581 continue; 582 if (kr->flags & F_STATIC) { 583 *metric = depend_ok ? r->metric : 584 r->metric | MAX_METRIC; 585 return (r->type & REDIST_NO ? 0 : 1); 586 } 587 break; 588 case REDIST_CONNECTED: 589 if (is_default) 590 continue; 591 if (kr->flags & F_DYNAMIC) 592 continue; 593 if (kr->flags & F_CONNECTED) { 594 *metric = depend_ok ? r->metric : 595 r->metric | MAX_METRIC; 596 return (r->type & REDIST_NO ? 0 : 1); 597 } 598 break; 599 case REDIST_ADDR: 600 if (kr->flags & F_DYNAMIC) 601 continue; 602 603 if (r->addr.s_addr == INADDR_ANY && 604 r->mask.s_addr == INADDR_ANY) { 605 if (is_default) { 606 *metric = depend_ok ? r->metric : 607 r->metric | MAX_METRIC; 608 return (r->type & REDIST_NO ? 0 : 1); 609 } else 610 return (0); 611 } 612 613 if ((kr->prefix.s_addr & r->mask.s_addr) == 614 (r->addr.s_addr & r->mask.s_addr) && 615 kr->prefixlen >= mask2prefixlen(r->mask.s_addr)) { 616 *metric = depend_ok ? r->metric : 617 r->metric | MAX_METRIC; 618 return (r->type & REDIST_NO ? 0 : 1); 619 } 620 break; 621 case REDIST_DEFAULT: 622 if (is_default) { 623 *metric = depend_ok ? r->metric : 624 r->metric | MAX_METRIC; 625 return (r->type & REDIST_NO ? 0 : 1); 626 } 627 break; 628 } 629 } 630 631 return (0); 632 } 633 634 int 635 ospf_reload(void) 636 { 637 struct area *area; 638 struct iface *iface; 639 struct ospfd_conf *xconf; 640 struct redistribute *r; 641 642 if ((xconf = parse_config(conffile, ospfd_conf->opts)) == NULL) 643 return (-1); 644 645 /* Abort the reload if rtr_id changed */ 646 if (ospfd_conf->rtr_id.s_addr != xconf->rtr_id.s_addr) { 647 log_warnx("router-id changed: restart required"); 648 return (-1); 649 } 650 651 /* send config to childs */ 652 if (ospf_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1) 653 return (-1); 654 655 /* send interfaces */ 656 LIST_FOREACH(area, &xconf->area_list, entry) { 657 if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1) 658 return (-1); 659 660 SIMPLEQ_FOREACH(r, &area->redist_list, entry) { 661 main_imsg_compose_rde(IMSG_RECONF_REDIST, 0, r, 662 sizeof(*r)); 663 } 664 LIST_FOREACH(iface, &area->iface_list, entry) { 665 if (ospf_sendboth(IMSG_RECONF_IFACE, iface, 666 sizeof(*iface)) == -1) 667 return (-1); 668 if (iface->auth_type == AUTH_CRYPT) 669 if (md_list_send(&iface->auth_md_list, 670 iev_ospfe) == -1) 671 return (-1); 672 } 673 } 674 675 if (ospf_sendboth(IMSG_RECONF_END, NULL, 0) == -1) 676 return (-1); 677 678 merge_config(ospfd_conf, xconf); 679 /* update redistribute lists */ 680 kr_reload(ospfd_conf->redist_label_or_prefix); 681 return (0); 682 } 683 684 int 685 ospf_sendboth(enum imsg_type type, void *buf, u_int16_t len) 686 { 687 if (imsg_compose_event(iev_ospfe, type, 0, 0, -1, buf, len) == -1) 688 return (-1); 689 if (imsg_compose_event(iev_rde, type, 0, 0, -1, buf, len) == -1) 690 return (-1); 691 return (0); 692 } 693 694 void 695 merge_config(struct ospfd_conf *conf, struct ospfd_conf *xconf) 696 { 697 struct area *a, *xa, *na; 698 struct iface *iface; 699 struct redistribute *r; 700 int rchange = 0; 701 702 conf->flags = xconf->flags; 703 conf->spf_delay = xconf->spf_delay; 704 conf->spf_hold_time = xconf->spf_hold_time; 705 if (SIMPLEQ_EMPTY(&conf->redist_list) != 706 SIMPLEQ_EMPTY(&xconf->redist_list)) 707 rchange = 1; 708 conf->rfc1583compat = xconf->rfc1583compat; 709 conf->redist_label_or_prefix = xconf->redist_label_or_prefix; 710 711 if (ospfd_process == PROC_MAIN) { 712 /* main process does neither use areas nor interfaces */ 713 while ((r = SIMPLEQ_FIRST(&conf->redist_list)) != NULL) { 714 SIMPLEQ_REMOVE_HEAD(&conf->redist_list, entry); 715 free(r); 716 } 717 while ((r = SIMPLEQ_FIRST(&xconf->redist_list)) != NULL) { 718 SIMPLEQ_REMOVE_HEAD(&xconf->redist_list, entry); 719 SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry); 720 } 721 722 /* adjust FIB priority if changed */ 723 if (conf->fib_priority != xconf->fib_priority) { 724 kr_fib_decouple(); 725 kr_fib_update_prio(xconf->fib_priority); 726 conf->fib_priority = xconf->fib_priority; 727 kr_fib_couple(); 728 } 729 730 goto done; 731 } 732 733 /* merge areas and interfaces */ 734 for (a = LIST_FIRST(&conf->area_list); a != NULL; a = na) { 735 na = LIST_NEXT(a, entry); 736 /* find deleted areas */ 737 if ((xa = area_find(xconf, a->id)) == NULL) { 738 if (ospfd_process == PROC_OSPF_ENGINE) { 739 LIST_FOREACH(iface, &a->iface_list, entry) 740 if_fsm(iface, IF_EVT_DOWN); 741 } 742 LIST_REMOVE(a, entry); 743 area_del(a); 744 } 745 } 746 747 for (xa = LIST_FIRST(&xconf->area_list); xa != NULL; xa = na) { 748 na = LIST_NEXT(xa, entry); 749 if ((a = area_find(conf, xa->id)) == NULL) { 750 LIST_REMOVE(xa, entry); 751 LIST_INSERT_HEAD(&conf->area_list, xa, entry); 752 if (ospfd_process == PROC_OSPF_ENGINE) { 753 /* start interfaces */ 754 ospfe_demote_area(xa, 0); 755 LIST_FOREACH(iface, &xa->iface_list, entry) { 756 if_init(conf, iface); 757 if (if_fsm(iface, IF_EVT_UP)) { 758 log_debug("error starting " 759 "interface %s", 760 iface->name); 761 } 762 } 763 } 764 /* no need to merge interfaces */ 765 continue; 766 } 767 /* 768 * stub is not yet used but switching between stub and normal 769 * will be another painful job. 770 */ 771 if (a->stub != xa->stub && ospfd_process == PROC_OSPF_ENGINE) 772 a->dirty = 1; /* force rtr LSA update */ 773 if (xa->stub && ospfd_process == PROC_RDE_ENGINE) { 774 while ((r = SIMPLEQ_FIRST(&a->redist_list)) != NULL) { 775 SIMPLEQ_REMOVE_HEAD(&a->redist_list, entry); 776 free(r); 777 } 778 779 while ((r = SIMPLEQ_FIRST(&xa->redist_list)) != NULL) { 780 SIMPLEQ_REMOVE_HEAD(&xa->redist_list, entry); 781 SIMPLEQ_INSERT_TAIL(&a->redist_list, r, entry); 782 } 783 } 784 785 a->stub = xa->stub; 786 a->stub_default_cost = xa->stub_default_cost; 787 if (ospfd_process == PROC_RDE_ENGINE) 788 a->dirty = 1; /* force SPF tree recalculation */ 789 790 /* merge interfaces */ 791 if (merge_interfaces(a, xa) && 792 ospfd_process == PROC_OSPF_ENGINE) 793 a->dirty = 1; /* force rtr LSA update */ 794 } 795 796 if (ospfd_process == PROC_OSPF_ENGINE) { 797 LIST_FOREACH(a, &conf->area_list, entry) { 798 LIST_FOREACH(iface, &a->iface_list, entry) { 799 if (iface->state == IF_STA_NEW) { 800 iface->state = IF_STA_DOWN; 801 if_init(conf, iface); 802 if (if_fsm(iface, IF_EVT_UP)) { 803 log_debug("error starting " 804 "interface %s", 805 iface->name); 806 } 807 } 808 } 809 if (a->dirty || rchange) { 810 a->dirty = 0; 811 orig_rtr_lsa(a); 812 } 813 } 814 } 815 if (ospfd_process == PROC_RDE_ENGINE) { 816 LIST_FOREACH(a, &conf->area_list, entry) { 817 if (a->dirty) { 818 start_spf_timer(); 819 break; 820 } 821 } 822 } 823 824 done: 825 while ((a = LIST_FIRST(&xconf->area_list)) != NULL) { 826 LIST_REMOVE(a, entry); 827 area_del(a); 828 } 829 free(xconf); 830 } 831 832 int 833 merge_interfaces(struct area *a, struct area *xa) 834 { 835 struct iface *i, *xi, *ni; 836 int dirty = 0; 837 838 /* problems: 839 * - new interfaces (easy) 840 * - deleted interfaces 841 * - changing passive (painful?) 842 */ 843 for (i = LIST_FIRST(&a->iface_list); i != NULL; i = ni) { 844 ni = LIST_NEXT(i, entry); 845 if (iface_lookup(xa, i) == NULL) { 846 log_debug("merge_interfaces: proc %d area %s removing " 847 "interface %s", ospfd_process, inet_ntoa(a->id), 848 i->name); 849 if (ospfd_process == PROC_OSPF_ENGINE) 850 if_fsm(i, IF_EVT_DOWN); 851 else if (ospfd_process == PROC_RDE_ENGINE) 852 rde_nbr_iface_del(i); 853 LIST_REMOVE(i, entry); 854 if_del(i); 855 dirty = 1; /* force rtr LSA update */ 856 } 857 } 858 859 for (xi = LIST_FIRST(&xa->iface_list); xi != NULL; xi = ni) { 860 ni = LIST_NEXT(xi, entry); 861 if ((i = iface_lookup(a, xi)) == NULL) { 862 /* new interface but delay initialisation */ 863 log_debug("merge_interfaces: proc %d area %s adding " 864 "interface %s", ospfd_process, inet_ntoa(a->id), 865 xi->name); 866 LIST_REMOVE(xi, entry); 867 LIST_INSERT_HEAD(&a->iface_list, xi, entry); 868 xi->area = a; 869 if (ospfd_process == PROC_OSPF_ENGINE) 870 xi->state = IF_STA_NEW; 871 continue; 872 } 873 log_debug("merge_interfaces: proc %d area %s merging " 874 "interface %s", ospfd_process, inet_ntoa(a->id), i->name); 875 i->dst = xi->dst; 876 i->abr_id = xi->abr_id; 877 i->baudrate = xi->baudrate; 878 i->dead_interval = xi->dead_interval; 879 i->mtu = xi->mtu; 880 i->transmit_delay = xi->transmit_delay; 881 i->hello_interval = xi->hello_interval; 882 i->rxmt_interval = xi->rxmt_interval; 883 if (i->metric != xi->metric) 884 dirty = 1; 885 i->metric = xi->metric; 886 i->priority = xi->priority; 887 if (i->self) 888 i->self->priority = i->priority; 889 i->flags = xi->flags; /* needed? */ 890 i->type = xi->type; /* needed? */ 891 i->if_type = xi->if_type; /* needed? */ 892 i->linkstate = xi->linkstate; /* needed? */ 893 894 i->auth_type = xi->auth_type; 895 strncpy(i->auth_key, xi->auth_key, MAX_SIMPLE_AUTH_LEN); 896 md_list_clr(&i->auth_md_list); 897 md_list_copy(&i->auth_md_list, &xi->auth_md_list); 898 899 if (i->passive != xi->passive) { 900 /* need to restart interface to cope with this change */ 901 if (ospfd_process == PROC_OSPF_ENGINE) 902 if_fsm(i, IF_EVT_DOWN); 903 i->passive = xi->passive; 904 if (ospfd_process == PROC_OSPF_ENGINE) 905 if_fsm(i, IF_EVT_UP); 906 } 907 908 strlcpy(i->dependon, xi->dependon, 909 sizeof(i->dependon)); 910 i->depend_ok = xi->depend_ok; 911 } 912 return (dirty); 913 } 914 915 struct iface * 916 iface_lookup(struct area *area, struct iface *iface) 917 { 918 struct iface *i; 919 920 LIST_FOREACH(i, &area->iface_list, entry) 921 if (i->ifindex == iface->ifindex && 922 i->addr.s_addr == iface->addr.s_addr && 923 i->mask.s_addr == iface->mask.s_addr) 924 return (i); 925 return (NULL); 926 } 927 928 int 929 ifstate_is_up(struct kif *kif) 930 { 931 if (!(kif->flags & IFF_UP)) 932 return (0); 933 if (kif->if_type == IFT_CARP && 934 kif->link_state == LINK_STATE_UNKNOWN) 935 return (0); 936 return LINK_STATE_IS_UP(kif->link_state); 937 } 938