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