1 /* $OpenBSD: lde.c,v 1.78 2024/04/23 13:34:51 jsg Exp $ */ 2 3 /* 4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> 5 * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> 6 * Copyright (c) 2004 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 <sys/time.h> 24 #include <sys/socket.h> 25 #include <netinet/in.h> 26 #include <netmpls/mpls.h> 27 #include <arpa/inet.h> 28 #include <errno.h> 29 #include <stdlib.h> 30 #include <signal.h> 31 #include <string.h> 32 #include <pwd.h> 33 #include <unistd.h> 34 #include <limits.h> 35 36 #include "ldp.h" 37 #include "ldpd.h" 38 #include "ldpe.h" 39 #include "log.h" 40 #include "lde.h" 41 42 static void lde_sig_handler(int sig, short, void *); 43 static __dead void lde_shutdown(void); 44 static int lde_imsg_compose_parent(int, pid_t, void *, uint16_t); 45 static void lde_dispatch_imsg(int, short, void *); 46 static void lde_dispatch_parent(int, short, void *); 47 static __inline int lde_nbr_compare(struct lde_nbr *, 48 struct lde_nbr *); 49 static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *); 50 static void lde_nbr_del(struct lde_nbr *); 51 static struct lde_nbr *lde_nbr_find(uint32_t); 52 static void lde_nbr_clear(void); 53 static void lde_nbr_addr_update(struct lde_nbr *, 54 struct lde_addr *, int); 55 static void lde_map_free(void *); 56 static int lde_address_add(struct lde_nbr *, struct lde_addr *); 57 static int lde_address_del(struct lde_nbr *, struct lde_addr *); 58 static void lde_address_list_free(struct lde_nbr *); 59 60 RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare) 61 62 struct ldpd_conf *ldeconf; 63 struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs); 64 65 static struct imsgev *iev_ldpe; 66 static struct imsgev *iev_main; 67 68 static void 69 lde_sig_handler(int sig, short event, void *arg) 70 { 71 /* 72 * signal handler rules don't apply, libevent decouples for us 73 */ 74 75 switch (sig) { 76 case SIGINT: 77 case SIGTERM: 78 lde_shutdown(); 79 /* NOTREACHED */ 80 default: 81 fatalx("unexpected signal"); 82 } 83 } 84 85 /* label decision engine */ 86 void 87 lde(int debug, int verbose) 88 { 89 struct event ev_sigint, ev_sigterm; 90 struct timeval now; 91 struct passwd *pw; 92 93 ldeconf = config_new_empty(); 94 95 log_init(debug); 96 log_verbose(verbose); 97 98 setproctitle("label decision engine"); 99 ldpd_process = PROC_LDE_ENGINE; 100 log_procname = "lde"; 101 102 if ((pw = getpwnam(LDPD_USER)) == NULL) 103 fatal("getpwnam"); 104 105 if (chroot(pw->pw_dir) == -1) 106 fatal("chroot"); 107 if (chdir("/") == -1) 108 fatal("chdir(\"/\")"); 109 110 if (setgroups(1, &pw->pw_gid) || 111 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 112 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 113 fatal("can't drop privileges"); 114 115 if (pledge("stdio recvfd", NULL) == -1) 116 fatal("pledge"); 117 118 event_init(); 119 120 /* setup signal handler */ 121 signal_set(&ev_sigint, SIGINT, lde_sig_handler, NULL); 122 signal_set(&ev_sigterm, SIGTERM, lde_sig_handler, NULL); 123 signal_add(&ev_sigint, NULL); 124 signal_add(&ev_sigterm, NULL); 125 signal(SIGPIPE, SIG_IGN); 126 signal(SIGHUP, SIG_IGN); 127 128 /* setup pipe and event handler to the parent process */ 129 if ((iev_main = malloc(sizeof(struct imsgev))) == NULL) 130 fatal(NULL); 131 imsg_init(&iev_main->ibuf, 3); 132 iev_main->handler = lde_dispatch_parent; 133 iev_main->events = EV_READ; 134 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events, 135 iev_main->handler, iev_main); 136 event_add(&iev_main->ev, NULL); 137 138 /* setup and start the LIB garbage collector */ 139 evtimer_set(&gc_timer, lde_gc_timer, NULL); 140 lde_gc_start_timer(); 141 142 gettimeofday(&now, NULL); 143 global.uptime = now.tv_sec; 144 145 event_dispatch(); 146 147 lde_shutdown(); 148 } 149 150 static __dead void 151 lde_shutdown(void) 152 { 153 /* close pipes */ 154 msgbuf_clear(&iev_ldpe->ibuf.w); 155 close(iev_ldpe->ibuf.fd); 156 msgbuf_clear(&iev_main->ibuf.w); 157 close(iev_main->ibuf.fd); 158 159 lde_gc_stop_timer(); 160 lde_nbr_clear(); 161 fec_tree_clear(); 162 163 config_clear(ldeconf); 164 165 free(iev_ldpe); 166 free(iev_main); 167 168 log_info("label decision engine exiting"); 169 exit(0); 170 } 171 172 /* imesg */ 173 static int 174 lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen) 175 { 176 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen)); 177 } 178 179 int 180 lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data, 181 uint16_t datalen) 182 { 183 return (imsg_compose_event(iev_ldpe, type, peerid, pid, 184 -1, data, datalen)); 185 } 186 187 static void 188 lde_dispatch_imsg(int fd, short event, void *bula) 189 { 190 struct imsgev *iev = bula; 191 struct imsgbuf *ibuf = &iev->ibuf; 192 struct imsg imsg; 193 struct lde_nbr *ln; 194 struct map map; 195 struct lde_addr lde_addr; 196 struct notify_msg nm; 197 ssize_t n; 198 int shut = 0, verbose; 199 200 if (event & EV_READ) { 201 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 202 fatal("imsg_read error"); 203 if (n == 0) /* connection closed */ 204 shut = 1; 205 } 206 if (event & EV_WRITE) { 207 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 208 fatal("msgbuf_write"); 209 if (n == 0) /* connection closed */ 210 shut = 1; 211 } 212 213 for (;;) { 214 if ((n = imsg_get(ibuf, &imsg)) == -1) 215 fatal("lde_dispatch_imsg: imsg_get error"); 216 if (n == 0) 217 break; 218 219 switch (imsg.hdr.type) { 220 case IMSG_LABEL_MAPPING_FULL: 221 ln = lde_nbr_find(imsg.hdr.peerid); 222 if (ln == NULL) { 223 log_debug("%s: cannot find lde neighbor", 224 __func__); 225 break; 226 } 227 228 fec_snap(ln); 229 break; 230 case IMSG_LABEL_MAPPING: 231 case IMSG_LABEL_REQUEST: 232 case IMSG_LABEL_RELEASE: 233 case IMSG_LABEL_WITHDRAW: 234 case IMSG_LABEL_ABORT: 235 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map)) 236 fatalx("lde_dispatch_imsg: wrong imsg len"); 237 memcpy(&map, imsg.data, sizeof(map)); 238 239 ln = lde_nbr_find(imsg.hdr.peerid); 240 if (ln == NULL) { 241 log_debug("%s: cannot find lde neighbor", 242 __func__); 243 break; 244 } 245 246 switch (imsg.hdr.type) { 247 case IMSG_LABEL_MAPPING: 248 lde_check_mapping(&map, ln); 249 break; 250 case IMSG_LABEL_REQUEST: 251 lde_check_request(&map, ln); 252 break; 253 case IMSG_LABEL_RELEASE: 254 lde_check_release(&map, ln); 255 break; 256 case IMSG_LABEL_WITHDRAW: 257 lde_check_withdraw(&map, ln); 258 break; 259 case IMSG_LABEL_ABORT: 260 /* not necessary */ 261 break; 262 } 263 break; 264 case IMSG_ADDRESS_ADD: 265 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr)) 266 fatalx("lde_dispatch_imsg: wrong imsg len"); 267 memcpy(&lde_addr, imsg.data, sizeof(lde_addr)); 268 269 ln = lde_nbr_find(imsg.hdr.peerid); 270 if (ln == NULL) { 271 log_debug("%s: cannot find lde neighbor", 272 __func__); 273 break; 274 } 275 if (lde_address_add(ln, &lde_addr) < 0) { 276 log_debug("%s: cannot add address %s, it " 277 "already exists", __func__, 278 log_addr(lde_addr.af, &lde_addr.addr)); 279 } 280 break; 281 case IMSG_ADDRESS_DEL: 282 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr)) 283 fatalx("lde_dispatch_imsg: wrong imsg len"); 284 memcpy(&lde_addr, imsg.data, sizeof(lde_addr)); 285 286 ln = lde_nbr_find(imsg.hdr.peerid); 287 if (ln == NULL) { 288 log_debug("%s: cannot find lde neighbor", 289 __func__); 290 break; 291 } 292 if (lde_address_del(ln, &lde_addr) < 0) { 293 log_debug("%s: cannot delete address %s, it " 294 "does not exist", __func__, 295 log_addr(lde_addr.af, &lde_addr.addr)); 296 } 297 break; 298 case IMSG_NOTIFICATION: 299 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm)) 300 fatalx("lde_dispatch_imsg: wrong imsg len"); 301 memcpy(&nm, imsg.data, sizeof(nm)); 302 303 ln = lde_nbr_find(imsg.hdr.peerid); 304 if (ln == NULL) { 305 log_debug("%s: cannot find lde neighbor", 306 __func__); 307 break; 308 } 309 310 switch (nm.status_code) { 311 case S_PW_STATUS: 312 l2vpn_recv_pw_status(ln, &nm); 313 break; 314 case S_ENDOFLIB: 315 /* 316 * Do nothing for now. Should be useful in 317 * the future when we implement LDP-IGP 318 * Synchronization (RFC 5443) and Graceful 319 * Restart (RFC 3478). 320 */ 321 default: 322 break; 323 } 324 break; 325 case IMSG_NEIGHBOR_UP: 326 if (imsg.hdr.len - IMSG_HEADER_SIZE != 327 sizeof(struct lde_nbr)) 328 fatalx("lde_dispatch_imsg: wrong imsg len"); 329 330 if (lde_nbr_find(imsg.hdr.peerid)) 331 fatalx("lde_dispatch_imsg: " 332 "neighbor already exists"); 333 lde_nbr_new(imsg.hdr.peerid, imsg.data); 334 break; 335 case IMSG_NEIGHBOR_DOWN: 336 lde_nbr_del(lde_nbr_find(imsg.hdr.peerid)); 337 break; 338 case IMSG_CTL_SHOW_LIB: 339 rt_dump(imsg.hdr.pid); 340 341 lde_imsg_compose_ldpe(IMSG_CTL_END, 0, 342 imsg.hdr.pid, NULL, 0); 343 break; 344 case IMSG_CTL_SHOW_L2VPN_PW: 345 l2vpn_pw_ctl(imsg.hdr.pid); 346 347 lde_imsg_compose_ldpe(IMSG_CTL_END, 0, 348 imsg.hdr.pid, NULL, 0); 349 break; 350 case IMSG_CTL_SHOW_L2VPN_BINDING: 351 l2vpn_binding_ctl(imsg.hdr.pid); 352 353 lde_imsg_compose_ldpe(IMSG_CTL_END, 0, 354 imsg.hdr.pid, NULL, 0); 355 break; 356 case IMSG_CTL_LOG_VERBOSE: 357 /* already checked by ldpe */ 358 memcpy(&verbose, imsg.data, sizeof(verbose)); 359 log_verbose(verbose); 360 break; 361 default: 362 log_debug("%s: unexpected imsg %d", __func__, 363 imsg.hdr.type); 364 break; 365 } 366 imsg_free(&imsg); 367 } 368 if (!shut) 369 imsg_event_add(iev); 370 else { 371 /* this pipe is dead, so remove the event handler */ 372 event_del(&iev->ev); 373 event_loopexit(NULL); 374 } 375 } 376 377 static void 378 lde_dispatch_parent(int fd, short event, void *bula) 379 { 380 static struct ldpd_conf *nconf; 381 struct iface *niface; 382 struct tnbr *ntnbr; 383 struct nbr_params *nnbrp; 384 static struct l2vpn *nl2vpn; 385 struct l2vpn_if *nlif; 386 struct l2vpn_pw *npw; 387 struct imsg imsg; 388 struct kroute kr; 389 struct imsgev *iev = bula; 390 struct imsgbuf *ibuf = &iev->ibuf; 391 ssize_t n; 392 int shut = 0; 393 struct fec fec; 394 395 if (event & EV_READ) { 396 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) 397 fatal("imsg_read error"); 398 if (n == 0) /* connection closed */ 399 shut = 1; 400 } 401 if (event & EV_WRITE) { 402 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) 403 fatal("msgbuf_write"); 404 if (n == 0) /* connection closed */ 405 shut = 1; 406 } 407 408 for (;;) { 409 if ((n = imsg_get(ibuf, &imsg)) == -1) 410 fatal("lde_dispatch_parent: imsg_get error"); 411 if (n == 0) 412 break; 413 414 switch (imsg.hdr.type) { 415 case IMSG_NETWORK_ADD: 416 case IMSG_NETWORK_DEL: 417 if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) { 418 log_warnx("%s: wrong imsg len", __func__); 419 break; 420 } 421 memcpy(&kr, imsg.data, sizeof(kr)); 422 423 switch (kr.af) { 424 case AF_INET: 425 fec.type = FEC_TYPE_IPV4; 426 fec.u.ipv4.prefix = kr.prefix.v4; 427 fec.u.ipv4.prefixlen = kr.prefixlen; 428 break; 429 case AF_INET6: 430 fec.type = FEC_TYPE_IPV6; 431 fec.u.ipv6.prefix = kr.prefix.v6; 432 fec.u.ipv6.prefixlen = kr.prefixlen; 433 break; 434 default: 435 fatalx("lde_dispatch_parent: unknown af"); 436 } 437 438 switch (imsg.hdr.type) { 439 case IMSG_NETWORK_ADD: 440 lde_kernel_insert(&fec, kr.af, &kr.nexthop, 441 kr.priority, kr.flags & F_CONNECTED, NULL); 442 break; 443 case IMSG_NETWORK_DEL: 444 lde_kernel_remove(&fec, kr.af, &kr.nexthop, 445 kr.priority); 446 break; 447 } 448 break; 449 case IMSG_SOCKET_IPC: 450 if (iev_ldpe) { 451 log_warnx("%s: received unexpected imsg fd " 452 "to ldpe", __func__); 453 break; 454 } 455 if ((fd = imsg_get_fd(&imsg)) == -1) { 456 log_warnx("%s: expected to receive imsg fd to " 457 "ldpe but didn't receive any", __func__); 458 break; 459 } 460 461 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL) 462 fatal(NULL); 463 imsg_init(&iev_ldpe->ibuf, fd); 464 iev_ldpe->handler = lde_dispatch_imsg; 465 iev_ldpe->events = EV_READ; 466 event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, 467 iev_ldpe->events, iev_ldpe->handler, iev_ldpe); 468 event_add(&iev_ldpe->ev, NULL); 469 break; 470 case IMSG_RECONF_CONF: 471 if ((nconf = malloc(sizeof(struct ldpd_conf))) == 472 NULL) 473 fatal(NULL); 474 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); 475 476 LIST_INIT(&nconf->iface_list); 477 LIST_INIT(&nconf->tnbr_list); 478 LIST_INIT(&nconf->nbrp_list); 479 LIST_INIT(&nconf->l2vpn_list); 480 LIST_INIT(&nconf->auth_list); 481 break; 482 case IMSG_RECONF_IFACE: 483 if ((niface = malloc(sizeof(struct iface))) == NULL) 484 fatal(NULL); 485 memcpy(niface, imsg.data, sizeof(struct iface)); 486 487 LIST_INIT(&niface->addr_list); 488 LIST_INIT(&niface->ipv4.adj_list); 489 LIST_INIT(&niface->ipv6.adj_list); 490 niface->ipv4.iface = niface; 491 niface->ipv6.iface = niface; 492 493 LIST_INSERT_HEAD(&nconf->iface_list, niface, entry); 494 break; 495 case IMSG_RECONF_TNBR: 496 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL) 497 fatal(NULL); 498 memcpy(ntnbr, imsg.data, sizeof(struct tnbr)); 499 500 LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry); 501 break; 502 case IMSG_RECONF_NBRP: 503 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL) 504 fatal(NULL); 505 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params)); 506 507 LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry); 508 break; 509 case IMSG_RECONF_L2VPN: 510 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL) 511 fatal(NULL); 512 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); 513 514 LIST_INIT(&nl2vpn->if_list); 515 LIST_INIT(&nl2vpn->pw_list); 516 517 LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry); 518 break; 519 case IMSG_RECONF_L2VPN_IF: 520 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL) 521 fatal(NULL); 522 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if)); 523 524 nlif->l2vpn = nl2vpn; 525 LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry); 526 break; 527 case IMSG_RECONF_L2VPN_PW: 528 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) 529 fatal(NULL); 530 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); 531 532 npw->l2vpn = nl2vpn; 533 LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry); 534 break; 535 case IMSG_RECONF_CONF_AUTH: { 536 struct ldp_auth *auth; 537 538 auth = malloc(sizeof(*auth)); 539 if (auth == NULL) 540 fatal(NULL); 541 542 memcpy(auth, imsg.data, sizeof(*auth)); 543 544 LIST_INSERT_HEAD(&nconf->auth_list, auth, entry); 545 break; 546 } 547 case IMSG_RECONF_END: 548 merge_config(ldeconf, nconf); 549 nconf = NULL; 550 break; 551 default: 552 log_debug("%s: unexpected imsg %d", __func__, 553 imsg.hdr.type); 554 break; 555 } 556 imsg_free(&imsg); 557 } 558 if (!shut) 559 imsg_event_add(iev); 560 else { 561 /* this pipe is dead, so remove the event handler */ 562 event_del(&iev->ev); 563 event_loopexit(NULL); 564 } 565 } 566 567 uint32_t 568 lde_assign_label(void) 569 { 570 static uint32_t label = MPLS_LABEL_RESERVED_MAX; 571 572 /* XXX some checks needed */ 573 label++; 574 return (label); 575 } 576 577 void 578 lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh) 579 { 580 struct kroute kr; 581 struct kpw kpw; 582 struct l2vpn_pw *pw; 583 584 switch (fn->fec.type) { 585 case FEC_TYPE_IPV4: 586 memset(&kr, 0, sizeof(kr)); 587 kr.af = AF_INET; 588 kr.prefix.v4 = fn->fec.u.ipv4.prefix; 589 kr.prefixlen = fn->fec.u.ipv4.prefixlen; 590 kr.nexthop.v4 = fnh->nexthop.v4; 591 kr.local_label = fn->local_label; 592 kr.remote_label = fnh->remote_label; 593 kr.priority = fnh->priority; 594 595 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, 596 sizeof(kr)); 597 598 if (fn->fec.u.ipv4.prefixlen == 32) 599 l2vpn_sync_pws(AF_INET, (union ldpd_addr *) 600 &fn->fec.u.ipv4.prefix); 601 break; 602 case FEC_TYPE_IPV6: 603 memset(&kr, 0, sizeof(kr)); 604 kr.af = AF_INET6; 605 kr.prefix.v6 = fn->fec.u.ipv6.prefix; 606 kr.prefixlen = fn->fec.u.ipv6.prefixlen; 607 kr.nexthop.v6 = fnh->nexthop.v6; 608 kr.local_label = fn->local_label; 609 kr.remote_label = fnh->remote_label; 610 kr.priority = fnh->priority; 611 612 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, 613 sizeof(kr)); 614 615 if (fn->fec.u.ipv6.prefixlen == 128) 616 l2vpn_sync_pws(AF_INET6, (union ldpd_addr *) 617 &fn->fec.u.ipv6.prefix); 618 break; 619 case FEC_TYPE_PWID: 620 if (fn->local_label == NO_LABEL || 621 fnh->remote_label == NO_LABEL) 622 return; 623 624 pw = (struct l2vpn_pw *) fn->data; 625 pw->flags |= F_PW_STATUS_UP; 626 627 memset(&kpw, 0, sizeof(kpw)); 628 kpw.ifindex = pw->ifindex; 629 kpw.pw_type = fn->fec.u.pwid.type; 630 kpw.af = pw->af; 631 kpw.nexthop = pw->addr; 632 kpw.local_label = fn->local_label; 633 kpw.remote_label = fnh->remote_label; 634 kpw.flags = pw->flags; 635 636 lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw, 637 sizeof(kpw)); 638 break; 639 } 640 } 641 642 void 643 lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh) 644 { 645 struct kroute kr; 646 struct kpw kpw; 647 struct l2vpn_pw *pw; 648 649 switch (fn->fec.type) { 650 case FEC_TYPE_IPV4: 651 memset(&kr, 0, sizeof(kr)); 652 kr.af = AF_INET; 653 kr.prefix.v4 = fn->fec.u.ipv4.prefix; 654 kr.prefixlen = fn->fec.u.ipv4.prefixlen; 655 kr.nexthop.v4 = fnh->nexthop.v4; 656 kr.local_label = fn->local_label; 657 kr.remote_label = fnh->remote_label; 658 kr.priority = fnh->priority; 659 660 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, 661 sizeof(kr)); 662 663 if (fn->fec.u.ipv4.prefixlen == 32) 664 l2vpn_sync_pws(AF_INET, (union ldpd_addr *) 665 &fn->fec.u.ipv4.prefix); 666 break; 667 case FEC_TYPE_IPV6: 668 memset(&kr, 0, sizeof(kr)); 669 kr.af = AF_INET6; 670 kr.prefix.v6 = fn->fec.u.ipv6.prefix; 671 kr.prefixlen = fn->fec.u.ipv6.prefixlen; 672 kr.nexthop.v6 = fnh->nexthop.v6; 673 kr.local_label = fn->local_label; 674 kr.remote_label = fnh->remote_label; 675 kr.priority = fnh->priority; 676 677 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, 678 sizeof(kr)); 679 680 if (fn->fec.u.ipv6.prefixlen == 128) 681 l2vpn_sync_pws(AF_INET6, (union ldpd_addr *) 682 &fn->fec.u.ipv6.prefix); 683 break; 684 case FEC_TYPE_PWID: 685 pw = (struct l2vpn_pw *) fn->data; 686 if (!(pw->flags & F_PW_STATUS_UP)) 687 return; 688 pw->flags &= ~F_PW_STATUS_UP; 689 690 memset(&kpw, 0, sizeof(kpw)); 691 kpw.ifindex = pw->ifindex; 692 kpw.pw_type = fn->fec.u.pwid.type; 693 kpw.af = pw->af; 694 kpw.nexthop = pw->addr; 695 kpw.local_label = fn->local_label; 696 kpw.remote_label = fnh->remote_label; 697 kpw.flags = pw->flags; 698 699 lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw, 700 sizeof(kpw)); 701 break; 702 } 703 } 704 705 void 706 lde_fec2map(struct fec *fec, struct map *map) 707 { 708 memset(map, 0, sizeof(*map)); 709 710 switch (fec->type) { 711 case FEC_TYPE_IPV4: 712 map->type = MAP_TYPE_PREFIX; 713 map->fec.prefix.af = AF_INET; 714 map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix; 715 map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen; 716 break; 717 case FEC_TYPE_IPV6: 718 map->type = MAP_TYPE_PREFIX; 719 map->fec.prefix.af = AF_INET6; 720 map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix; 721 map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen; 722 break; 723 case FEC_TYPE_PWID: 724 map->type = MAP_TYPE_PWID; 725 map->fec.pwid.type = fec->u.pwid.type; 726 map->fec.pwid.group_id = 0; 727 map->flags |= F_MAP_PW_ID; 728 map->fec.pwid.pwid = fec->u.pwid.pwid; 729 break; 730 } 731 } 732 733 void 734 lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec) 735 { 736 memset(fec, 0, sizeof(*fec)); 737 738 switch (map->type) { 739 case MAP_TYPE_PREFIX: 740 switch (map->fec.prefix.af) { 741 case AF_INET: 742 fec->type = FEC_TYPE_IPV4; 743 fec->u.ipv4.prefix = map->fec.prefix.prefix.v4; 744 fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen; 745 break; 746 case AF_INET6: 747 fec->type = FEC_TYPE_IPV6; 748 fec->u.ipv6.prefix = map->fec.prefix.prefix.v6; 749 fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen; 750 break; 751 default: 752 fatalx("lde_map2fec: unknown af"); 753 break; 754 } 755 break; 756 case MAP_TYPE_PWID: 757 fec->type = FEC_TYPE_PWID; 758 fec->u.pwid.type = map->fec.pwid.type; 759 fec->u.pwid.pwid = map->fec.pwid.pwid; 760 fec->u.pwid.lsr_id = lsr_id; 761 break; 762 } 763 } 764 765 void 766 lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single) 767 { 768 struct lde_req *lre; 769 struct lde_map *me; 770 struct map map; 771 struct l2vpn_pw *pw; 772 773 /* 774 * This function skips SL.1 - 3 and SL.9 - 14 because the label 775 * allocation is done way earlier (because of the merging nature of 776 * ldpd). 777 */ 778 779 lde_fec2map(&fn->fec, &map); 780 switch (fn->fec.type) { 781 case FEC_TYPE_IPV4: 782 if (!ln->v4_enabled) 783 return; 784 break; 785 case FEC_TYPE_IPV6: 786 if (!ln->v6_enabled) 787 return; 788 break; 789 case FEC_TYPE_PWID: 790 pw = (struct l2vpn_pw *) fn->data; 791 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr) 792 /* not the remote end of the pseudowire */ 793 return; 794 795 map.flags |= F_MAP_PW_IFMTU; 796 map.fec.pwid.ifmtu = pw->l2vpn->mtu; 797 if (pw->flags & F_PW_CWORD) 798 map.flags |= F_MAP_PW_CWORD; 799 if (pw->flags & F_PW_STATUSTLV) { 800 map.flags |= F_MAP_PW_STATUS; 801 /* VPLS are always up */ 802 map.pw_status = PW_FORWARDING; 803 } 804 break; 805 } 806 map.label = fn->local_label; 807 808 /* SL.6: is there a pending request for this mapping? */ 809 lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec); 810 if (lre) { 811 /* set label request msg id in the mapping response. */ 812 map.requestid = lre->msg_id; 813 map.flags = F_MAP_REQ_ID; 814 815 /* SL.7: delete record of pending request */ 816 lde_req_del(ln, lre, 0); 817 } 818 819 /* SL.4: send label mapping */ 820 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0, 821 &map, sizeof(map)); 822 if (single) 823 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0, 824 NULL, 0); 825 826 /* SL.5: record sent label mapping */ 827 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec); 828 if (me == NULL) 829 me = lde_map_add(ln, fn, 1); 830 me->map = map; 831 } 832 833 void 834 lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, 835 struct map *wcard, struct status_tlv *st) 836 { 837 struct lde_wdraw *lw; 838 struct map map; 839 struct fec *f; 840 struct l2vpn_pw *pw; 841 842 if (fn) { 843 lde_fec2map(&fn->fec, &map); 844 switch (fn->fec.type) { 845 case FEC_TYPE_IPV4: 846 if (!ln->v4_enabled) 847 return; 848 break; 849 case FEC_TYPE_IPV6: 850 if (!ln->v6_enabled) 851 return; 852 break; 853 case FEC_TYPE_PWID: 854 pw = (struct l2vpn_pw *) fn->data; 855 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr) 856 /* not the remote end of the pseudowire */ 857 return; 858 859 if (pw->flags & F_PW_CWORD) 860 map.flags |= F_MAP_PW_CWORD; 861 break; 862 } 863 map.label = fn->local_label; 864 } else 865 memcpy(&map, wcard, sizeof(map)); 866 867 if (st) { 868 map.st.status_code = st->status_code; 869 map.st.msg_id = st->msg_id; 870 map.st.msg_type = st->msg_type; 871 map.flags |= F_MAP_STATUS; 872 } 873 874 /* SWd.1: send label withdraw. */ 875 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0, 876 &map, sizeof(map)); 877 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0); 878 879 /* SWd.2: record label withdraw. */ 880 if (fn) { 881 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec); 882 if (lw == NULL) 883 lw = lde_wdraw_add(ln, fn); 884 lw->label = map.label; 885 } else { 886 struct lde_map *me; 887 888 RB_FOREACH(f, fec_tree, &ft) { 889 fn = (struct fec_node *)f; 890 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec); 891 if (lde_wildcard_apply(wcard, &fn->fec, me) == 0) 892 continue; 893 894 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, 895 &fn->fec); 896 if (lw == NULL) 897 lw = lde_wdraw_add(ln, fn); 898 lw->label = map.label; 899 } 900 } 901 } 902 903 void 904 lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label) 905 { 906 struct map wcard; 907 908 memset(&wcard, 0, sizeof(wcard)); 909 wcard.type = MAP_TYPE_WILDCARD; 910 wcard.label = label; 911 lde_send_labelwithdraw(ln, NULL, &wcard, NULL); 912 } 913 914 void 915 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af, 916 uint32_t label) 917 { 918 struct map wcard; 919 920 memset(&wcard, 0, sizeof(wcard)); 921 wcard.type = MAP_TYPE_TYPED_WCARD; 922 wcard.fec.twcard.type = MAP_TYPE_PREFIX; 923 wcard.fec.twcard.u.prefix_af = af; 924 wcard.label = label; 925 lde_send_labelwithdraw(ln, NULL, &wcard, NULL); 926 } 927 928 void 929 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr *ln, uint16_t pw_type, 930 uint32_t label) 931 { 932 struct map wcard; 933 934 memset(&wcard, 0, sizeof(wcard)); 935 wcard.type = MAP_TYPE_TYPED_WCARD; 936 wcard.fec.twcard.type = MAP_TYPE_PWID; 937 wcard.fec.twcard.u.pw_type = pw_type; 938 wcard.label = label; 939 lde_send_labelwithdraw(ln, NULL, &wcard, NULL); 940 } 941 942 void 943 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type, 944 uint32_t group_id) 945 { 946 struct map wcard; 947 948 memset(&wcard, 0, sizeof(wcard)); 949 wcard.type = MAP_TYPE_PWID; 950 wcard.fec.pwid.type = pw_type; 951 wcard.fec.pwid.group_id = group_id; 952 /* we can not append a Label TLV when using PWid group wildcards. */ 953 wcard.label = NO_LABEL; 954 lde_send_labelwithdraw(ln, NULL, &wcard, NULL); 955 } 956 957 void 958 lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn, 959 struct map *wcard, uint32_t label) 960 { 961 struct map map; 962 struct l2vpn_pw *pw; 963 964 if (fn) { 965 lde_fec2map(&fn->fec, &map); 966 switch (fn->fec.type) { 967 case FEC_TYPE_IPV4: 968 if (!ln->v4_enabled) 969 return; 970 break; 971 case FEC_TYPE_IPV6: 972 if (!ln->v6_enabled) 973 return; 974 break; 975 case FEC_TYPE_PWID: 976 pw = (struct l2vpn_pw *) fn->data; 977 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr) 978 /* not the remote end of the pseudowire */ 979 return; 980 981 if (pw->flags & F_PW_CWORD) 982 map.flags |= F_MAP_PW_CWORD; 983 break; 984 } 985 } else 986 memcpy(&map, wcard, sizeof(map)); 987 map.label = label; 988 989 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0, 990 &map, sizeof(map)); 991 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0); 992 } 993 994 void 995 lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id, 996 uint16_t msg_type) 997 { 998 struct notify_msg nm; 999 1000 memset(&nm, 0, sizeof(nm)); 1001 nm.status_code = status_code; 1002 /* 'msg_id' and 'msg_type' should be in network byte order */ 1003 nm.msg_id = msg_id; 1004 nm.msg_type = msg_type; 1005 1006 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0, 1007 &nm, sizeof(nm)); 1008 } 1009 1010 void 1011 lde_send_notification_eol_prefix(struct lde_nbr *ln, int af) 1012 { 1013 struct notify_msg nm; 1014 1015 memset(&nm, 0, sizeof(nm)); 1016 nm.status_code = S_ENDOFLIB; 1017 nm.fec.type = MAP_TYPE_TYPED_WCARD; 1018 nm.fec.fec.twcard.type = MAP_TYPE_PREFIX; 1019 nm.fec.fec.twcard.u.prefix_af = af; 1020 nm.flags |= F_NOTIF_FEC; 1021 1022 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0, 1023 &nm, sizeof(nm)); 1024 } 1025 1026 void 1027 lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type) 1028 { 1029 struct notify_msg nm; 1030 1031 memset(&nm, 0, sizeof(nm)); 1032 nm.status_code = S_ENDOFLIB; 1033 nm.fec.type = MAP_TYPE_TYPED_WCARD; 1034 nm.fec.fec.twcard.type = MAP_TYPE_PWID; 1035 nm.fec.fec.twcard.u.pw_type = pw_type; 1036 nm.flags |= F_NOTIF_FEC; 1037 1038 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0, 1039 &nm, sizeof(nm)); 1040 } 1041 1042 static __inline int 1043 lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b) 1044 { 1045 return (a->peerid - b->peerid); 1046 } 1047 1048 static struct lde_nbr * 1049 lde_nbr_new(uint32_t peerid, struct lde_nbr *new) 1050 { 1051 struct lde_nbr *ln; 1052 1053 if ((ln = calloc(1, sizeof(*ln))) == NULL) 1054 fatal(__func__); 1055 1056 ln->id = new->id; 1057 ln->v4_enabled = new->v4_enabled; 1058 ln->v6_enabled = new->v6_enabled; 1059 ln->flags = new->flags; 1060 ln->peerid = peerid; 1061 fec_init(&ln->recv_map); 1062 fec_init(&ln->sent_map); 1063 fec_init(&ln->recv_req); 1064 fec_init(&ln->sent_req); 1065 fec_init(&ln->sent_wdraw); 1066 1067 TAILQ_INIT(&ln->addr_list); 1068 1069 if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL) 1070 fatalx("lde_nbr_new: RB_INSERT failed"); 1071 1072 return (ln); 1073 } 1074 1075 static void 1076 lde_nbr_del(struct lde_nbr *ln) 1077 { 1078 struct fec *f; 1079 struct fec_node *fn; 1080 struct fec_nh *fnh; 1081 struct l2vpn_pw *pw; 1082 1083 if (ln == NULL) 1084 return; 1085 1086 /* uninstall received mappings */ 1087 RB_FOREACH(f, fec_tree, &ft) { 1088 fn = (struct fec_node *)f; 1089 1090 LIST_FOREACH(fnh, &fn->nexthops, entry) { 1091 switch (f->type) { 1092 case FEC_TYPE_IPV4: 1093 case FEC_TYPE_IPV6: 1094 if (!lde_address_find(ln, fnh->af, 1095 &fnh->nexthop)) 1096 continue; 1097 break; 1098 case FEC_TYPE_PWID: 1099 if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr) 1100 continue; 1101 pw = (struct l2vpn_pw *) fn->data; 1102 if (pw) 1103 l2vpn_pw_reset(pw); 1104 break; 1105 default: 1106 break; 1107 } 1108 1109 lde_send_delete_klabel(fn, fnh); 1110 fnh->remote_label = NO_LABEL; 1111 } 1112 } 1113 1114 lde_address_list_free(ln); 1115 1116 fec_clear(&ln->recv_map, lde_map_free); 1117 fec_clear(&ln->sent_map, lde_map_free); 1118 fec_clear(&ln->recv_req, free); 1119 fec_clear(&ln->sent_req, free); 1120 fec_clear(&ln->sent_wdraw, free); 1121 1122 RB_REMOVE(nbr_tree, &lde_nbrs, ln); 1123 1124 free(ln); 1125 } 1126 1127 static struct lde_nbr * 1128 lde_nbr_find(uint32_t peerid) 1129 { 1130 struct lde_nbr ln; 1131 1132 ln.peerid = peerid; 1133 1134 return (RB_FIND(nbr_tree, &lde_nbrs, &ln)); 1135 } 1136 1137 struct lde_nbr * 1138 lde_nbr_find_by_lsrid(struct in_addr addr) 1139 { 1140 struct lde_nbr *ln; 1141 1142 RB_FOREACH(ln, nbr_tree, &lde_nbrs) 1143 if (ln->id.s_addr == addr.s_addr) 1144 return (ln); 1145 1146 return (NULL); 1147 } 1148 1149 struct lde_nbr * 1150 lde_nbr_find_by_addr(int af, union ldpd_addr *addr) 1151 { 1152 struct lde_nbr *ln; 1153 1154 RB_FOREACH(ln, nbr_tree, &lde_nbrs) 1155 if (lde_address_find(ln, af, addr) != NULL) 1156 return (ln); 1157 1158 return (NULL); 1159 } 1160 1161 static void 1162 lde_nbr_clear(void) 1163 { 1164 struct lde_nbr *ln; 1165 1166 while ((ln = RB_ROOT(&lde_nbrs)) != NULL) 1167 lde_nbr_del(ln); 1168 } 1169 1170 static void 1171 lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed) 1172 { 1173 struct fec *fec; 1174 struct fec_node *fn; 1175 struct fec_nh *fnh; 1176 struct lde_map *me; 1177 1178 RB_FOREACH(fec, fec_tree, &ln->recv_map) { 1179 fn = (struct fec_node *)fec_find(&ft, fec); 1180 switch (fec->type) { 1181 case FEC_TYPE_IPV4: 1182 if (lde_addr->af != AF_INET) 1183 continue; 1184 break; 1185 case FEC_TYPE_IPV6: 1186 if (lde_addr->af != AF_INET6) 1187 continue; 1188 break; 1189 default: 1190 continue; 1191 } 1192 1193 LIST_FOREACH(fnh, &fn->nexthops, entry) { 1194 if (ldp_addrcmp(fnh->af, &fnh->nexthop, 1195 &lde_addr->addr)) 1196 continue; 1197 1198 if (removed) { 1199 lde_send_delete_klabel(fn, fnh); 1200 fnh->remote_label = NO_LABEL; 1201 } else { 1202 me = (struct lde_map *)fec; 1203 fnh->remote_label = me->map.label; 1204 lde_send_change_klabel(fn, fnh); 1205 } 1206 break; 1207 } 1208 } 1209 } 1210 1211 struct lde_map * 1212 lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent) 1213 { 1214 struct lde_map *me; 1215 1216 me = calloc(1, sizeof(*me)); 1217 if (me == NULL) 1218 fatal(__func__); 1219 1220 me->fec = fn->fec; 1221 me->nexthop = ln; 1222 1223 if (sent) { 1224 LIST_INSERT_HEAD(&fn->upstream, me, entry); 1225 if (fec_insert(&ln->sent_map, &me->fec)) 1226 log_warnx("failed to add %s to sent map", 1227 log_fec(&me->fec)); 1228 /* XXX on failure more cleanup is needed */ 1229 } else { 1230 LIST_INSERT_HEAD(&fn->downstream, me, entry); 1231 if (fec_insert(&ln->recv_map, &me->fec)) 1232 log_warnx("failed to add %s to recv map", 1233 log_fec(&me->fec)); 1234 } 1235 1236 return (me); 1237 } 1238 1239 void 1240 lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent) 1241 { 1242 if (sent) 1243 fec_remove(&ln->sent_map, &me->fec); 1244 else 1245 fec_remove(&ln->recv_map, &me->fec); 1246 1247 lde_map_free(me); 1248 } 1249 1250 static void 1251 lde_map_free(void *ptr) 1252 { 1253 struct lde_map *map = ptr; 1254 1255 LIST_REMOVE(map, entry); 1256 free(map); 1257 } 1258 1259 struct lde_req * 1260 lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent) 1261 { 1262 struct fec_tree *t; 1263 struct lde_req *lre; 1264 1265 t = sent ? &ln->sent_req : &ln->recv_req; 1266 1267 lre = calloc(1, sizeof(*lre)); 1268 if (lre != NULL) { 1269 lre->fec = *fec; 1270 1271 if (fec_insert(t, &lre->fec)) { 1272 log_warnx("failed to add %s to %s req", 1273 log_fec(&lre->fec), sent ? "sent" : "recv"); 1274 free(lre); 1275 return (NULL); 1276 } 1277 } 1278 1279 return (lre); 1280 } 1281 1282 void 1283 lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent) 1284 { 1285 if (sent) 1286 fec_remove(&ln->sent_req, &lre->fec); 1287 else 1288 fec_remove(&ln->recv_req, &lre->fec); 1289 1290 free(lre); 1291 } 1292 1293 struct lde_wdraw * 1294 lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn) 1295 { 1296 struct lde_wdraw *lw; 1297 1298 lw = calloc(1, sizeof(*lw)); 1299 if (lw == NULL) 1300 fatal(__func__); 1301 1302 lw->fec = fn->fec; 1303 1304 if (fec_insert(&ln->sent_wdraw, &lw->fec)) 1305 log_warnx("failed to add %s to sent wdraw", 1306 log_fec(&lw->fec)); 1307 1308 return (lw); 1309 } 1310 1311 void 1312 lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw) 1313 { 1314 fec_remove(&ln->sent_wdraw, &lw->fec); 1315 free(lw); 1316 } 1317 1318 void 1319 lde_change_egress_label(int af, int was_implicit) 1320 { 1321 struct lde_nbr *ln; 1322 struct fec *f; 1323 struct fec_node *fn; 1324 1325 RB_FOREACH(ln, nbr_tree, &lde_nbrs) { 1326 /* explicit withdraw */ 1327 if (was_implicit) 1328 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL); 1329 else { 1330 if (ln->v4_enabled) 1331 lde_send_labelwithdraw_wcard(ln, 1332 MPLS_LABEL_IPV4NULL); 1333 if (ln->v6_enabled) 1334 lde_send_labelwithdraw_wcard(ln, 1335 MPLS_LABEL_IPV6NULL); 1336 } 1337 1338 /* advertise new label of connected prefixes */ 1339 RB_FOREACH(f, fec_tree, &ft) { 1340 fn = (struct fec_node *)f; 1341 if (fn->local_label > MPLS_LABEL_RESERVED_MAX) 1342 continue; 1343 1344 switch (af) { 1345 case AF_INET: 1346 if (fn->fec.type != FEC_TYPE_IPV4) 1347 continue; 1348 break; 1349 case AF_INET6: 1350 if (fn->fec.type != FEC_TYPE_IPV6) 1351 continue; 1352 break; 1353 default: 1354 fatalx("lde_change_egress_label: unknown af"); 1355 } 1356 1357 fn->local_label = egress_label(fn->fec.type); 1358 lde_send_labelmapping(ln, fn, 0); 1359 } 1360 1361 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0, 1362 NULL, 0); 1363 } 1364 } 1365 1366 static int 1367 lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr) 1368 { 1369 struct lde_addr *new; 1370 1371 if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL) 1372 return (-1); 1373 1374 if ((new = calloc(1, sizeof(*new))) == NULL) 1375 fatal(__func__); 1376 1377 new->af = lde_addr->af; 1378 new->addr = lde_addr->addr; 1379 TAILQ_INSERT_TAIL(&ln->addr_list, new, entry); 1380 1381 /* reevaluate the previously received mappings from this neighbor */ 1382 lde_nbr_addr_update(ln, lde_addr, 0); 1383 1384 return (0); 1385 } 1386 1387 static int 1388 lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr) 1389 { 1390 lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr); 1391 if (lde_addr == NULL) 1392 return (-1); 1393 1394 /* reevaluate the previously received mappings from this neighbor */ 1395 lde_nbr_addr_update(ln, lde_addr, 1); 1396 1397 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry); 1398 free(lde_addr); 1399 1400 return (0); 1401 } 1402 1403 struct lde_addr * 1404 lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr) 1405 { 1406 struct lde_addr *lde_addr; 1407 1408 TAILQ_FOREACH(lde_addr, &ln->addr_list, entry) 1409 if (lde_addr->af == af && 1410 ldp_addrcmp(af, &lde_addr->addr, addr) == 0) 1411 return (lde_addr); 1412 1413 return (NULL); 1414 } 1415 1416 static void 1417 lde_address_list_free(struct lde_nbr *ln) 1418 { 1419 struct lde_addr *lde_addr; 1420 1421 while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) { 1422 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry); 1423 free(lde_addr); 1424 } 1425 } 1426