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