ldpd.c revision 1.47
1/* $OpenBSD: ldpd.c,v 1.47 2016/05/23 19:14:03 renato Exp $ */ 2 3/* 4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> 5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004, 2008 Esben Norby <norby@openbsd.org> 7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22#include <sys/types.h> 23#include <sys/wait.h> 24#include <err.h> 25#include <errno.h> 26#include <pwd.h> 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <signal.h> 31#include <unistd.h> 32 33#include "ldpd.h" 34#include "ldpe.h" 35#include "lde.h" 36#include "log.h" 37 38static void main_sig_handler(int, short, void *); 39static __dead void usage(void); 40static void ldpd_shutdown(void); 41static int check_child(pid_t, const char *); 42static void main_dispatch_ldpe(int, short, void *); 43static void main_dispatch_lde(int, short, void *); 44static int main_imsg_compose_both(enum imsg_type, void *, 45 uint16_t); 46static void main_imsg_send_net_sockets(int); 47static void main_imsg_send_net_socket(int, enum socket_type); 48static int ldp_reload(void); 49static void merge_global(struct ldpd_conf *, struct ldpd_conf *); 50static void merge_af(int, struct ldpd_af_conf *, 51 struct ldpd_af_conf *); 52static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *); 53static void merge_iface_af(struct iface_af *, struct iface_af *); 54static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *); 55static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *); 56static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *); 57static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *, 58 struct l2vpn *); 59 60struct ldpd_global global; 61struct ldpd_conf *ldpd_conf; 62 63static char *conffile; 64static int pipe_parent2ldpe[2]; 65static int pipe_parent2lde[2]; 66static int pipe_ldpe2lde[2]; 67static struct imsgev *iev_ldpe; 68static struct imsgev *iev_lde; 69static pid_t ldpe_pid; 70static pid_t lde_pid; 71 72/* ARGSUSED */ 73static void 74main_sig_handler(int sig, short event, void *arg) 75{ 76 /* 77 * signal handler rules don't apply, libevent decouples for us 78 */ 79 80 int die = 0; 81 82 switch (sig) { 83 case SIGTERM: 84 case SIGINT: 85 die = 1; 86 /* FALLTHROUGH */ 87 case SIGCHLD: 88 if (check_child(ldpe_pid, "ldp engine")) { 89 ldpe_pid = 0; 90 die = 1; 91 } 92 if (check_child(lde_pid, "label decision engine")) { 93 lde_pid = 0; 94 die = 1; 95 } 96 if (die) 97 ldpd_shutdown(); 98 break; 99 case SIGHUP: 100 if (ldp_reload() == -1) 101 log_warnx("configuration reload failed"); 102 else 103 log_debug("configuration reloaded"); 104 break; 105 default: 106 fatalx("unexpected signal"); 107 /* NOTREACHED */ 108 } 109} 110 111static __dead void 112usage(void) 113{ 114 extern char *__progname; 115 116 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 117 __progname); 118 exit(1); 119} 120 121int 122main(int argc, char *argv[]) 123{ 124 struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; 125 int ch; 126 int debug = 0; 127 128 conffile = CONF_FILE; 129 ldpd_process = PROC_MAIN; 130 131 log_init(1); /* log to stderr until daemonized */ 132 log_verbose(1); 133 134 while ((ch = getopt(argc, argv, "dD:f:nv")) != -1) { 135 switch (ch) { 136 case 'd': 137 debug = 1; 138 break; 139 case 'D': 140 if (cmdline_symset(optarg) < 0) 141 log_warnx("could not parse macro definition %s", 142 optarg); 143 break; 144 case 'f': 145 conffile = optarg; 146 break; 147 case 'n': 148 global.cmd_opts |= LDPD_OPT_NOACTION; 149 break; 150 case 'v': 151 if (global.cmd_opts & LDPD_OPT_VERBOSE) 152 global.cmd_opts |= LDPD_OPT_VERBOSE2; 153 global.cmd_opts |= LDPD_OPT_VERBOSE; 154 break; 155 default: 156 usage(); 157 /* NOTREACHED */ 158 } 159 } 160 161 /* fetch interfaces early */ 162 kif_init(); 163 164 /* parse config file */ 165 if ((ldpd_conf = parse_config(conffile)) == NULL ) { 166 kif_clear(); 167 exit(1); 168 } 169 170 if (global.cmd_opts & LDPD_OPT_NOACTION) { 171 if (global.cmd_opts & LDPD_OPT_VERBOSE) 172 print_config(ldpd_conf); 173 else 174 fprintf(stderr, "configuration OK\n"); 175 kif_clear(); 176 exit(0); 177 } 178 179 /* check for root privileges */ 180 if (geteuid()) 181 errx(1, "need root privileges"); 182 183 /* check for ldpd user */ 184 if (getpwnam(LDPD_USER) == NULL) 185 errx(1, "unknown user %s", LDPD_USER); 186 187 log_init(debug); 188 log_verbose(global.cmd_opts & (LDPD_OPT_VERBOSE | LDPD_OPT_VERBOSE2)); 189 190 if (!debug) 191 daemon(1, 0); 192 193 log_info("startup"); 194 195 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 196 PF_UNSPEC, pipe_parent2ldpe) == -1) 197 fatal("socketpair"); 198 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 199 PF_UNSPEC, pipe_parent2lde) == -1) 200 fatal("socketpair"); 201 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 202 PF_UNSPEC, pipe_ldpe2lde) == -1) 203 fatal("socketpair"); 204 205 /* start children */ 206 lde_pid = lde(ldpd_conf, pipe_parent2lde, pipe_ldpe2lde, 207 pipe_parent2ldpe); 208 ldpe_pid = ldpe(ldpd_conf, pipe_parent2ldpe, pipe_ldpe2lde, 209 pipe_parent2lde); 210 211 event_init(); 212 213 /* setup signal handler */ 214 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 215 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 216 signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL); 217 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 218 signal_add(&ev_sigint, NULL); 219 signal_add(&ev_sigterm, NULL); 220 signal_add(&ev_sigchld, NULL); 221 signal_add(&ev_sighup, NULL); 222 signal(SIGPIPE, SIG_IGN); 223 224 /* setup pipes to children */ 225 close(pipe_parent2ldpe[1]); 226 close(pipe_parent2lde[1]); 227 close(pipe_ldpe2lde[0]); 228 close(pipe_ldpe2lde[1]); 229 230 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL || 231 (iev_lde = malloc(sizeof(struct imsgev))) == NULL) 232 fatal(NULL); 233 imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]); 234 iev_ldpe->handler = main_dispatch_ldpe; 235 imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]); 236 iev_lde->handler = main_dispatch_lde; 237 238 /* setup event handler */ 239 iev_ldpe->events = EV_READ; 240 event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events, 241 iev_ldpe->handler, iev_ldpe); 242 event_add(&iev_ldpe->ev, NULL); 243 244 iev_lde->events = EV_READ; 245 event_set(&iev_lde->ev, iev_lde->ibuf.fd, iev_lde->events, 246 iev_lde->handler, iev_lde); 247 event_add(&iev_lde->ev, NULL); 248 249 /* notify ldpe about existing interfaces and addresses */ 250 kif_redistribute(NULL); 251 252 if (kr_init(!(ldpd_conf->flags & F_LDPD_NO_FIB_UPDATE)) == -1) 253 fatalx("kr_init failed"); 254 255 main_imsg_send_net_sockets(AF_INET); 256 main_imsg_send_net_sockets(AF_INET6); 257 258 /* remove unneded stuff from config */ 259 /* ... */ 260 261 event_dispatch(); 262 263 ldpd_shutdown(); 264 /* NOTREACHED */ 265 return (0); 266} 267 268static void 269ldpd_shutdown(void) 270{ 271 pid_t pid; 272 273 if (ldpe_pid) 274 kill(ldpe_pid, SIGTERM); 275 276 if (lde_pid) 277 kill(lde_pid, SIGTERM); 278 279 kr_shutdown(); 280 281 do { 282 if ((pid = wait(NULL)) == -1 && 283 errno != EINTR && errno != ECHILD) 284 fatal("wait"); 285 } while (pid != -1 || (pid == -1 && errno == EINTR)); 286 287 config_clear(ldpd_conf); 288 289 msgbuf_clear(&iev_ldpe->ibuf.w); 290 free(iev_ldpe); 291 msgbuf_clear(&iev_lde->ibuf.w); 292 free(iev_lde); 293 294 log_info("terminating"); 295 exit(0); 296} 297 298static int 299check_child(pid_t pid, const char *pname) 300{ 301 int status; 302 303 if (waitpid(pid, &status, WNOHANG) > 0) { 304 if (WIFEXITED(status)) { 305 log_warnx("lost child: %s exited", pname); 306 return (1); 307 } 308 if (WIFSIGNALED(status)) { 309 log_warnx("lost child: %s terminated; signal %d", 310 pname, WTERMSIG(status)); 311 return (1); 312 } 313 } 314 315 return (0); 316} 317 318/* imsg handling */ 319/* ARGSUSED */ 320static void 321main_dispatch_ldpe(int fd, short event, void *bula) 322{ 323 struct imsgev *iev = bula; 324 struct imsgbuf *ibuf = &iev->ibuf; 325 struct imsg imsg; 326 int af; 327 ssize_t n; 328 int shut = 0, verbose; 329 330 if (event & EV_READ) { 331 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 332 fatal("imsg_read error"); 333 if (n == 0) /* connection closed */ 334 shut = 1; 335 } 336 if (event & EV_WRITE) { 337 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 338 fatal("msgbuf_write"); 339 if (n == 0) 340 shut = 1; 341 } 342 343 for (;;) { 344 if ((n = imsg_get(ibuf, &imsg)) == -1) 345 fatal("imsg_get"); 346 347 if (n == 0) 348 break; 349 350 switch (imsg.hdr.type) { 351 case IMSG_REQUEST_SOCKETS: 352 af = imsg.hdr.peerid; 353 main_imsg_send_net_sockets(af); 354 break; 355 case IMSG_CTL_RELOAD: 356 if (ldp_reload() == -1) 357 log_warnx("configuration reload failed"); 358 else 359 log_debug("configuration reloaded"); 360 break; 361 case IMSG_CTL_FIB_COUPLE: 362 kr_fib_couple(); 363 break; 364 case IMSG_CTL_FIB_DECOUPLE: 365 kr_fib_decouple(); 366 break; 367 case IMSG_CTL_KROUTE: 368 case IMSG_CTL_KROUTE_ADDR: 369 kr_show_route(&imsg); 370 break; 371 case IMSG_CTL_IFINFO: 372 if (imsg.hdr.len == IMSG_HEADER_SIZE) 373 kr_ifinfo(NULL, imsg.hdr.pid); 374 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 375 kr_ifinfo(imsg.data, imsg.hdr.pid); 376 else 377 log_warnx("IFINFO request with wrong len"); 378 break; 379 case IMSG_CTL_LOG_VERBOSE: 380 /* already checked by ldpe */ 381 memcpy(&verbose, imsg.data, sizeof(verbose)); 382 log_verbose(verbose); 383 break; 384 default: 385 log_debug("%s: error handling imsg %d", __func__, 386 imsg.hdr.type); 387 break; 388 } 389 imsg_free(&imsg); 390 } 391 if (!shut) 392 imsg_event_add(iev); 393 else { 394 /* this pipe is dead, so remove the event handler */ 395 event_del(&iev->ev); 396 event_loopexit(NULL); 397 } 398} 399 400/* ARGSUSED */ 401static void 402main_dispatch_lde(int fd, short event, void *bula) 403{ 404 struct imsgev *iev = bula; 405 struct imsgbuf *ibuf = &iev->ibuf; 406 struct imsg imsg; 407 ssize_t n; 408 int shut = 0; 409 410 if (event & EV_READ) { 411 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 412 fatal("imsg_read error"); 413 if (n == 0) /* connection closed */ 414 shut = 1; 415 } 416 if (event & EV_WRITE) { 417 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 418 fatal("msgbuf_write"); 419 if (n == 0) 420 shut = 1; 421 } 422 423 for (;;) { 424 if ((n = imsg_get(ibuf, &imsg)) == -1) 425 fatal("imsg_get"); 426 427 if (n == 0) 428 break; 429 430 switch (imsg.hdr.type) { 431 case IMSG_KLABEL_CHANGE: 432 if (imsg.hdr.len - IMSG_HEADER_SIZE != 433 sizeof(struct kroute)) 434 fatalx("invalid size of IMSG_KLABEL_CHANGE"); 435 if (kr_change(imsg.data)) 436 log_warn("%s: error changing route", __func__); 437 break; 438 case IMSG_KLABEL_DELETE: 439 if (imsg.hdr.len - IMSG_HEADER_SIZE != 440 sizeof(struct kroute)) 441 fatalx("invalid size of IMSG_KLABEL_DELETE"); 442 if (kr_delete(imsg.data)) 443 log_warn("%s: error deleting route", __func__); 444 break; 445 case IMSG_KPWLABEL_CHANGE: 446 if (imsg.hdr.len - IMSG_HEADER_SIZE != 447 sizeof(struct kpw)) 448 fatalx("invalid size of IMSG_KPWLABEL_CHANGE"); 449 if (kmpw_set(imsg.data)) 450 log_warn("%s: error changing pseudowire", 451 __func__); 452 break; 453 case IMSG_KPWLABEL_DELETE: 454 if (imsg.hdr.len - IMSG_HEADER_SIZE != 455 sizeof(struct kpw)) 456 fatalx("invalid size of IMSG_KPWLABEL_DELETE"); 457 if (kmpw_unset(imsg.data)) 458 log_warn("%s: error unsetting pseudowire", 459 __func__); 460 break; 461 default: 462 log_debug("%s: error handling imsg %d", __func__, 463 imsg.hdr.type); 464 break; 465 } 466 imsg_free(&imsg); 467 } 468 if (!shut) 469 imsg_event_add(iev); 470 else { 471 /* this pipe is dead, so remove the event handler */ 472 event_del(&iev->ev); 473 event_loopexit(NULL); 474 } 475} 476 477void 478main_imsg_compose_ldpe(int type, pid_t pid, void *data, uint16_t datalen) 479{ 480 if (iev_ldpe == NULL) 481 return; 482 imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen); 483} 484 485void 486main_imsg_compose_lde(int type, pid_t pid, void *data, uint16_t datalen) 487{ 488 imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen); 489} 490 491static int 492main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len) 493{ 494 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1) 495 return (-1); 496 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1) 497 return (-1); 498 return (0); 499} 500 501void 502imsg_event_add(struct imsgev *iev) 503{ 504 iev->events = EV_READ; 505 if (iev->ibuf.w.queued) 506 iev->events |= EV_WRITE; 507 508 event_del(&iev->ev); 509 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 510 event_add(&iev->ev, NULL); 511} 512 513int 514imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid, 515 pid_t pid, int fd, void *data, uint16_t datalen) 516{ 517 int ret; 518 519 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 520 pid, fd, data, datalen)) != -1) 521 imsg_event_add(iev); 522 return (ret); 523} 524 525void 526evbuf_enqueue(struct evbuf *eb, struct ibuf *buf) 527{ 528 ibuf_close(&eb->wbuf, buf); 529 evbuf_event_add(eb); 530} 531 532void 533evbuf_event_add(struct evbuf *eb) 534{ 535 if (eb->wbuf.queued) 536 event_add(&eb->ev, NULL); 537} 538 539void 540evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *), 541 void *arg) 542{ 543 msgbuf_init(&eb->wbuf); 544 eb->wbuf.fd = fd; 545 event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg); 546} 547 548void 549evbuf_clear(struct evbuf *eb) 550{ 551 event_del(&eb->ev); 552 msgbuf_clear(&eb->wbuf); 553 eb->wbuf.fd = -1; 554} 555 556static void 557main_imsg_send_net_sockets(int af) 558{ 559 main_imsg_send_net_socket(af, LDP_SOCKET_DISC); 560 main_imsg_send_net_socket(af, LDP_SOCKET_EDISC); 561 main_imsg_send_net_socket(af, LDP_SOCKET_SESSION); 562 imsg_compose_event(iev_ldpe, IMSG_SETUP_SOCKETS, af, 0, -1, NULL, 0); 563} 564 565static void 566main_imsg_send_net_socket(int af, enum socket_type type) 567{ 568 int fd; 569 570 fd = ldp_create_socket(af, type); 571 if (fd == -1) { 572 log_warnx("%s: failed to create %s socket for address-family " 573 "%s", __func__, socket_name(type), af_name(af)); 574 return; 575 } 576 577 imsg_compose_event(iev_ldpe, IMSG_SOCKET_NET, af, 0, fd, &type, 578 sizeof(type)); 579} 580 581struct ldpd_af_conf * 582ldp_af_conf_get(struct ldpd_conf *xconf, int af) 583{ 584 switch (af) { 585 case AF_INET: 586 return (&xconf->ipv4); 587 case AF_INET6: 588 return (&xconf->ipv6); 589 default: 590 fatalx("ldp_af_conf_get: unknown af"); 591 } 592} 593 594struct ldpd_af_global * 595ldp_af_global_get(struct ldpd_global *xglobal, int af) 596{ 597 switch (af) { 598 case AF_INET: 599 return (&xglobal->ipv4); 600 case AF_INET6: 601 return (&xglobal->ipv6); 602 default: 603 fatalx("ldp_af_global_get: unknown af"); 604 } 605} 606 607int 608ldp_is_dual_stack(struct ldpd_conf *xconf) 609{ 610 return ((xconf->ipv4.flags & F_LDPD_AF_ENABLED) && 611 (xconf->ipv6.flags & F_LDPD_AF_ENABLED)); 612} 613 614static int 615ldp_reload(void) 616{ 617 struct iface *iface; 618 struct tnbr *tnbr; 619 struct nbr_params *nbrp; 620 struct l2vpn *l2vpn; 621 struct l2vpn_if *lif; 622 struct l2vpn_pw *pw; 623 struct ldpd_conf *xconf; 624 625 if ((xconf = parse_config(conffile)) == NULL) 626 return (-1); 627 628 if (main_imsg_compose_both(IMSG_RECONF_CONF, xconf, 629 sizeof(*xconf)) == -1) 630 return (-1); 631 632 LIST_FOREACH(iface, &xconf->iface_list, entry) { 633 if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface, 634 sizeof(*iface)) == -1) 635 return (-1); 636 } 637 638 LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) { 639 if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr, 640 sizeof(*tnbr)) == -1) 641 return (-1); 642 } 643 644 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) { 645 if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp, 646 sizeof(*nbrp)) == -1) 647 return (-1); 648 } 649 650 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) { 651 if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn, 652 sizeof(*l2vpn)) == -1) 653 return (-1); 654 655 LIST_FOREACH(lif, &l2vpn->if_list, entry) { 656 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif, 657 sizeof(*lif)) == -1) 658 return (-1); 659 } 660 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 661 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw, 662 sizeof(*pw)) == -1) 663 return (-1); 664 } 665 } 666 667 if (main_imsg_compose_both(IMSG_RECONF_END, NULL, 0) == -1) 668 return (-1); 669 670 merge_config(ldpd_conf, xconf); 671 672 return (0); 673} 674 675void 676merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) 677{ 678 merge_global(conf, xconf); 679 merge_af(AF_INET, &conf->ipv4, &xconf->ipv4); 680 merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6); 681 merge_ifaces(conf, xconf); 682 merge_tnbrs(conf, xconf); 683 merge_nbrps(conf, xconf); 684 merge_l2vpns(conf, xconf); 685 free(xconf); 686} 687 688static void 689merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf) 690{ 691 /* change of router-id requires resetting all neighborships */ 692 if (conf->rtr_id.s_addr != xconf->rtr_id.s_addr) { 693 if (ldpd_process == PROC_LDP_ENGINE) { 694 ldpe_reset_nbrs(AF_INET); 695 ldpe_reset_nbrs(AF_INET6); 696 if (conf->rtr_id.s_addr == INADDR_ANY || 697 xconf->rtr_id.s_addr == INADDR_ANY) { 698 if_update_all(AF_UNSPEC); 699 tnbr_update_all(AF_UNSPEC); 700 } 701 } 702 conf->rtr_id = xconf->rtr_id; 703 } 704 705 if (conf->trans_pref != xconf->trans_pref) { 706 if (ldpd_process == PROC_LDP_ENGINE) 707 ldpe_reset_ds_nbrs(); 708 conf->trans_pref = xconf->trans_pref; 709 } 710 711 if ((conf->flags & F_LDPD_DS_CISCO_INTEROP) != 712 (xconf->flags & F_LDPD_DS_CISCO_INTEROP)) { 713 if (ldpd_process == PROC_LDP_ENGINE) 714 ldpe_reset_ds_nbrs(); 715 } 716 717 conf->flags = xconf->flags; 718} 719 720static void 721merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa) 722{ 723 struct nbr *nbr; 724 struct nbr_params *nbrp; 725 int egress_label_changed = 0; 726 727 if (af_conf->keepalive != xa->keepalive) { 728 af_conf->keepalive = xa->keepalive; 729 if (ldpd_process == PROC_LDP_ENGINE) 730 ldpe_stop_init_backoff(af); 731 } 732 af_conf->thello_holdtime = xa->thello_holdtime; 733 af_conf->thello_interval = xa->thello_interval; 734 735 /* update flags */ 736 if (ldpd_process == PROC_LDP_ENGINE && 737 (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) && 738 !(xa->flags & F_LDPD_AF_THELLO_ACCEPT)) 739 ldpe_remove_dynamic_tnbrs(af); 740 741 if ((af_conf->flags & F_LDPD_AF_EXPNULL) != 742 (xa->flags & F_LDPD_AF_EXPNULL)) 743 egress_label_changed = 1; 744 745 af_conf->flags = xa->flags; 746 747 if (egress_label_changed) { 748 switch (ldpd_process) { 749 case PROC_LDE_ENGINE: 750 lde_change_egress_label(af, af_conf->flags & 751 F_LDPD_AF_EXPNULL); 752 break; 753 case PROC_MAIN: 754 kr_change_egress_label(af, af_conf->flags & 755 F_LDPD_AF_EXPNULL); 756 break; 757 default: 758 break; 759 } 760 } 761 762 if (ldp_addrcmp(af, &af_conf->trans_addr, &xa->trans_addr)) { 763 af_conf->trans_addr = xa->trans_addr; 764 if (ldpd_process == PROC_MAIN) 765 imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 766 0, -1, NULL, 0); 767 if (ldpd_process == PROC_LDP_ENGINE) { 768 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 769 if (nbr->af != af) 770 continue; 771 772 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 773 774 pfkey_remove(nbr); 775 nbr->laddr = af_conf->trans_addr; 776 nbrp = nbr_params_find(leconf, nbr->id); 777 if (nbrp && pfkey_establish(nbr, nbrp) == -1) 778 fatalx("pfkey setup failed"); 779 } 780 } 781 } 782} 783 784static void 785merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf) 786{ 787 struct iface *iface, *itmp, *xi; 788 789 LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) { 790 /* find deleted interfaces */ 791 if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) { 792 LIST_REMOVE(iface, entry); 793 if (ldpd_process == PROC_LDP_ENGINE) 794 if_del(iface); 795 else 796 free(iface); 797 } 798 } 799 LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) { 800 /* find new interfaces */ 801 if ((iface = if_lookup(conf, xi->ifindex)) == NULL) { 802 LIST_REMOVE(xi, entry); 803 LIST_INSERT_HEAD(&conf->iface_list, xi, entry); 804 805 /* resend addresses to activate new interfaces */ 806 if (ldpd_process == PROC_MAIN) 807 kif_redistribute(xi->name); 808 continue; 809 } 810 811 /* update existing interfaces */ 812 merge_iface_af(&iface->ipv4, &xi->ipv4); 813 merge_iface_af(&iface->ipv6, &xi->ipv6); 814 LIST_REMOVE(xi, entry); 815 free(xi); 816 } 817} 818 819static void 820merge_iface_af(struct iface_af *ia, struct iface_af *xi) 821{ 822 if (ia->enabled != xi->enabled) { 823 ia->enabled = xi->enabled; 824 if (ldpd_process == PROC_LDP_ENGINE) 825 if_update(ia->iface, ia->af); 826 } 827 ia->hello_holdtime = xi->hello_holdtime; 828 ia->hello_interval = xi->hello_interval; 829} 830 831static void 832merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf) 833{ 834 struct tnbr *tnbr, *ttmp, *xt; 835 836 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) { 837 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 838 continue; 839 840 /* find deleted tnbrs */ 841 if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) { 842 if (ldpd_process == PROC_LDP_ENGINE) { 843 tnbr->flags &= ~F_TNBR_CONFIGURED; 844 tnbr_check(tnbr); 845 } else { 846 LIST_REMOVE(tnbr, entry); 847 free(tnbr); 848 } 849 } 850 } 851 LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) { 852 /* find new tnbrs */ 853 if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) { 854 LIST_REMOVE(xt, entry); 855 LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry); 856 857 if (ldpd_process == PROC_LDP_ENGINE) 858 tnbr_update(xt); 859 continue; 860 } 861 862 /* update existing tnbrs */ 863 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 864 tnbr->flags |= F_TNBR_CONFIGURED; 865 tnbr->hello_holdtime = xt->hello_holdtime; 866 tnbr->hello_interval = xt->hello_interval; 867 LIST_REMOVE(xt, entry); 868 free(xt); 869 } 870} 871 872static void 873merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf) 874{ 875 struct nbr_params *nbrp, *ntmp, *xn; 876 struct nbr *nbr; 877 int nbrp_changed; 878 879 LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) { 880 /* find deleted nbrps */ 881 if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) { 882 if (ldpd_process == PROC_LDP_ENGINE) { 883 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr); 884 if (nbr) { 885 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 886 pfkey_remove(nbr); 887 } 888 } 889 LIST_REMOVE(nbrp, entry); 890 free(nbrp); 891 } 892 } 893 LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) { 894 /* find new nbrps */ 895 if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) { 896 LIST_REMOVE(xn, entry); 897 LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry); 898 899 if (ldpd_process == PROC_LDP_ENGINE) { 900 nbr = nbr_find_ldpid(xn->lsr_id.s_addr); 901 if (nbr) { 902 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 903 if (pfkey_establish(nbr, xn) == -1) 904 fatalx("pfkey setup failed"); 905 } 906 } 907 continue; 908 } 909 910 /* update existing nbrps */ 911 if (nbrp->keepalive != xn->keepalive || 912 nbrp->auth.method != xn->auth.method || 913 strcmp(nbrp->auth.md5key, xn->auth.md5key) != 0) 914 nbrp_changed = 1; 915 else 916 nbrp_changed = 0; 917 918 nbrp->keepalive = xn->keepalive; 919 nbrp->auth.method = xn->auth.method; 920 strlcpy(nbrp->auth.md5key, xn->auth.md5key, 921 sizeof(nbrp->auth.md5key)); 922 nbrp->auth.md5key_len = xn->auth.md5key_len; 923 nbrp->flags = xn->flags; 924 925 if (ldpd_process == PROC_LDP_ENGINE) { 926 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr); 927 if (nbr && nbrp_changed) { 928 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 929 pfkey_remove(nbr); 930 if (pfkey_establish(nbr, nbrp) == -1) 931 fatalx("pfkey setup failed"); 932 } 933 } 934 LIST_REMOVE(xn, entry); 935 free(xn); 936 } 937} 938 939static void 940merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf) 941{ 942 struct l2vpn *l2vpn, *ltmp, *xl; 943 944 LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) { 945 /* find deleted l2vpns */ 946 if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) { 947 LIST_REMOVE(l2vpn, entry); 948 949 switch (ldpd_process) { 950 case PROC_LDE_ENGINE: 951 l2vpn_del(l2vpn); 952 break; 953 case PROC_LDP_ENGINE: 954 ldpe_l2vpn_exit(l2vpn); 955 free(l2vpn); 956 break; 957 case PROC_MAIN: 958 free(l2vpn); 959 break; 960 } 961 } 962 } 963 LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) { 964 /* find new l2vpns */ 965 if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) { 966 LIST_REMOVE(xl, entry); 967 LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry); 968 969 switch (ldpd_process) { 970 case PROC_LDE_ENGINE: 971 l2vpn_init(xl); 972 break; 973 case PROC_LDP_ENGINE: 974 ldpe_l2vpn_init(xl); 975 break; 976 case PROC_MAIN: 977 break; 978 } 979 continue; 980 } 981 982 /* update existing l2vpns */ 983 merge_l2vpn(conf, l2vpn, xl); 984 LIST_REMOVE(xl, entry); 985 free(xl); 986 } 987} 988 989static void 990merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl) 991{ 992 struct l2vpn_if *lif, *ftmp, *xf; 993 struct l2vpn_pw *pw, *ptmp, *xp; 994 struct nbr *nbr; 995 int reset_nbr, reinstall_pwfec, reinstall_tnbr; 996 int previous_pw_type, previous_mtu; 997 998 previous_pw_type = l2vpn->pw_type; 999 previous_mtu = l2vpn->mtu; 1000 1001 /* merge intefaces */ 1002 LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) { 1003 /* find deleted interfaces */ 1004 if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) { 1005 LIST_REMOVE(lif, entry); 1006 free(lif); 1007 } 1008 } 1009 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) { 1010 /* find new interfaces */ 1011 if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) { 1012 LIST_REMOVE(xf, entry); 1013 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry); 1014 xf->l2vpn = l2vpn; 1015 continue; 1016 } 1017 1018 LIST_REMOVE(xf, entry); 1019 free(xf); 1020 } 1021 1022 /* merge pseudowires */ 1023 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) { 1024 /* find deleted pseudowires */ 1025 if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) { 1026 switch (ldpd_process) { 1027 case PROC_LDE_ENGINE: 1028 l2vpn_pw_exit(pw); 1029 break; 1030 case PROC_LDP_ENGINE: 1031 ldpe_l2vpn_pw_exit(pw); 1032 break; 1033 case PROC_MAIN: 1034 break; 1035 } 1036 1037 LIST_REMOVE(pw, entry); 1038 free(pw); 1039 } 1040 } 1041 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) { 1042 /* find new pseudowires */ 1043 if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) { 1044 LIST_REMOVE(xp, entry); 1045 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); 1046 xp->l2vpn = l2vpn; 1047 1048 switch (ldpd_process) { 1049 case PROC_LDE_ENGINE: 1050 l2vpn_pw_init(xp); 1051 break; 1052 case PROC_LDP_ENGINE: 1053 ldpe_l2vpn_pw_init(xp); 1054 break; 1055 case PROC_MAIN: 1056 break; 1057 } 1058 continue; 1059 } 1060 1061 /* update existing pseudowire */ 1062 if (pw->af != xp->af || 1063 ldp_addrcmp(pw->af, &pw->addr, &xp->addr)) 1064 reinstall_tnbr = 1; 1065 else 1066 reinstall_tnbr = 0; 1067 1068 /* changes that require a session restart */ 1069 if ((pw->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)) != 1070 (xp->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF))) 1071 reset_nbr = 1; 1072 else 1073 reset_nbr = 0; 1074 1075 if (l2vpn->pw_type != xl->pw_type || l2vpn->mtu != xl->mtu || 1076 pw->pwid != xp->pwid || reinstall_tnbr || reset_nbr || 1077 pw->lsr_id.s_addr != xp->lsr_id.s_addr) 1078 reinstall_pwfec = 1; 1079 else 1080 reinstall_pwfec = 0; 1081 1082 if (ldpd_process == PROC_LDP_ENGINE) { 1083 if (reinstall_tnbr) 1084 ldpe_l2vpn_pw_exit(pw); 1085 if (reset_nbr) { 1086 nbr = nbr_find_ldpid(pw->lsr_id.s_addr); 1087 if (nbr && nbr->state == NBR_STA_OPER) 1088 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 1089 } 1090 } 1091 if (ldpd_process == PROC_LDE_ENGINE && 1092 !reset_nbr && reinstall_pwfec) 1093 l2vpn_pw_exit(pw); 1094 pw->lsr_id = xp->lsr_id; 1095 pw->af = xp->af; 1096 pw->addr = xp->addr; 1097 pw->pwid = xp->pwid; 1098 strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname)); 1099 pw->ifindex = xp->ifindex; 1100 if (xp->flags & F_PW_CWORD_CONF) 1101 pw->flags |= F_PW_CWORD_CONF; 1102 else 1103 pw->flags &= ~F_PW_CWORD_CONF; 1104 if (xp->flags & F_PW_STATUSTLV_CONF) 1105 pw->flags |= F_PW_STATUSTLV_CONF; 1106 else 1107 pw->flags &= ~F_PW_STATUSTLV_CONF; 1108 if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr) 1109 ldpe_l2vpn_pw_init(pw); 1110 if (ldpd_process == PROC_LDE_ENGINE && 1111 !reset_nbr && reinstall_pwfec) { 1112 l2vpn->pw_type = xl->pw_type; 1113 l2vpn->mtu = xl->mtu; 1114 l2vpn_pw_init(pw); 1115 l2vpn->pw_type = previous_pw_type; 1116 l2vpn->mtu = previous_mtu; 1117 } 1118 1119 LIST_REMOVE(xp, entry); 1120 free(xp); 1121 } 1122 1123 l2vpn->pw_type = xl->pw_type; 1124 l2vpn->mtu = xl->mtu; 1125 strlcpy(l2vpn->br_ifname, xl->br_ifname, sizeof(l2vpn->br_ifname)); 1126 l2vpn->br_ifindex = xl->br_ifindex; 1127} 1128 1129void 1130config_clear(struct ldpd_conf *conf) 1131{ 1132 struct ldpd_conf *xconf; 1133 1134 /* merge current config with an empty config */ 1135 xconf = malloc(sizeof(*xconf)); 1136 if (xconf == NULL) 1137 fatal(NULL); 1138 1139 *xconf = *conf; 1140 LIST_INIT(&xconf->iface_list); 1141 LIST_INIT(&xconf->tnbr_list); 1142 LIST_INIT(&xconf->nbrp_list); 1143 LIST_INIT(&xconf->l2vpn_list); 1144 merge_config(conf, xconf); 1145 1146 free(conf); 1147} 1148