1 /* $OpenBSD: ldpd.c,v 1.3 2009/07/13 19:04:26 michele 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 #include <sys/param.h> 28 #include <sys/sysctl.h> 29 30 #include <netinet/in.h> 31 #include <arpa/inet.h> 32 #include <netmpls/mpls.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 "ldpd.h" 45 #include "ldp.h" 46 #include "ldpe.h" 47 #include "control.h" 48 #include "log.h" 49 #include "lde.h" 50 51 void main_sig_handler(int, short, void *); 52 __dead void usage(void); 53 void ldpd_shutdown(void); 54 int check_child(pid_t, const char *); 55 56 void main_dispatch_ldpe(int, short, void *); 57 void main_dispatch_lde(int, short, void *); 58 59 /*int ldp_reload(void); */ 60 int ldp_sendboth(enum imsg_type, void *, u_int16_t); 61 /*int merge_interfaces(struct lspace *, struct lspace *); */ 62 /*struct iface *iface_lookup(struct lspace *, struct iface *); */ 63 64 int pipe_parent2ldpe[2]; 65 int pipe_parent2lde[2]; 66 int pipe_ldpe2lde[2]; 67 68 struct ldpd_conf *ldpd_conf = NULL; 69 struct imsgev *iev_ldpe; 70 struct imsgev *iev_lde; 71 char *conffile; 72 73 pid_t ldpe_pid = 0; 74 pid_t lde_pid = 0; 75 76 /* ARGSUSED */ 77 void 78 main_sig_handler(int sig, short event, void *arg) 79 { 80 /* 81 * signal handler rules don't apply, libevent decouples for us 82 */ 83 84 int die = 0; 85 86 switch (sig) { 87 case SIGTERM: 88 case SIGINT: 89 die = 1; 90 /* FALLTHROUGH */ 91 case SIGCHLD: 92 if (check_child(ldpe_pid, "ldp engine")) { 93 ldpe_pid = 0; 94 die = 1; 95 } 96 if (check_child(lde_pid, "label decision engine")) { 97 lde_pid = 0; 98 die = 1; 99 } 100 if (die) 101 ldpd_shutdown(); 102 break; 103 case SIGHUP: 104 /* 105 if (ldp_reload() == -1) 106 log_warnx("configuration reload failed"); 107 else 108 log_debug("configuration reloaded"); 109 */ 110 break; 111 default: 112 fatalx("unexpected signal"); 113 /* NOTREACHED */ 114 } 115 } 116 117 __dead void 118 usage(void) 119 { 120 extern char *__progname; 121 122 fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n", 123 __progname); 124 exit(1); 125 } 126 127 int 128 main(int argc, char *argv[]) 129 { 130 struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup; 131 int ch, opts = 0; 132 int debug = 0; 133 int ipforwarding, mplsenable; 134 int mib[4]; 135 size_t len; 136 137 conffile = CONF_FILE; 138 ldpd_process = PROC_MAIN; 139 140 log_init(1); /* log to stderr until daemonized */ 141 142 while ((ch = getopt(argc, argv, "cdD:f:nv")) != -1) { 143 switch (ch) { 144 case 'd': 145 debug = 1; 146 break; 147 case 'D': 148 if (cmdline_symset(optarg) < 0) 149 log_warnx("could not parse macro definition %s", 150 optarg); 151 break; 152 case 'f': 153 conffile = optarg; 154 break; 155 case 'n': 156 opts |= LDPD_OPT_NOACTION; 157 break; 158 case 'v': 159 if (opts & LDPD_OPT_VERBOSE) 160 opts |= LDPD_OPT_VERBOSE2; 161 opts |= LDPD_OPT_VERBOSE; 162 break; 163 164 default: 165 usage(); 166 /* NOTREACHED */ 167 } 168 } 169 170 mib[0] = CTL_NET; 171 mib[1] = PF_INET; 172 mib[2] = IPPROTO_IP; 173 mib[3] = IPCTL_FORWARDING; 174 len = sizeof(ipforwarding); 175 if (sysctl(mib, 4, &ipforwarding, &len, NULL, 0) == -1) 176 err(1, "sysctl"); 177 178 if (ipforwarding != 1) 179 log_warnx("WARNING: IP forwarding NOT enabled"); 180 181 mib[0] = CTL_NET; 182 mib[1] = PF_MPLS; 183 mib[2] = MPLSCTL_ENABLE; 184 len = sizeof(mplsenable); 185 if (sysctl(mib, 3, &mplsenable, &len, NULL, 0) == -1) 186 err(1, "sysctl"); 187 188 if (mplsenable != 1) 189 log_warnx("WARNING: MPLS NOT enabled"); 190 191 /* fetch interfaces early */ 192 kif_init(); 193 194 /* parse config file */ 195 if ((ldpd_conf = parse_config(conffile, opts)) == NULL ) 196 exit(1); 197 198 /* parse config file */ 199 200 if (ldpd_conf->opts & LDPD_OPT_NOACTION) { 201 if (ldpd_conf->opts & LDPD_OPT_VERBOSE) 202 print_config(ldpd_conf); 203 else 204 fprintf(stderr, "configuration OK\n"); 205 exit(0); 206 } 207 208 /* check for root privileges */ 209 if (geteuid()) 210 errx(1, "need root privileges"); 211 212 /* check for ldpd user */ 213 if (getpwnam(LDPD_USER) == NULL) 214 errx(1, "unknown user %s", LDPD_USER); 215 216 log_init(debug); 217 218 if (!debug) 219 daemon(1, 0); 220 221 log_info("startup"); 222 223 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, 224 pipe_parent2ldpe) == -1) 225 fatal("socketpair"); 226 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1) 227 fatal("socketpair"); 228 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_ldpe2lde) == -1) 229 fatal("socketpair"); 230 session_socket_blockmode(pipe_parent2ldpe[0], BM_NONBLOCK); 231 session_socket_blockmode(pipe_parent2ldpe[1], BM_NONBLOCK); 232 session_socket_blockmode(pipe_parent2lde[0], BM_NONBLOCK); 233 session_socket_blockmode(pipe_parent2lde[1], BM_NONBLOCK); 234 session_socket_blockmode(pipe_ldpe2lde[0], BM_NONBLOCK); 235 session_socket_blockmode(pipe_ldpe2lde[1], BM_NONBLOCK); 236 237 /* start children */ 238 lde_pid = lde(ldpd_conf, pipe_parent2lde, pipe_ldpe2lde, 239 pipe_parent2ldpe); 240 ldpe_pid = ldpe(ldpd_conf, pipe_parent2ldpe, pipe_ldpe2lde, 241 pipe_parent2lde); 242 243 /* show who we are */ 244 setproctitle("parent"); 245 246 event_init(); 247 248 /* setup signal handler */ 249 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL); 250 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL); 251 signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL); 252 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL); 253 signal_add(&ev_sigint, NULL); 254 signal_add(&ev_sigterm, NULL); 255 signal_add(&ev_sigchld, NULL); 256 signal_add(&ev_sighup, NULL); 257 signal(SIGPIPE, SIG_IGN); 258 259 /* setup pipes to children */ 260 close(pipe_parent2ldpe[1]); 261 close(pipe_parent2lde[1]); 262 close(pipe_ldpe2lde[0]); 263 close(pipe_ldpe2lde[1]); 264 265 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL || 266 (iev_lde = malloc(sizeof(struct imsgev))) == NULL) 267 fatal(NULL); 268 imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]); 269 iev_ldpe->handler = main_dispatch_ldpe; 270 imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]); 271 iev_lde->handler = main_dispatch_lde; 272 273 /* setup event handler */ 274 iev_ldpe->events = EV_READ; 275 event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events, 276 iev_ldpe->handler, iev_ldpe); 277 event_add(&iev_ldpe->ev, NULL); 278 279 iev_lde->events = EV_READ; 280 event_set(&iev_lde->ev, iev_lde->ibuf.fd, iev_lde->events, 281 iev_lde->handler, iev_lde); 282 event_add(&iev_lde->ev, NULL); 283 284 if (kr_init(!(ldpd_conf->flags & LDPD_FLAG_NO_LFIB_UPDATE)) == -1) 285 fatalx("kr_init failed"); 286 287 /* remove unneded stuff from config */ 288 /* ... */ 289 290 291 event_dispatch(); 292 293 ldpd_shutdown(); 294 /* NOTREACHED */ 295 return (0); 296 } 297 298 void 299 ldpd_shutdown(void) 300 { 301 pid_t pid; 302 303 if (ldpe_pid) 304 kill(ldpe_pid, SIGTERM); 305 306 if (lde_pid) 307 kill(lde_pid, SIGTERM); 308 309 control_cleanup(); 310 kr_shutdown(); 311 312 do { 313 if ((pid = wait(NULL)) == -1 && 314 errno != EINTR && errno != ECHILD) 315 fatal("wait"); 316 } while (pid != -1 || (pid == -1 && errno == EINTR)); 317 318 msgbuf_clear(&iev_ldpe->ibuf.w); 319 free(iev_ldpe); 320 msgbuf_clear(&iev_lde->ibuf.w); 321 free(iev_lde); 322 free(ldpd_conf); 323 324 close(ldpd_conf->ldp_session_socket); 325 326 log_info("terminating"); 327 exit(0); 328 } 329 330 int 331 check_child(pid_t pid, const char *pname) 332 { 333 int status; 334 335 if (waitpid(pid, &status, WNOHANG) > 0) { 336 if (WIFEXITED(status)) { 337 log_warnx("lost child: %s exited", pname); 338 return (1); 339 } 340 if (WIFSIGNALED(status)) { 341 log_warnx("lost child: %s terminated; signal %d", 342 pname, WTERMSIG(status)); 343 return (1); 344 } 345 } 346 347 return (0); 348 } 349 350 /* imsg handling */ 351 /* ARGSUSED */ 352 void 353 main_dispatch_ldpe(int fd, short event, void *bula) 354 { 355 struct imsgev *iev = bula; 356 struct imsgbuf *ibuf = &iev->ibuf; 357 struct imsg imsg; 358 ssize_t n; 359 int shut = 0; 360 361 if (event & EV_READ) { 362 if ((n = imsg_read(ibuf)) == -1) 363 fatal("imsg_read error"); 364 if (n == 0) /* connection closed */ 365 shut = 1; 366 } 367 if (event & EV_WRITE) { 368 if (msgbuf_write(&ibuf->w) == -1) 369 fatal("msgbuf_write"); 370 } 371 372 for (;;) { 373 if ((n = imsg_get(ibuf, &imsg)) == -1) 374 fatal("imsg_get"); 375 376 if (n == 0) 377 break; 378 379 switch (imsg.hdr.type) { 380 case IMSG_CTL_RELOAD: 381 /* 382 if (ldp_reload() == -1) 383 log_warnx("configuration reload failed"); 384 else 385 log_debug("configuration reloaded"); 386 break; 387 */ 388 case IMSG_CTL_LFIB_COUPLE: 389 kr_lfib_couple(); 390 break; 391 case IMSG_CTL_LFIB_DECOUPLE: 392 kr_lfib_decouple(); 393 break; 394 case IMSG_CTL_KROUTE: 395 case IMSG_CTL_KROUTE_ADDR: 396 kr_show_route(&imsg); 397 break; 398 case IMSG_CTL_IFINFO: 399 if (imsg.hdr.len == IMSG_HEADER_SIZE) 400 kr_ifinfo(NULL, imsg.hdr.pid); 401 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ) 402 kr_ifinfo(imsg.data, imsg.hdr.pid); 403 else 404 log_warnx("IFINFO request with wrong len"); 405 break; 406 default: 407 log_debug("main_dispatch_ldpe: error handling imsg %d", 408 imsg.hdr.type); 409 break; 410 } 411 imsg_free(&imsg); 412 } 413 if (!shut) 414 imsg_event_add(iev); 415 else { 416 /* this pipe is dead, so remove the event handler */ 417 event_del(&iev->ev); 418 event_loopexit(NULL); 419 } 420 } 421 422 /* ARGSUSED */ 423 void 424 main_dispatch_lde(int fd, short event, void *bula) 425 { 426 struct imsgev *iev = bula; 427 struct imsgbuf *ibuf = &iev->ibuf; 428 struct imsg imsg; 429 ssize_t n; 430 int shut = 0; 431 432 if (event & EV_READ) { 433 if ((n = imsg_read(ibuf)) == -1) 434 fatal("imsg_read error"); 435 if (n == 0) /* connection closed */ 436 shut = 1; 437 } 438 if (event & EV_WRITE) { 439 if (msgbuf_write(&ibuf->w) == -1) 440 fatal("msgbuf_write"); 441 } 442 443 for (;;) { 444 if ((n = imsg_get(ibuf, &imsg)) == -1) 445 fatal("imsg_get"); 446 447 if (n == 0) 448 break; 449 450 switch (imsg.hdr.type) { 451 case IMSG_KLABEL_INSERT: 452 kroute_insert_label(imsg.data); 453 break; 454 case IMSG_KLABEL_CHANGE: 455 if (kr_change(imsg.data)) 456 log_warn("main_dispatch_lde: error changing " 457 "route"); 458 break; 459 case IMSG_KLABEL_DELETE: 460 if (kr_delete(imsg.data)) 461 log_warn("main_dispatch_lde: error deleting " 462 "route"); 463 break; 464 default: 465 log_debug("main_dispatch_lde: error handling imsg %d", 466 imsg.hdr.type); 467 break; 468 } 469 imsg_free(&imsg); 470 } 471 if (!shut) 472 imsg_event_add(iev); 473 else { 474 /* this pipe is dead, so remove the event handler */ 475 event_del(&iev->ev); 476 event_loopexit(NULL); 477 } 478 } 479 480 void 481 main_imsg_compose_ldpe(int type, pid_t pid, void *data, u_int16_t datalen) 482 { 483 imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen); 484 } 485 486 void 487 main_imsg_compose_lde(int type, pid_t pid, void *data, u_int16_t datalen) 488 { 489 imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen); 490 } 491 492 void 493 imsg_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 504 int 505 imsg_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 516 /* 517 int 518 ldp_reload(void) 519 { 520 struct lspace *lspace; 521 struct iface *iface; 522 struct ldpd_conf *xconf; 523 524 if ((xconf = parse_config(conffile, ldpd_conf->opts)) == NULL) 525 return (-1); 526 527 if (ldp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1) 528 return (-1); 529 530 LIST_FOREACH(lspace, &xconf->lspace_list, entry) { 531 if (ldp_sendboth(IMSG_RECONF_AREA, lspace, sizeof(*lspace)) == -1) 532 return (-1); 533 534 LIST_FOREACH(iface, &lspace->iface_list, entry) { 535 if (ldp_sendboth(IMSG_RECONF_IFACE, iface, 536 sizeof(*iface)) == -1) 537 return (-1); 538 } 539 } 540 541 if (ldp_sendboth(IMSG_RECONF_END, NULL, 0) == -1) 542 return (-1); 543 544 merge_config(ldpd_conf, xconf); 545 546 kr_reload(); 547 return (0); 548 } 549 550 int 551 ldp_sendboth(enum imsg_type type, void *buf, u_int16_t len) 552 { 553 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1) 554 return (-1); 555 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1) 556 return (-1); 557 return (0); 558 } 559 560 void 561 merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf) 562 { 563 struct lspace *a, *xa, *na; 564 struct iface *iface; 565 struct redistribute *r; 566 int rchange = 0; 567 568 conf->flags = xconf->flags; 569 conf->spf_delay = xconf->spf_delay; 570 conf->spf_hold_time = xconf->spf_hold_time; 571 if ((conf->redistribute & REDISTRIBUTE_ON) != 572 (xconf->redistribute & REDISTRIBUTE_ON)) 573 rchange = 1; 574 conf->redistribute = xconf->redistribute; 575 conf->rfc1583compat = xconf->rfc1583compat; 576 577 if (ldpd_process == PROC_MAIN) { 578 while ((r = SIMPLEQ_FIRST(&conf->redist_list)) != NULL) { 579 SIMPLEQ_REMOVE_HEAD(&conf->redist_list, entry); 580 free(r); 581 } 582 while ((r = SIMPLEQ_FIRST(&xconf->redist_list)) != NULL) { 583 SIMPLEQ_REMOVE_HEAD(&xconf->redist_list, entry); 584 SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry); 585 } 586 goto done; 587 } 588 589 for (a = LIST_FIRST(&conf->lspace_list); a != NULL; a = na) { 590 na = LIST_NEXT(a, entry); 591 if ((xa = lspace_find(xconf, a->id)) == NULL) { 592 if (ldpd_process == PROC_LDP_ENGINE) { 593 LIST_FOREACH(iface, &a->iface_list, entry) 594 if_fsm(iface, IF_EVT_DOWN); 595 } 596 LIST_REMOVE(a, entry); 597 lspace_del(a); 598 } 599 } 600 601 for (xa = LIST_FIRST(&xconf->lspace_list); xa != NULL; xa = na) { 602 na = LIST_NEXT(xa, entry); 603 if ((a = lspace_find(conf, xa->id)) == NULL) { 604 LIST_REMOVE(xa, entry); 605 LIST_INSERT_HEAD(&conf->lspace_list, xa, entry); 606 if (ldpd_process == PROC_LDP_ENGINE) { 607 LIST_FOREACH(iface, &xa->iface_list, entry) { 608 if_init(conf, iface); 609 if (if_fsm(iface, IF_EVT_UP)) { 610 log_debug("error starting " 611 "interface %s", 612 iface->name); 613 } 614 } 615 } 616 continue; 617 } 618 a->stub = xa->stub; 619 a->stub_default_cost = xa->stub_default_cost; 620 if (ldpd_process == PROC_LDE_ENGINE) 621 a->dirty = 1; 622 623 if (merge_interfaces(a, xa) && 624 ldpd_process == PROC_LDP_ENGINE) 625 a->dirty = 1; 626 } 627 628 if (ldpd_process == PROC_LDP_ENGINE) { 629 LIST_FOREACH(a, &conf->lspace_list, entry) { 630 LIST_FOREACH(iface, &a->iface_list, entry) { 631 if (iface->state == IF_STA_NEW) { 632 iface->state = IF_STA_DOWN; 633 if_init(conf, iface); 634 if (if_fsm(iface, IF_EVT_UP)) { 635 log_debug("error starting " 636 "interface %s", 637 iface->name); 638 } 639 } 640 } 641 } 642 } 643 644 done: 645 while ((a = LIST_FIRST(&xconf->lspace_list)) != NULL) { 646 LIST_REMOVE(a, entry); 647 lspace_del(a); 648 } 649 free(xconf); 650 } 651 652 int 653 merge_interfaces(struct lspace *a, struct lspace *xa) 654 { 655 struct iface *i, *xi, *ni; 656 int dirty = 0; 657 658 for (i = LIST_FIRST(&a->iface_list); i != NULL; i = ni) { 659 ni = LIST_NEXT(i, entry); 660 if (iface_lookup(xa, i) == NULL) { 661 log_debug("merge_config: proc %d label space %s removing " 662 "interface %s", ldpd_process, inet_ntoa(a->id), 663 i->name); 664 if (ldpd_process == PROC_LDP_ENGINE) 665 if_fsm(i, IF_EVT_DOWN); 666 LIST_REMOVE(i, entry); 667 if_del(i); 668 } 669 } 670 671 for (xi = LIST_FIRST(&xa->iface_list); xi != NULL; xi = ni) { 672 ni = LIST_NEXT(xi, entry); 673 if ((i = iface_lookup(a, xi)) == NULL) { 674 log_debug("merge_config: proc %d label space %s adding " 675 "interface %s", ldpd_process, inet_ntoa(a->id), 676 xi->name); 677 LIST_REMOVE(xi, entry); 678 LIST_INSERT_HEAD(&a->iface_list, xi, entry); 679 xi->lspace = a; 680 if (ldpd_process == PROC_LDP_ENGINE) 681 xi->state = IF_STA_NEW; 682 continue; 683 } 684 log_debug("merge_config: proc %d label space %s merging interface %s", 685 ldpd_process, inet_ntoa(a->id), i->name); 686 i->addr = xi->addr; 687 i->dst = xi->dst; 688 i->mask = xi->mask; 689 i->abr_id = xi->abr_id; 690 i->baudrate = xi->baudrate; 691 i->dead_interval = xi->dead_interval; 692 i->mtu = xi->mtu; 693 i->transmit_delay = xi->transmit_delay; 694 i->hello_interval = xi->hello_interval; 695 i->rxmt_interval = xi->rxmt_interval; 696 if (i->metric != xi->metric) 697 dirty = 1; 698 i->metric = xi->metric; 699 i->priority = xi->priority; 700 i->flags = xi->flags; 701 i->type = xi->type; 702 i->media_type = xi->media_type; 703 i->linkstate = xi->linkstate; 704 705 if (i->passive != xi->passive) { 706 if (ldpd_process == PROC_LDP_ENGINE) 707 if_fsm(i, IF_EVT_DOWN); 708 i->passive = xi->passive; 709 if (ldpd_process == PROC_LDP_ENGINE) 710 if_fsm(i, IF_EVT_UP); 711 } 712 } 713 return (dirty); 714 } 715 716 struct iface * 717 iface_lookup(struct lspace *lspace, struct iface *iface) 718 { 719 struct iface *i; 720 721 LIST_FOREACH(i, &lspace->iface_list, entry) 722 if (i->ifindex == iface->ifindex) 723 return (i); 724 return (NULL); 725 } 726 */ 727