1 /* $OpenBSD: ldpe.c,v 1.67 2016/06/18 17:31:32 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 <stdlib.h> 24 #include <signal.h> 25 #include <string.h> 26 #include <pwd.h> 27 #include <unistd.h> 28 #include <arpa/inet.h> 29 #include <errno.h> 30 31 #include "ldpd.h" 32 #include "ldpe.h" 33 #include "lde.h" 34 #include "control.h" 35 #include "log.h" 36 37 static void ldpe_sig_handler(int, short, void *); 38 static void ldpe_shutdown(void); 39 static void ldpe_dispatch_main(int, short, void *); 40 static void ldpe_dispatch_lde(int, short, void *); 41 static void ldpe_dispatch_pfkey(int, short, void *); 42 static void ldpe_setup_sockets(int, int, int, int); 43 static void ldpe_close_sockets(int); 44 static void ldpe_iface_af_ctl(struct ctl_conn *, int, unsigned int); 45 46 struct ldpd_conf *leconf; 47 struct ldpd_sysdep sysdep; 48 49 static struct imsgev *iev_main; 50 static struct imsgev *iev_lde; 51 static struct event pfkey_ev; 52 53 /* ARGSUSED */ 54 static void 55 ldpe_sig_handler(int sig, short event, void *bula) 56 { 57 switch (sig) { 58 case SIGINT: 59 case SIGTERM: 60 ldpe_shutdown(); 61 /* NOTREACHED */ 62 default: 63 fatalx("unexpected signal"); 64 } 65 } 66 67 /* label distribution protocol engine */ 68 pid_t 69 ldpe(int debug, int verbose) 70 { 71 struct passwd *pw; 72 struct event ev_sigint, ev_sigterm; 73 74 leconf = config_new_empty(); 75 76 log_init(debug); 77 log_verbose(verbose); 78 79 setproctitle("ldp engine"); 80 ldpd_process = PROC_LDP_ENGINE; 81 82 /* create ldpd control socket outside chroot */ 83 if (control_init() == -1) 84 fatalx("control socket setup failed"); 85 86 LIST_INIT(&global.addr_list); 87 LIST_INIT(&global.adj_list); 88 TAILQ_INIT(&global.pending_conns); 89 if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1) 90 fatal("inet_pton"); 91 if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1) 92 fatal("inet_pton"); 93 global.pfkeysock = pfkey_init(); 94 95 if ((pw = getpwnam(LDPD_USER)) == NULL) 96 fatal("getpwnam"); 97 98 if (chroot(pw->pw_dir) == -1) 99 fatal("chroot"); 100 if (chdir("/") == -1) 101 fatal("chdir(\"/\")"); 102 103 if (setgroups(1, &pw->pw_gid) || 104 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 105 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 106 fatal("can't drop privileges"); 107 108 if (pledge("stdio cpath inet mcast recvfd", NULL) == -1) 109 fatal("pledge"); 110 111 event_init(); 112 accept_init(); 113 114 /* setup signal handler */ 115 signal_set(&ev_sigint, SIGINT, ldpe_sig_handler, NULL); 116 signal_set(&ev_sigterm, SIGTERM, ldpe_sig_handler, NULL); 117 signal_add(&ev_sigint, NULL); 118 signal_add(&ev_sigterm, NULL); 119 signal(SIGPIPE, SIG_IGN); 120 signal(SIGHUP, SIG_IGN); 121 122 /* setup pipe and event handler to the parent process */ 123 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 124 fatal(NULL); 125 imsg_init(&iev_main->ibuf, 3); 126 iev_main->handler = ldpe_dispatch_main; 127 iev_main->events = EV_READ; 128 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 129 iev_main->handler, iev_main); 130 event_add(&iev_main->ev, NULL); 131 132 if (sysdep.no_pfkey == 0) { 133 event_set(&pfkey_ev, global.pfkeysock, EV_READ | EV_PERSIST, 134 ldpe_dispatch_pfkey, NULL); 135 event_add(&pfkey_ev, NULL); 136 } 137 138 /* mark sockets as closed */ 139 global.ipv4.ldp_disc_socket = -1; 140 global.ipv4.ldp_edisc_socket = -1; 141 global.ipv4.ldp_session_socket = -1; 142 global.ipv6.ldp_disc_socket = -1; 143 global.ipv6.ldp_edisc_socket = -1; 144 global.ipv6.ldp_session_socket = -1; 145 146 /* listen on ldpd control socket */ 147 TAILQ_INIT(&ctl_conns); 148 control_listen(); 149 150 if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL) 151 fatal(__func__); 152 153 event_dispatch(); 154 155 ldpe_shutdown(); 156 /* NOTREACHED */ 157 return (0); 158 } 159 160 static void 161 ldpe_shutdown(void) 162 { 163 struct if_addr *if_addr; 164 struct adj *adj; 165 166 control_cleanup(); 167 config_clear(leconf); 168 169 if (sysdep.no_pfkey == 0) { 170 event_del(&pfkey_ev); 171 close(global.pfkeysock); 172 } 173 ldpe_close_sockets(AF_INET); 174 ldpe_close_sockets(AF_INET6); 175 176 /* remove addresses from global list */ 177 while ((if_addr = LIST_FIRST(&global.addr_list)) != NULL) { 178 LIST_REMOVE(if_addr, entry); 179 free(if_addr); 180 } 181 while ((adj = LIST_FIRST(&global.adj_list)) != NULL) 182 adj_del(adj, S_SHUTDOWN); 183 184 /* clean up */ 185 msgbuf_write(&iev_lde->ibuf.w); 186 msgbuf_clear(&iev_lde->ibuf.w); 187 free(iev_lde); 188 msgbuf_write(&iev_main->ibuf.w); 189 msgbuf_clear(&iev_main->ibuf.w); 190 free(iev_main); 191 free(pkt_ptr); 192 193 log_info("ldp engine exiting"); 194 _exit(0); 195 } 196 197 /* imesg */ 198 int 199 ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen) 200 { 201 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); 202 } 203 204 int 205 ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data, 206 uint16_t datalen) 207 { 208 return (imsg_compose_event(iev_lde, type, peerid, pid, -1, 209 data, datalen)); 210 } 211 212 /* ARGSUSED */ 213 static void 214 ldpe_dispatch_main(int fd, short event, void *bula) 215 { 216 static struct ldpd_conf *nconf; 217 struct iface *niface; 218 struct tnbr *ntnbr; 219 struct nbr_params *nnbrp; 220 static struct l2vpn *nl2vpn; 221 struct l2vpn_if *nlif; 222 struct l2vpn_pw *npw; 223 struct imsg imsg; 224 struct imsgev *iev = bula; 225 struct imsgbuf *ibuf = &iev->ibuf; 226 struct iface *iface = NULL; 227 struct kif *kif; 228 int af; 229 enum socket_type *socket_type; 230 static int disc_socket = -1; 231 static int edisc_socket = -1; 232 static int session_socket = -1; 233 struct nbr *nbr; 234 struct nbr_params *nbrp; 235 int n, shut = 0; 236 237 if (event & EV_READ) { 238 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 239 fatal("imsg_read error"); 240 if (n == 0) /* connection closed */ 241 shut = 1; 242 } 243 if (event & EV_WRITE) { 244 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 245 fatal("ldpe_dispatch_main: msgbuf_write"); 246 if (n == 0) 247 shut = 1; 248 } 249 250 for (;;) { 251 if ((n = imsg_get(ibuf, &imsg)) == -1) 252 fatal("ldpe_dispatch_main: imsg_get error"); 253 if (n == 0) 254 break; 255 256 switch (imsg.hdr.type) { 257 case IMSG_IFSTATUS: 258 if (imsg.hdr.len != IMSG_HEADER_SIZE + 259 sizeof(struct kif)) 260 fatalx("IFSTATUS imsg with wrong len"); 261 kif = imsg.data; 262 263 iface = if_lookup(leconf, kif->ifindex); 264 if (!iface) 265 break; 266 267 iface->flags = kif->flags; 268 iface->linkstate = kif->link_state; 269 if_update(iface, AF_UNSPEC); 270 break; 271 case IMSG_NEWADDR: 272 if (imsg.hdr.len != IMSG_HEADER_SIZE + 273 sizeof(struct kaddr)) 274 fatalx("NEWADDR imsg with wrong len"); 275 276 if_addr_add(imsg.data); 277 break; 278 case IMSG_DELADDR: 279 if (imsg.hdr.len != IMSG_HEADER_SIZE + 280 sizeof(struct kaddr)) 281 fatalx("DELADDR imsg with wrong len"); 282 283 if_addr_del(imsg.data); 284 break; 285 case IMSG_SOCKET_IPC: 286 if (iev_lde) { 287 log_warnx("%s: received unexpected imsg fd " 288 "to lde", __func__); 289 break; 290 } 291 if ((fd = imsg.fd) == -1) { 292 log_warnx("%s: expected to receive imsg fd to " 293 "lde but didn't receive any", __func__); 294 break; 295 } 296 297 if ((iev_lde = malloc(sizeof(struct imsgev))) == NULL) 298 fatal(NULL); 299 imsg_init(&iev_lde->ibuf, fd); 300 iev_lde->handler = ldpe_dispatch_lde; 301 iev_lde->events = EV_READ; 302 event_set(&iev_lde->ev, iev_lde->ibuf.fd, 303 iev_lde->events, iev_lde->handler, iev_lde); 304 event_add(&iev_lde->ev, NULL); 305 break; 306 case IMSG_CLOSE_SOCKETS: 307 af = imsg.hdr.peerid; 308 309 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 310 if (nbr->af != af) 311 continue; 312 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 313 pfkey_remove(nbr); 314 } 315 ldpe_close_sockets(af); 316 if_update_all(af); 317 tnbr_update_all(af); 318 319 disc_socket = -1; 320 edisc_socket = -1; 321 session_socket = -1; 322 if ((ldp_af_conf_get(leconf, af))->flags & 323 F_LDPD_AF_ENABLED) 324 ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS, 325 af, NULL, 0); 326 break; 327 case IMSG_SOCKET_NET: 328 if (imsg.hdr.len != IMSG_HEADER_SIZE + 329 sizeof(enum socket_type)) 330 fatalx("SOCKET_NET imsg with wrong len"); 331 socket_type = imsg.data; 332 333 switch (*socket_type) { 334 case LDP_SOCKET_DISC: 335 disc_socket = imsg.fd; 336 break; 337 case LDP_SOCKET_EDISC: 338 edisc_socket = imsg.fd; 339 break; 340 case LDP_SOCKET_SESSION: 341 session_socket = imsg.fd; 342 break; 343 } 344 break; 345 case IMSG_SETUP_SOCKETS: 346 af = imsg.hdr.peerid; 347 if (disc_socket == -1 || edisc_socket == -1 || 348 session_socket == -1) { 349 if (disc_socket != -1) 350 close(disc_socket); 351 if (edisc_socket != -1) 352 close(edisc_socket); 353 if (session_socket != -1) 354 close(session_socket); 355 break; 356 } 357 358 ldpe_setup_sockets(af, disc_socket, edisc_socket, 359 session_socket); 360 if_update_all(af); 361 tnbr_update_all(af); 362 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 363 if (nbr->af != af) 364 continue; 365 nbr->laddr = (ldp_af_conf_get(leconf, 366 af))->trans_addr; 367 nbrp = nbr_params_find(leconf, nbr->id); 368 if (nbrp && pfkey_establish(nbr, nbrp) == -1) 369 fatalx("pfkey setup failed"); 370 if (nbr_session_active_role(nbr)) 371 nbr_establish_connection(nbr); 372 } 373 break; 374 case IMSG_RECONF_CONF: 375 if ((nconf = malloc(sizeof(struct ldpd_conf))) == 376 NULL) 377 fatal(NULL); 378 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); 379 380 LIST_INIT(&nconf->iface_list); 381 LIST_INIT(&nconf->tnbr_list); 382 LIST_INIT(&nconf->nbrp_list); 383 LIST_INIT(&nconf->l2vpn_list); 384 break; 385 case IMSG_RECONF_IFACE: 386 if ((niface = malloc(sizeof(struct iface))) == NULL) 387 fatal(NULL); 388 memcpy(niface, imsg.data, sizeof(struct iface)); 389 390 LIST_INIT(&niface->addr_list); 391 LIST_INIT(&niface->ipv4.adj_list); 392 LIST_INIT(&niface->ipv6.adj_list); 393 niface->ipv4.iface = niface; 394 niface->ipv6.iface = niface; 395 396 LIST_INSERT_HEAD(&nconf->iface_list, niface, entry); 397 break; 398 case IMSG_RECONF_TNBR: 399 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL) 400 fatal(NULL); 401 memcpy(ntnbr, imsg.data, sizeof(struct tnbr)); 402 403 LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry); 404 break; 405 case IMSG_RECONF_NBRP: 406 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL) 407 fatal(NULL); 408 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params)); 409 410 LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry); 411 break; 412 case IMSG_RECONF_L2VPN: 413 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL) 414 fatal(NULL); 415 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); 416 417 LIST_INIT(&nl2vpn->if_list); 418 LIST_INIT(&nl2vpn->pw_list); 419 420 LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry); 421 break; 422 case IMSG_RECONF_L2VPN_IF: 423 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL) 424 fatal(NULL); 425 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if)); 426 427 nlif->l2vpn = nl2vpn; 428 LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry); 429 break; 430 case IMSG_RECONF_L2VPN_PW: 431 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) 432 fatal(NULL); 433 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); 434 435 npw->l2vpn = nl2vpn; 436 LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry); 437 break; 438 case IMSG_RECONF_END: 439 merge_config(leconf, nconf); 440 nconf = NULL; 441 global.conf_seqnum++; 442 break; 443 case IMSG_CTL_KROUTE: 444 case IMSG_CTL_KROUTE_ADDR: 445 case IMSG_CTL_IFINFO: 446 case IMSG_CTL_END: 447 control_imsg_relay(&imsg); 448 break; 449 default: 450 log_debug("ldpe_dispatch_main: error handling imsg %d", 451 imsg.hdr.type); 452 break; 453 } 454 imsg_free(&imsg); 455 } 456 if (!shut) 457 imsg_event_add(iev); 458 else { 459 /* this pipe is dead, so remove the event handler */ 460 event_del(&iev->ev); 461 event_loopexit(NULL); 462 } 463 } 464 465 /* ARGSUSED */ 466 static void 467 ldpe_dispatch_lde(int fd, short event, void *bula) 468 { 469 struct imsgev *iev = bula; 470 struct imsgbuf *ibuf = &iev->ibuf; 471 struct imsg imsg; 472 struct map map; 473 struct notify_msg nm; 474 int n, shut = 0; 475 struct nbr *nbr = NULL; 476 477 if (event & EV_READ) { 478 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 479 fatal("imsg_read error"); 480 if (n == 0) /* connection closed */ 481 shut = 1; 482 } 483 if (event & EV_WRITE) { 484 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 485 fatal("ldpe_dispatch_lde: msgbuf_write"); 486 if (n == 0) 487 shut = 1; 488 } 489 490 for (;;) { 491 if ((n = imsg_get(ibuf, &imsg)) == -1) 492 fatal("ldpe_dispatch_lde: imsg_get error"); 493 if (n == 0) 494 break; 495 496 switch (imsg.hdr.type) { 497 case IMSG_MAPPING_ADD: 498 case IMSG_RELEASE_ADD: 499 case IMSG_REQUEST_ADD: 500 case IMSG_WITHDRAW_ADD: 501 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map)) 502 fatalx("invalid size of map request"); 503 memcpy(&map, imsg.data, sizeof(map)); 504 505 nbr = nbr_find_peerid(imsg.hdr.peerid); 506 if (nbr == NULL) { 507 log_debug("ldpe_dispatch_lde: cannot find " 508 "neighbor"); 509 break; 510 } 511 if (nbr->state != NBR_STA_OPER) 512 break; 513 514 switch (imsg.hdr.type) { 515 case IMSG_MAPPING_ADD: 516 mapping_list_add(&nbr->mapping_list, &map); 517 break; 518 case IMSG_RELEASE_ADD: 519 mapping_list_add(&nbr->release_list, &map); 520 break; 521 case IMSG_REQUEST_ADD: 522 mapping_list_add(&nbr->request_list, &map); 523 break; 524 case IMSG_WITHDRAW_ADD: 525 mapping_list_add(&nbr->withdraw_list, &map); 526 break; 527 } 528 break; 529 case IMSG_MAPPING_ADD_END: 530 case IMSG_RELEASE_ADD_END: 531 case IMSG_REQUEST_ADD_END: 532 case IMSG_WITHDRAW_ADD_END: 533 nbr = nbr_find_peerid(imsg.hdr.peerid); 534 if (nbr == NULL) { 535 log_debug("ldpe_dispatch_lde: cannot find " 536 "neighbor"); 537 break; 538 } 539 if (nbr->state != NBR_STA_OPER) 540 break; 541 542 switch (imsg.hdr.type) { 543 case IMSG_MAPPING_ADD_END: 544 send_labelmessage(nbr, MSG_TYPE_LABELMAPPING, 545 &nbr->mapping_list); 546 break; 547 case IMSG_RELEASE_ADD_END: 548 send_labelmessage(nbr, MSG_TYPE_LABELRELEASE, 549 &nbr->release_list); 550 break; 551 case IMSG_REQUEST_ADD_END: 552 send_labelmessage(nbr, MSG_TYPE_LABELREQUEST, 553 &nbr->request_list); 554 break; 555 case IMSG_WITHDRAW_ADD_END: 556 send_labelmessage(nbr, MSG_TYPE_LABELWITHDRAW, 557 &nbr->withdraw_list); 558 break; 559 } 560 break; 561 case IMSG_NOTIFICATION_SEND: 562 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm)) 563 fatalx("invalid size of OE request"); 564 memcpy(&nm, imsg.data, sizeof(nm)); 565 566 nbr = nbr_find_peerid(imsg.hdr.peerid); 567 if (nbr == NULL) { 568 log_debug("ldpe_dispatch_lde: cannot find " 569 "neighbor"); 570 break; 571 } 572 if (nbr->state != NBR_STA_OPER) 573 break; 574 575 send_notification_full(nbr->tcp, &nm); 576 break; 577 case IMSG_CTL_END: 578 case IMSG_CTL_SHOW_LIB: 579 case IMSG_CTL_SHOW_L2VPN_PW: 580 case IMSG_CTL_SHOW_L2VPN_BINDING: 581 control_imsg_relay(&imsg); 582 break; 583 default: 584 log_debug("ldpe_dispatch_lde: error handling imsg %d", 585 imsg.hdr.type); 586 break; 587 } 588 imsg_free(&imsg); 589 } 590 if (!shut) 591 imsg_event_add(iev); 592 else { 593 /* this pipe is dead, so remove the event handler */ 594 event_del(&iev->ev); 595 event_loopexit(NULL); 596 } 597 } 598 599 /* ARGSUSED */ 600 static void 601 ldpe_dispatch_pfkey(int fd, short event, void *bula) 602 { 603 if (event & EV_READ) { 604 if (pfkey_read(fd, NULL) == -1) { 605 fatal("pfkey_read failed, exiting..."); 606 } 607 } 608 } 609 610 static void 611 ldpe_setup_sockets(int af, int disc_socket, int edisc_socket, 612 int session_socket) 613 { 614 struct ldpd_af_global *af_global; 615 616 af_global = ldp_af_global_get(&global, af); 617 618 /* discovery socket */ 619 af_global->ldp_disc_socket = disc_socket; 620 event_set(&af_global->disc_ev, af_global->ldp_disc_socket, 621 EV_READ|EV_PERSIST, disc_recv_packet, NULL); 622 event_add(&af_global->disc_ev, NULL); 623 624 /* extended discovery socket */ 625 af_global->ldp_edisc_socket = edisc_socket; 626 event_set(&af_global->edisc_ev, af_global->ldp_edisc_socket, 627 EV_READ|EV_PERSIST, disc_recv_packet, NULL); 628 event_add(&af_global->edisc_ev, NULL); 629 630 /* session socket */ 631 af_global->ldp_session_socket = session_socket; 632 accept_add(af_global->ldp_session_socket, session_accept, NULL); 633 } 634 635 static void 636 ldpe_close_sockets(int af) 637 { 638 struct ldpd_af_global *af_global; 639 640 af_global = ldp_af_global_get(&global, af); 641 642 /* discovery socket */ 643 if (event_initialized(&af_global->disc_ev)) 644 event_del(&af_global->disc_ev); 645 if (af_global->ldp_disc_socket != -1) { 646 close(af_global->ldp_disc_socket); 647 af_global->ldp_disc_socket = -1; 648 } 649 650 /* extended discovery socket */ 651 if (event_initialized(&af_global->edisc_ev)) 652 event_del(&af_global->edisc_ev); 653 if (af_global->ldp_edisc_socket != -1) { 654 close(af_global->ldp_edisc_socket); 655 af_global->ldp_edisc_socket = -1; 656 } 657 658 /* session socket */ 659 if (af_global->ldp_session_socket != -1) { 660 accept_del(af_global->ldp_session_socket); 661 close(af_global->ldp_session_socket); 662 af_global->ldp_session_socket = -1; 663 } 664 } 665 666 void 667 ldpe_reset_nbrs(int af) 668 { 669 struct nbr *nbr; 670 671 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 672 if (nbr->af == af) 673 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 674 } 675 } 676 677 void 678 ldpe_reset_ds_nbrs(void) 679 { 680 struct nbr *nbr; 681 682 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 683 if (nbr->ds_tlv) 684 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 685 } 686 } 687 688 void 689 ldpe_remove_dynamic_tnbrs(int af) 690 { 691 struct tnbr *tnbr, *safe; 692 693 LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) { 694 if (tnbr->af != af) 695 continue; 696 697 tnbr->flags &= ~F_TNBR_DYNAMIC; 698 tnbr_check(tnbr); 699 } 700 } 701 702 void 703 ldpe_stop_init_backoff(int af) 704 { 705 struct nbr *nbr; 706 707 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) { 708 if (nbr->af == af && nbr_pending_idtimer(nbr)) { 709 nbr_stop_idtimer(nbr); 710 nbr_establish_connection(nbr); 711 } 712 } 713 } 714 715 static void 716 ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx) 717 { 718 struct iface *iface; 719 struct iface_af *ia; 720 struct ctl_iface *ictl; 721 722 LIST_FOREACH(iface, &leconf->iface_list, entry) { 723 if (idx == 0 || idx == iface->ifindex) { 724 ia = iface_af_get(iface, af); 725 if (!ia->enabled) 726 continue; 727 728 ictl = if_to_ctl(ia); 729 imsg_compose_event(&c->iev, 730 IMSG_CTL_SHOW_INTERFACE, 731 0, 0, -1, ictl, sizeof(struct ctl_iface)); 732 } 733 } 734 } 735 736 void 737 ldpe_iface_ctl(struct ctl_conn *c, unsigned int idx) 738 { 739 ldpe_iface_af_ctl(c, AF_INET, idx); 740 ldpe_iface_af_ctl(c, AF_INET6, idx); 741 } 742 743 void 744 ldpe_adj_ctl(struct ctl_conn *c) 745 { 746 struct nbr *nbr; 747 struct adj *adj; 748 struct ctl_adj *actl; 749 750 RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) { 751 LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) { 752 actl = adj_to_ctl(adj); 753 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 754 0, 0, -1, actl, sizeof(struct ctl_adj)); 755 } 756 } 757 /* show adjacencies not associated with any neighbor */ 758 LIST_FOREACH(adj, &global.adj_list, global_entry) { 759 if (adj->nbr != NULL) 760 continue; 761 762 actl = adj_to_ctl(adj); 763 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, 764 -1, actl, sizeof(struct ctl_adj)); 765 } 766 767 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); 768 } 769 770 void 771 ldpe_nbr_ctl(struct ctl_conn *c) 772 { 773 struct nbr *nbr; 774 struct ctl_nbr *nctl; 775 776 RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) { 777 nctl = nbr_to_ctl(nbr); 778 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, 779 sizeof(struct ctl_nbr)); 780 } 781 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); 782 } 783 784 void 785 mapping_list_add(struct mapping_head *mh, struct map *map) 786 { 787 struct mapping_entry *me; 788 789 me = calloc(1, sizeof(*me)); 790 if (me == NULL) 791 fatal(__func__); 792 me->map = *map; 793 794 TAILQ_INSERT_TAIL(mh, me, entry); 795 } 796 797 void 798 mapping_list_clr(struct mapping_head *mh) 799 { 800 struct mapping_entry *me; 801 802 while ((me = TAILQ_FIRST(mh)) != NULL) { 803 TAILQ_REMOVE(mh, me, entry); 804 free(me); 805 } 806 } 807