ldpd.c revision 1.33
1/* $OpenBSD: ldpd.c,v 1.33 2016/05/23 15:55:45 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 482int 483ldp_sendboth(enum imsg_type type, void *buf, uint16_t len) 484{ 485 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1) 486 return (-1); 487 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1) 488 return (-1); 489 return (0); 490} 491 492void 493imsg_event_add(struct imsgev *iev) 494{ 495 iev->events = EV_READ; 496 if (iev->ibuf.w.queued) 497 iev->events |= EV_WRITE; 498 499 event_del(&iev->ev); 500 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev); 501 event_add(&iev->ev, NULL); 502} 503 504int 505imsg_compose_event(struct imsgev *iev, u_int16_t type, 506 u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) 507{ 508 int ret; 509 510 if ((ret = imsg_compose(&iev->ibuf, type, peerid, 511 pid, fd, data, datalen)) != -1) 512 imsg_event_add(iev); 513 return (ret); 514} 515 516void 517evbuf_enqueue(struct evbuf *eb, struct ibuf *buf) 518{ 519 ibuf_close(&eb->wbuf, buf); 520 evbuf_event_add(eb); 521} 522 523void 524evbuf_event_add(struct evbuf *eb) 525{ 526 if (eb->wbuf.queued) 527 event_add(&eb->ev, NULL); 528} 529 530void 531evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *), 532 void *arg) 533{ 534 msgbuf_init(&eb->wbuf); 535 eb->wbuf.fd = fd; 536 event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg); 537} 538 539void 540evbuf_clear(struct evbuf *eb) 541{ 542 event_del(&eb->ev); 543 msgbuf_clear(&eb->wbuf); 544 eb->wbuf.fd = -1; 545} 546 547int 548ldp_reload(void) 549{ 550 struct iface *iface; 551 struct tnbr *tnbr; 552 struct nbr_params *nbrp; 553 struct l2vpn *l2vpn; 554 struct l2vpn_if *lif; 555 struct l2vpn_pw *pw; 556 struct ldpd_conf *xconf; 557 558 if ((xconf = parse_config(conffile, ldpd_conf->opts)) == NULL) 559 return (-1); 560 561 if (ldp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1) 562 return (-1); 563 564 LIST_FOREACH(iface, &xconf->iface_list, entry) { 565 if (ldp_sendboth(IMSG_RECONF_IFACE, iface, 566 sizeof(*iface)) == -1) 567 return (-1); 568 } 569 570 LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) { 571 if (ldp_sendboth(IMSG_RECONF_TNBR, tnbr, 572 sizeof(*tnbr)) == -1) 573 return (-1); 574 } 575 576 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) { 577 if (ldp_sendboth(IMSG_RECONF_NBRP, nbrp, 578 sizeof(*nbrp)) == -1) 579 return (-1); 580 } 581 582 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) { 583 if (ldp_sendboth(IMSG_RECONF_L2VPN, l2vpn, 584 sizeof(*l2vpn)) == -1) 585 return (-1); 586 587 LIST_FOREACH(lif, &l2vpn->if_list, entry) { 588 if (ldp_sendboth(IMSG_RECONF_L2VPN_IF, lif, 589 sizeof(*lif)) == -1) 590 return (-1); 591 } 592 LIST_FOREACH(pw, &l2vpn->pw_list, entry) { 593 if (ldp_sendboth(IMSG_RECONF_L2VPN_PW, pw, 594 sizeof(*pw)) == -1) 595 return (-1); 596 } 597 } 598 599 if (ldp_sendboth(IMSG_RECONF_END, NULL, 0) == -1) 600 return (-1); 601 602 merge_config(ldpd_conf, xconf); 603 604 return (0); 605} 606 607int 608ldp_sendboth(enum imsg_type type, void *buf, u_int16_t len) 609{ 610 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1) 611 return (-1); 612 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1) 613 return (-1); 614 return (0); 615} 616 617void 618merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) 619{ 620 struct iface *iface, *itmp, *xi; 621 struct tnbr *tnbr, *ttmp, *xt; 622 struct nbr_params *nbrp, *ntmp, *xn; 623 struct l2vpn *l2vpn, *ltmp, *xl; 624 struct nbr *nbr; 625 626 /* change of rtr_id needs a restart */ 627 conf->flags = xconf->flags; 628 conf->keepalive = xconf->keepalive; 629 conf->thello_holdtime = xconf->thello_holdtime; 630 conf->thello_interval = xconf->thello_interval; 631 conf->trans_addr.s_addr = xconf->trans_addr.s_addr; 632 633 /* merge interfaces */ 634 LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) { 635 /* find deleted interfaces */ 636 if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) { 637 LIST_REMOVE(iface, entry); 638 if (ldpd_process == PROC_LDP_ENGINE) 639 if_del(iface); 640 else 641 free(iface); 642 } 643 } 644 LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) { 645 /* find new interfaces */ 646 if ((iface = if_lookup(conf, xi->ifindex)) == NULL) { 647 LIST_REMOVE(xi, entry); 648 LIST_INSERT_HEAD(&conf->iface_list, xi, entry); 649 if (ldpd_process == PROC_LDP_ENGINE) 650 if_init(conf, xi); 651 continue; 652 } 653 654 /* update existing interfaces */ 655 iface->hello_holdtime = xi->hello_holdtime; 656 iface->hello_interval = xi->hello_interval; 657 } 658 /* resend addresses to activate new interfaces */ 659 if (ldpd_process == PROC_MAIN) 660 kif_redistribute(); 661} 662 663void 664merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf) 665{ 666 struct tnbr *tnbr, *ttmp, *xt; 667 668 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) { 669 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 670 continue; 671 672 /* find deleted tnbrs */ 673 if ((xt = tnbr_find(xconf, tnbr->addr)) == NULL) { 674 if (ldpd_process == PROC_LDP_ENGINE) { 675 tnbr->flags &= ~F_TNBR_CONFIGURED; 676 tnbr_check(tnbr); 677 } else { 678 LIST_REMOVE(tnbr, entry); 679 free(tnbr); 680 } 681 } 682 } 683 LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) { 684 /* find new tnbrs */ 685 if ((tnbr = tnbr_find(conf, xt->addr)) == NULL) { 686 LIST_REMOVE(xt, entry); 687 LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry); 688 if (ldpd_process == PROC_LDP_ENGINE) 689 tnbr_init(conf, xt); 690 continue; 691 } 692 693 /* update existing tnbrs */ 694 if (!(tnbr->flags & F_TNBR_CONFIGURED)) 695 tnbr->flags |= F_TNBR_CONFIGURED; 696 tnbr->hello_holdtime = xt->hello_holdtime; 697 tnbr->hello_interval = xt->hello_interval; 698 } 699} 700 701void 702merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf) 703{ 704 struct nbr_params *nbrp, *ntmp, *xn; 705 struct nbr *nbr; 706 707 LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) { 708 /* find deleted nbrps */ 709 if ((xn = nbr_params_find(xconf, nbrp->addr)) == NULL) { 710 if (ldpd_process == PROC_LDP_ENGINE) { 711 nbr = nbr_find_ldpid(nbrp->addr.s_addr); 712 if (nbr) { 713 if (nbr->state == NBR_STA_OPER) 714 session_shutdown(nbr, 715 S_SHUTDOWN, 0, 0); 716 pfkey_remove(nbr); 717 } 718 } 719 LIST_REMOVE(nbrp, entry); 720 free(nbrp); 721 } 722 } 723 LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) { 724 /* find new nbrps */ 725 if ((nbrp = nbr_params_find(conf, xn->addr)) == NULL) { 726 LIST_REMOVE(xn, entry); 727 LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry); 728 729 if (ldpd_process == PROC_LDP_ENGINE) { 730 nbr = nbr_find_ldpid(xn->addr.s_addr); 731 if (nbr) { 732 if (nbr->state == NBR_STA_OPER) 733 session_shutdown(nbr, 734 S_SHUTDOWN, 0, 0); 735 pfkey_remove(nbr); 736 if (pfkey_establish(nbr, xn) == -1) 737 fatalx("pfkey setup failed"); 738 } 739 } 740 continue; 741 } 742 743 /* update existing nbrps */ 744 nbrp->keepalive = xn->keepalive; 745 nbrp->auth.method = xn->auth.method; 746 strlcpy(nbrp->auth.md5key, xn->auth.md5key, 747 sizeof(nbrp->auth.md5key)); 748 nbrp->auth.md5key_len = xn->auth.md5key_len; 749 750 if (ldpd_process == PROC_LDP_ENGINE) { 751 nbr = nbr_find_ldpid(nbrp->addr.s_addr); 752 if (nbr && 753 (nbr->auth.method != nbrp->auth.method || 754 strcmp(nbr->auth.md5key, nbrp->auth.md5key) != 0)) { 755 if (nbr->state == NBR_STA_OPER) 756 session_shutdown(nbr, S_SHUTDOWN, 757 0, 0); 758 pfkey_remove(nbr); 759 if (pfkey_establish(nbr, nbrp) == -1) 760 fatalx("pfkey setup failed"); 761 } 762 } 763 } 764} 765 766void 767merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf) 768{ 769 struct l2vpn *l2vpn, *ltmp, *xl; 770 771 LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) { 772 /* find deleted l2vpns */ 773 if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) { 774 LIST_REMOVE(l2vpn, entry); 775 776 switch (ldpd_process) { 777 case PROC_LDE_ENGINE: 778 l2vpn_del(l2vpn); 779 break; 780 case PROC_LDP_ENGINE: 781 ldpe_l2vpn_exit(l2vpn); 782 free(l2vpn); 783 break; 784 case PROC_MAIN: 785 free(l2vpn); 786 break; 787 } 788 } 789 } 790 LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) { 791 /* find new l2vpns */ 792 if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) { 793 LIST_REMOVE(xl, entry); 794 LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry); 795 796 switch (ldpd_process) { 797 case PROC_LDE_ENGINE: 798 l2vpn_init(xl); 799 break; 800 case PROC_LDP_ENGINE: 801 ldpe_l2vpn_init(xl); 802 break; 803 case PROC_MAIN: 804 break; 805 } 806 continue; 807 } 808 809 /* update existing l2vpns */ 810 merge_l2vpn(conf, l2vpn, xl); 811 } 812} 813 814void 815merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl) 816{ 817 struct l2vpn_if *lif, *ftmp, *xf; 818 struct l2vpn_pw *pw, *ptmp, *xp; 819 820 /* merge intefaces */ 821 LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) { 822 /* find deleted interfaces */ 823 if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) { 824 LIST_REMOVE(lif, entry); 825 free(lif); 826 } 827 } 828 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) { 829 /* find new interfaces */ 830 if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) { 831 LIST_REMOVE(xf, entry); 832 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry); 833 lif->l2vpn = l2vpn; 834 continue; 835 } 836 837 /* update existing interfaces */ 838 lif->l2vpn = l2vpn; 839 } 840 841 /* merge pseudowires */ 842 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) { 843 /* find deleted pseudowires */ 844 if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) { 845 LIST_REMOVE(pw, entry); 846 847 switch (ldpd_process) { 848 case PROC_LDE_ENGINE: 849 l2vpn_pw_del(pw); 850 break; 851 case PROC_LDP_ENGINE: 852 ldpe_l2vpn_pw_exit(pw); 853 free(pw); 854 break; 855 case PROC_MAIN: 856 free(pw); 857 break; 858 } 859 } 860 } 861 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) { 862 /* find new pseudowires */ 863 if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) { 864 LIST_REMOVE(xp, entry); 865 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); 866 867 switch (ldpd_process) { 868 case PROC_LDE_ENGINE: 869 l2vpn_pw_init(xp); 870 break; 871 case PROC_LDP_ENGINE: 872 ldpe_l2vpn_pw_init(xp); 873 break; 874 case PROC_MAIN: 875 break; 876 } 877 continue; 878 } 879 880 /* changes that require a full reset of the pseudowire */ 881 if (l2vpn->pw_type != xl->pw_type || 882 l2vpn->mtu != xl->mtu || 883 pw->addr.s_addr != xp->addr.s_addr || 884 pw->pwid != xp->pwid || 885 ((pw->flags & 886 (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)) != 887 (xp->flags & 888 (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)))) { 889 LIST_REMOVE(pw, entry); 890 LIST_REMOVE(xp, entry); 891 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); 892 893 switch (ldpd_process) { 894 case PROC_LDE_ENGINE: 895 l2vpn_pw_del(pw); 896 l2vpn_pw_init(xp); 897 break; 898 case PROC_LDP_ENGINE: 899 if (pw->addr.s_addr != xp->addr.s_addr) { 900 ldpe_l2vpn_pw_exit(pw); 901 ldpe_l2vpn_pw_init(xp); 902 } 903 free(pw); 904 break; 905 case PROC_MAIN: 906 free(pw); 907 break; 908 } 909 } 910 911 /* update existing pseudowires */ 912 pw->l2vpn = xp->l2vpn; 913 } 914 915 l2vpn->mtu = xl->mtu; 916 l2vpn->br_ifindex = xl->br_ifindex; 917} 918 919void 920config_clear(struct ldpd_conf *conf) 921{ 922 struct ldpd_conf *xconf; 923 924 /* merge current config with an empty config */ 925 xconf = malloc(sizeof(*xconf)); 926 memcpy(xconf, conf, sizeof(*xconf)); 927 LIST_INIT(&xconf->iface_list); 928 LIST_INIT(&xconf->tnbr_list); 929 LIST_INIT(&xconf->nbrp_list); 930 LIST_INIT(&xconf->l2vpn_list); 931 merge_config(conf, xconf); 932 933 free(conf); 934} 935