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