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