ldpd.c revision 1.30
1/* $OpenBSD: ldpd.c,v 1.30 2016/05/23 15:41:04 renato Exp $ */ 2 3/* 4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2004, 2008 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 28#include <netinet/in.h> 29#include <arpa/inet.h> 30#include <netmpls/mpls.h> 31 32#include <event.h> 33#include <err.h> 34#include <errno.h> 35#include <pwd.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39#include <signal.h> 40#include <unistd.h> 41 42#include "ldpd.h" 43#include "ldp.h" 44#include "ldpe.h" 45#include "control.h" 46#include "log.h" 47#include "lde.h" 48 49void main_sig_handler(int, short, void *); 50__dead void usage(void); 51void ldpd_shutdown(void); 52int check_child(pid_t, const char *); 53 54void main_dispatch_ldpe(int, short, void *); 55void main_dispatch_lde(int, short, void *); 56 57int ldp_reload(void); 58int ldp_sendboth(enum imsg_type, void *, u_int16_t); 59void merge_l2vpns(struct ldpd_conf *, struct l2vpn *, struct l2vpn *); 60 61int pipe_parent2ldpe[2]; 62int pipe_parent2lde[2]; 63int pipe_ldpe2lde[2]; 64 65struct ldpd_conf *ldpd_conf = NULL; 66struct imsgev *iev_ldpe; 67struct imsgev *iev_lde; 68char *conffile; 69 70pid_t ldpe_pid = 0; 71pid_t lde_pid = 0; 72 73/* ARGSUSED */ 74void 75main_sig_handler(int sig, short event, void *arg) 76{ 77 /* 78 * signal handler rules don't apply, libevent decouples for us 79 */ 80 81 int die = 0; 82 83 switch (sig) { 84 case SIGTERM: 85 case SIGINT: 86 die = 1; 87 /* FALLTHROUGH */ 88 case SIGCHLD: 89 if (check_child(ldpe_pid, "ldp engine")) { 90 ldpe_pid = 0; 91 die = 1; 92 } 93 if (check_child(lde_pid, "label decision engine")) { 94 lde_pid = 0; 95 die = 1; 96 } 97 if (die) 98 ldpd_shutdown(); 99 break; 100 case SIGHUP: 101 if (ldp_reload() == -1) 102 log_warnx("configuration reload failed"); 103 else 104 log_debug("configuration reloaded"); 105 break; 106 default: 107 fatalx("unexpected signal"); 108 /* NOTREACHED */ 109 } 110} 111 112__dead void 113usage(void) 114{ 115 extern char *__progname; 116 117 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 118 __progname); 119 exit(1); 120} 121 122int 123main(int argc, char *argv[]) 124{ 125 struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; 126 int ch, opts = 0; 127 int debug = 0; 128 129 conffile = CONF_FILE; 130 ldpd_process = PROC_MAIN; 131 132 log_init(1); /* log to stderr until daemonized */ 133 log_verbose(1); 134 135 while ((ch = getopt(argc, argv, "dD:f:nv")) != -1) { 136 switch (ch) { 137 case 'd': 138 debug = 1; 139 break; 140 case 'D': 141 if (cmdline_symset(optarg) < 0) 142 log_warnx("could not parse macro definition %s", 143 optarg); 144 break; 145 case 'f': 146 conffile = optarg; 147 break; 148 case 'n': 149 opts |= LDPD_OPT_NOACTION; 150 break; 151 case 'v': 152 if (opts & LDPD_OPT_VERBOSE) 153 opts |= LDPD_OPT_VERBOSE2; 154 opts |= LDPD_OPT_VERBOSE; 155 break; 156 default: 157 usage(); 158 /* NOTREACHED */ 159 } 160 } 161 162 /* fetch interfaces early */ 163 kif_init(); 164 165 /* parse config file */ 166 if ((ldpd_conf = parse_config(conffile, opts)) == NULL ) 167 exit(1); 168 169 if (ldpd_conf->opts & LDPD_OPT_NOACTION) { 170 if (ldpd_conf->opts & LDPD_OPT_VERBOSE) 171 print_config(ldpd_conf); 172 else 173 fprintf(stderr, "configuration OK\n"); 174 exit(0); 175 } 176 177 /* check for root privileges */ 178 if (geteuid()) 179 errx(1, "need root privileges"); 180 181 /* check for ldpd user */ 182 if (getpwnam(LDPD_USER) == NULL) 183 errx(1, "unknown user %s", LDPD_USER); 184 185 log_init(debug); 186 log_verbose(opts & (LDPD_OPT_VERBOSE | LDPD_OPT_VERBOSE2)); 187 188 if (!debug) 189 daemon(1, 0); 190 191 log_info("startup"); 192 193 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 194 PF_UNSPEC, pipe_parent2ldpe) == -1) 195 fatal("socketpair"); 196 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 197 PF_UNSPEC, pipe_parent2lde) == -1) 198 fatal("socketpair"); 199 if (socketpair(AF_UNIX, SOCK_STREAM |SOCK_NONBLOCK | SOCK_CLOEXEC, 200 PF_UNSPEC, pipe_ldpe2lde) == -1) 201 fatal("socketpair"); 202 203 /* start children */ 204 lde_pid = lde(ldpd_conf, pipe_parent2lde, pipe_ldpe2lde, 205 pipe_parent2ldpe); 206 ldpe_pid = ldpe(ldpd_conf, pipe_parent2ldpe, pipe_ldpe2lde, 207 pipe_parent2lde); 208 209 event_init(); 210 211 /* setup signal handler */ 212 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 213 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 214 signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL); 215 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 216 signal_add(&ev_sigint, NULL); 217 signal_add(&ev_sigterm, NULL); 218 signal_add(&ev_sigchld, NULL); 219 signal_add(&ev_sighup, NULL); 220 signal(SIGPIPE, SIG_IGN); 221 222 /* setup pipes to children */ 223 close(pipe_parent2ldpe[1]); 224 close(pipe_parent2lde[1]); 225 close(pipe_ldpe2lde[0]); 226 close(pipe_ldpe2lde[1]); 227 228 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL || 229 (iev_lde = malloc(sizeof(struct imsgev))) == NULL) 230 fatal(NULL); 231 imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]); 232 iev_ldpe->handler = main_dispatch_ldpe; 233 imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]); 234 iev_lde->handler = main_dispatch_lde; 235 236 /* setup event handler */ 237 iev_ldpe->events = EV_READ; 238 event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events, 239 iev_ldpe->handler, iev_ldpe); 240 event_add(&iev_ldpe->ev, NULL); 241 242 iev_lde->events = EV_READ; 243 event_set(&iev_lde->ev, iev_lde->ibuf.fd, iev_lde->events, 244 iev_lde->handler, iev_lde); 245 event_add(&iev_lde->ev, NULL); 246 247 /* notify ldpe about existing interfaces and addresses */ 248 kif_redistribute(); 249 250 if (kr_init(!(ldpd_conf->flags & LDPD_FLAG_NO_FIB_UPDATE)) == -1) 251 fatalx("kr_init failed"); 252 253 /* remove unneded stuff from config */ 254 /* ... */ 255 256 event_dispatch(); 257 258 ldpd_shutdown(); 259 /* NOTREACHED */ 260 return (0); 261} 262 263void 264ldpd_shutdown(void) 265{ 266 pid_t pid; 267 268 if (ldpe_pid) 269 kill(ldpe_pid, SIGTERM); 270 271 if (lde_pid) 272 kill(lde_pid, SIGTERM); 273 274 kr_shutdown(); 275 276 do { 277 if ((pid = wait(NULL)) == -1 && 278 errno != EINTR && errno != ECHILD) 279 fatal("wait"); 280 } while (pid != -1 || (pid == -1 && errno == EINTR)); 281 282 config_clear(ldpd_conf); 283 284 msgbuf_clear(&iev_ldpe->ibuf.w); 285 free(iev_ldpe); 286 msgbuf_clear(&iev_lde->ibuf.w); 287 free(iev_lde); 288 289 log_info("terminating"); 290 exit(0); 291} 292 293int 294check_child(pid_t pid, const char *pname) 295{ 296 int status; 297 298 if (waitpid(pid, &status, WNOHANG) > 0) { 299 if (WIFEXITED(status)) { 300 log_warnx("lost child: %s exited", pname); 301 return (1); 302 } 303 if (WIFSIGNALED(status)) { 304 log_warnx("lost child: %s terminated; signal %d", 305 pname, WTERMSIG(status)); 306 return (1); 307 } 308 } 309 310 return (0); 311} 312 313/* imsg handling */ 314/* ARGSUSED */ 315void 316main_dispatch_ldpe(int fd, short event, void *bula) 317{ 318 struct imsgev *iev = bula; 319 struct imsgbuf *ibuf = &iev->ibuf; 320 struct imsg imsg; 321 ssize_t n; 322 int shut = 0, verbose; 323 324 if (event & EV_READ) { 325 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 326 fatal("imsg_read error"); 327 if (n == 0) /* connection closed */ 328 shut = 1; 329 } 330 if (event & EV_WRITE) { 331 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 332 fatal("msgbuf_write"); 333 if (n == 0) 334 shut = 1; 335 } 336 337 for (;;) { 338 if ((n = imsg_get(ibuf, &imsg)) == -1) 339 fatal("imsg_get"); 340 341 if (n == 0) 342 break; 343 344 switch (imsg.hdr.type) { 345 case IMSG_CTL_RELOAD: 346 if (ldp_reload() == -1) 347 log_warnx("configuration reload failed"); 348 else 349 log_debug("configuration reloaded"); 350 break; 351 case IMSG_CTL_FIB_COUPLE: 352 kr_fib_couple(); 353 break; 354 case IMSG_CTL_FIB_DECOUPLE: 355 kr_fib_decouple(); 356 break; 357 case IMSG_CTL_KROUTE: 358 case IMSG_CTL_KROUTE_ADDR: 359 kr_show_route(&imsg); 360 break; 361 case IMSG_CTL_IFINFO: 362 if (imsg.hdr.len == IMSG_HEADER_SIZE) 363 kr_ifinfo(NULL, imsg.hdr.pid); 364 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 365 kr_ifinfo(imsg.data, imsg.hdr.pid); 366 else 367 log_warnx("IFINFO request with wrong len"); 368 break; 369 case IMSG_CTL_LOG_VERBOSE: 370 /* already checked by ldpe */ 371 memcpy(&verbose, imsg.data, sizeof(verbose)); 372 log_verbose(verbose); 373 break; 374 default: 375 log_debug("%s: error handling imsg %d", __func__, 376 imsg.hdr.type); 377 break; 378 } 379 imsg_free(&imsg); 380 } 381 if (!shut) 382 imsg_event_add(iev); 383 else { 384 /* this pipe is dead, so remove the event handler */ 385 event_del(&iev->ev); 386 event_loopexit(NULL); 387 } 388} 389 390/* ARGSUSED */ 391void 392main_dispatch_lde(int fd, short event, void *bula) 393{ 394 struct imsgev *iev = bula; 395 struct imsgbuf *ibuf = &iev->ibuf; 396 struct imsg imsg; 397 ssize_t n; 398 int shut = 0; 399 struct kpw *kpw; 400 401 if (event & EV_READ) { 402 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 403 fatal("imsg_read error"); 404 if (n == 0) /* connection closed */ 405 shut = 1; 406 } 407 if (event & EV_WRITE) { 408 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 409 fatal("msgbuf_write"); 410 if (n == 0) 411 shut = 1; 412 } 413 414 for (;;) { 415 if ((n = imsg_get(ibuf, &imsg)) == -1) 416 fatal("imsg_get"); 417 418 if (n == 0) 419 break; 420 421 switch (imsg.hdr.type) { 422 case IMSG_KLABEL_CHANGE: 423 if (imsg.hdr.len - IMSG_HEADER_SIZE != 424 sizeof(struct kroute)) 425 fatalx("invalid size of IMSG_KLABEL_CHANGE"); 426 if (kr_change(imsg.data)) 427 log_warn("%s: error changing route", __func__); 428 break; 429 case IMSG_KLABEL_DELETE: 430 if (imsg.hdr.len - IMSG_HEADER_SIZE != 431 sizeof(struct kroute)) 432 fatalx("invalid size of IMSG_KLABEL_DELETE"); 433 if (kr_delete(imsg.data)) 434 log_warn("%s: error deleting route", __func__); 435 break; 436 case IMSG_KPWLABEL_CHANGE: 437 if (imsg.hdr.len - IMSG_HEADER_SIZE != 438 sizeof(struct kpw)) 439 fatalx("invalid size of IMSG_KPWLABEL_CHANGE"); 440 441 kpw = imsg.data; 442 kmpw_set(kpw); 443 break; 444 case IMSG_KPWLABEL_DELETE: 445 if (imsg.hdr.len - IMSG_HEADER_SIZE != 446 sizeof(struct kpw)) 447 fatalx("invalid size of IMSG_KPWLABEL_DELETE"); 448 449 kpw = imsg.data; 450 kmpw_unset(kpw); 451 break; 452 default: 453 log_debug("%s: error handling imsg %d", __func__, 454 imsg.hdr.type); 455 break; 456 } 457 imsg_free(&imsg); 458 } 459 if (!shut) 460 imsg_event_add(iev); 461 else { 462 /* this pipe is dead, so remove the event handler */ 463 event_del(&iev->ev); 464 event_loopexit(NULL); 465 } 466} 467 468void 469main_imsg_compose_ldpe(int type, pid_t pid, void *data, u_int16_t datalen) 470{ 471 if (iev_ldpe == NULL) 472 return; 473 imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen); 474} 475 476void 477main_imsg_compose_lde(int type, pid_t pid, void *data, u_int16_t datalen) 478{ 479 imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen); 480} 481 482void 483imsg_event_add(struct imsgev *iev) 484{ 485 iev->events = EV_READ; 486 if (iev->ibuf.w.queued) 487 iev->events |= EV_WRITE; 488 489 event_del(&iev->ev); 490 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 491 event_add(&iev->ev, NULL); 492} 493 494int 495imsg_compose_event(struct imsgev *iev, u_int16_t type, 496 u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) 497{ 498 int ret; 499 500 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 501 pid, fd, data, datalen)) != -1) 502 imsg_event_add(iev); 503 return (ret); 504} 505 506void 507evbuf_enqueue(struct evbuf *eb, struct ibuf *buf) 508{ 509 ibuf_close(&eb->wbuf, buf); 510 evbuf_event_add(eb); 511} 512 513void 514evbuf_event_add(struct evbuf *eb) 515{ 516 if (eb->wbuf.queued) 517 event_add(&eb->ev, NULL); 518} 519 520void 521evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *), 522 void *arg) 523{ 524 msgbuf_init(&eb->wbuf); 525 eb->wbuf.fd = fd; 526 event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg); 527} 528 529void 530evbuf_clear(struct evbuf *eb) 531{ 532 event_del(&eb->ev); 533 msgbuf_clear(&eb->wbuf); 534 eb->wbuf.fd = -1; 535} 536 537int 538ldp_reload(void) 539{ 540 struct iface *iface; 541 struct tnbr *tnbr; 542 struct nbr_params *nbrp; 543 struct l2vpn *l2vpn; 544 struct l2vpn_if *lif; 545 struct l2vpn_pw *pw; 546 struct ldpd_conf *xconf; 547 548 if ((xconf = parse_config(conffile, ldpd_conf->opts)) == NULL) 549 return (-1); 550 551 if (ldp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1) 552 return (-1); 553 554 LIST_FOREACH(iface, &xconf->iface_list, entry) { 555 if (ldp_sendboth(IMSG_RECONF_IFACE, iface, 556 sizeof(*iface)) == -1) 557 return (-1); 558 } 559 560 LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) { 561 if (ldp_sendboth(IMSG_RECONF_TNBR, tnbr, 562 sizeof(*tnbr)) == -1) 563 return (-1); 564 } 565 566 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) { 567 if (ldp_sendboth(IMSG_RECONF_NBRP, nbrp, 568 sizeof(*nbrp)) == -1) 569 return (-1); 570 } 571 572 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) { 573 if (ldp_sendboth(IMSG_RECONF_L2VPN, l2vpn, 574 sizeof(*l2vpn)) == -1) 575 return (-1); 576 577 LIST_FOREACH(lif, &l2vpn->if_list, entry) { 578 if (ldp_sendboth(IMSG_RECONF_L2VPN_IF, lif, 579 sizeof(*lif)) == -1) 580 return (-1); 581 } 582 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 583 if (ldp_sendboth(IMSG_RECONF_L2VPN_PW, pw, 584 sizeof(*pw)) == -1) 585 return (-1); 586 } 587 } 588 589 if (ldp_sendboth(IMSG_RECONF_END, NULL, 0) == -1) 590 return (-1); 591 592 merge_config(ldpd_conf, xconf); 593 594 return (0); 595} 596 597int 598ldp_sendboth(enum imsg_type type, void *buf, u_int16_t len) 599{ 600 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1) 601 return (-1); 602 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1) 603 return (-1); 604 return (0); 605} 606 607void 608merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) 609{ 610 struct iface *iface, *itmp, *xi; 611 struct tnbr *tnbr, *ttmp, *xt; 612 struct nbr_params *nbrp, *ntmp, *xn; 613 struct l2vpn *l2vpn, *ltmp, *xl; 614 struct nbr *nbr; 615 616 /* change of rtr_id needs a restart */ 617 conf->flags = xconf->flags; 618 conf->keepalive = xconf->keepalive; 619 conf->thello_holdtime = xconf->thello_holdtime; 620 conf->thello_interval = xconf->thello_interval; 621 622 /* merge interfaces */ 623 LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) { 624 /* find deleted interfaces */ 625 if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) { 626 LIST_REMOVE(iface, entry); 627 if (ldpd_process == PROC_LDP_ENGINE) 628 if_del(iface); 629 else 630 free(iface); 631 } 632 } 633 LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) { 634 /* find new interfaces */ 635 if ((iface = if_lookup(conf, xi->ifindex)) == NULL) { 636 LIST_REMOVE(xi, entry); 637 LIST_INSERT_HEAD(&conf->iface_list, xi, entry); 638 if (ldpd_process == PROC_LDP_ENGINE) 639 if_init(conf, xi); 640 continue; 641 } 642 643 /* update existing interfaces */ 644 iface->hello_holdtime = xi->hello_holdtime; 645 iface->hello_interval = xi->hello_interval; 646 } 647 /* resend addresses to activate new interfaces */ 648 if (ldpd_process == PROC_MAIN) 649 kif_redistribute(); 650 651 /* merge tnbrs */ 652 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) { 653 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 654 continue; 655 656 /* find deleted tnbrs */ 657 if ((xt = tnbr_find(xconf, tnbr->addr)) == NULL) { 658 if (ldpd_process == PROC_LDP_ENGINE) { 659 tnbr->flags &= ~F_TNBR_CONFIGURED; 660 tnbr_check(tnbr); 661 } else { 662 LIST_REMOVE(tnbr, entry); 663 free(tnbr); 664 } 665 } 666 } 667 LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) { 668 /* find new tnbrs */ 669 if ((tnbr = tnbr_find(conf, xt->addr)) == NULL) { 670 LIST_REMOVE(xt, entry); 671 LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry); 672 if (ldpd_process == PROC_LDP_ENGINE) 673 tnbr_init(conf, xt); 674 continue; 675 } 676 677 /* update existing tnbrs */ 678 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 679 tnbr->flags |= F_TNBR_CONFIGURED; 680 tnbr->hello_holdtime = xt->hello_holdtime; 681 tnbr->hello_interval = xt->hello_interval; 682 } 683 684 /* merge neighbor parameters */ 685 LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) { 686 /* find deleted nbrps */ 687 if ((xn = nbr_params_find(xconf, nbrp->addr)) == NULL) { 688 if (ldpd_process == PROC_LDP_ENGINE) { 689 nbr = nbr_find_ldpid(nbrp->addr.s_addr); 690 if (nbr) { 691 if (nbr->state == NBR_STA_OPER) 692 session_shutdown(nbr, 693 S_SHUTDOWN, 0, 0); 694 pfkey_remove(nbr); 695 } 696 } 697 LIST_REMOVE(nbrp, entry); 698 free(nbrp); 699 } 700 } 701 LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) { 702 /* find new nbrps */ 703 if ((nbrp = nbr_params_find(conf, xn->addr)) == NULL) { 704 LIST_REMOVE(xn, entry); 705 LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry); 706 707 if (ldpd_process == PROC_LDP_ENGINE) { 708 nbr = nbr_find_ldpid(xn->addr.s_addr); 709 if (nbr) { 710 if (nbr->state == NBR_STA_OPER) 711 session_shutdown(nbr, 712 S_SHUTDOWN, 0, 0); 713 pfkey_remove(nbr); 714 if (pfkey_establish(nbr, xn) == -1) 715 fatalx("pfkey setup failed"); 716 } 717 } 718 continue; 719 } 720 721 /* update existing nbrps */ 722 nbrp->keepalive = xn->keepalive; 723 nbrp->auth.method = xn->auth.method; 724 strlcpy(nbrp->auth.md5key, xn->auth.md5key, 725 sizeof(nbrp->auth.md5key)); 726 nbrp->auth.md5key_len = xn->auth.md5key_len; 727 728 if (ldpd_process == PROC_LDP_ENGINE) { 729 nbr = nbr_find_ldpid(nbrp->addr.s_addr); 730 if (nbr && 731 (nbr->auth.method != nbrp->auth.method || 732 strcmp(nbr->auth.md5key, nbrp->auth.md5key) != 0)) { 733 if (nbr->state == NBR_STA_OPER) 734 session_shutdown(nbr, S_SHUTDOWN, 735 0, 0); 736 pfkey_remove(nbr); 737 if (pfkey_establish(nbr, nbrp) == -1) 738 fatalx("pfkey setup failed"); 739 } 740 } 741 } 742 743 /* merge l2vpns */ 744 LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) { 745 /* find deleted l2vpns */ 746 if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) { 747 LIST_REMOVE(l2vpn, entry); 748 749 switch (ldpd_process) { 750 case PROC_LDE_ENGINE: 751 l2vpn_del(l2vpn); 752 break; 753 case PROC_LDP_ENGINE: 754 ldpe_l2vpn_exit(l2vpn); 755 free(l2vpn); 756 break; 757 case PROC_MAIN: 758 free(l2vpn); 759 break; 760 } 761 } 762 } 763 LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) { 764 /* find new l2vpns */ 765 if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) { 766 LIST_REMOVE(xl, entry); 767 LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry); 768 769 switch (ldpd_process) { 770 case PROC_LDE_ENGINE: 771 l2vpn_init(xl); 772 break; 773 case PROC_LDP_ENGINE: 774 ldpe_l2vpn_init(xl); 775 break; 776 case PROC_MAIN: 777 break; 778 } 779 continue; 780 } 781 782 /* update existing l2vpns */ 783 merge_l2vpns(conf, l2vpn, xl); 784 } 785 786 free(xconf); 787} 788 789void 790merge_l2vpns(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl) 791{ 792 struct l2vpn_if *lif, *ftmp, *xf; 793 struct l2vpn_pw *pw, *ptmp, *xp; 794 795 /* merge intefaces */ 796 LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) { 797 /* find deleted interfaces */ 798 if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) { 799 LIST_REMOVE(lif, entry); 800 free(lif); 801 } 802 } 803 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) { 804 /* find new interfaces */ 805 if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) { 806 LIST_REMOVE(xf, entry); 807 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry); 808 lif->l2vpn = l2vpn; 809 continue; 810 } 811 812 /* update existing interfaces */ 813 lif->l2vpn = l2vpn; 814 } 815 816 /* merge pseudowires */ 817 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) { 818 /* find deleted pseudowires */ 819 if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) { 820 LIST_REMOVE(pw, entry); 821 822 switch (ldpd_process) { 823 case PROC_LDE_ENGINE: 824 l2vpn_pw_del(pw); 825 break; 826 case PROC_LDP_ENGINE: 827 ldpe_l2vpn_pw_exit(pw); 828 free(pw); 829 break; 830 case PROC_MAIN: 831 free(pw); 832 break; 833 } 834 } 835 } 836 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) { 837 /* find new pseudowires */ 838 if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) { 839 LIST_REMOVE(xp, entry); 840 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); 841 842 switch (ldpd_process) { 843 case PROC_LDE_ENGINE: 844 l2vpn_pw_init(xp); 845 break; 846 case PROC_LDP_ENGINE: 847 ldpe_l2vpn_pw_init(xp); 848 break; 849 case PROC_MAIN: 850 break; 851 } 852 continue; 853 } 854 855 /* changes that require a full reset of the pseudowire */ 856 if (l2vpn->pw_type != xl->pw_type || 857 l2vpn->mtu != xl->mtu || 858 pw->addr.s_addr != xp->addr.s_addr || 859 pw->pwid != xp->pwid || 860 ((pw->flags & 861 (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)) != 862 (xp->flags & 863 (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)))) { 864 LIST_REMOVE(pw, entry); 865 LIST_REMOVE(xp, entry); 866 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); 867 868 switch (ldpd_process) { 869 case PROC_LDE_ENGINE: 870 l2vpn_pw_del(pw); 871 l2vpn_pw_init(xp); 872 break; 873 case PROC_LDP_ENGINE: 874 if (pw->addr.s_addr != xp->addr.s_addr) { 875 ldpe_l2vpn_pw_exit(pw); 876 ldpe_l2vpn_pw_init(xp); 877 } 878 free(pw); 879 break; 880 case PROC_MAIN: 881 free(pw); 882 break; 883 } 884 } 885 886 /* update existing pseudowires */ 887 pw->l2vpn = xp->l2vpn; 888 } 889 890 l2vpn->mtu = xl->mtu; 891 l2vpn->br_ifindex = xl->br_ifindex; 892} 893 894void 895config_clear(struct ldpd_conf *conf) 896{ 897 struct ldpd_conf *xconf; 898 899 /* merge current config with an empty config */ 900 xconf = malloc(sizeof(*xconf)); 901 memcpy(xconf, conf, sizeof(*xconf)); 902 LIST_INIT(&xconf->iface_list); 903 LIST_INIT(&xconf->tnbr_list); 904 LIST_INIT(&xconf->nbrp_list); 905 LIST_INIT(&xconf->l2vpn_list); 906 merge_config(conf, xconf); 907 908 free(conf); 909} 910