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>
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.
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.
29 #include "ldp_debug.h"
36 #include <lib/linklist.h>
42 static void lde_shutdown(void);
43 static int lde_dispatch_imsg(struct thread
*);
44 static int lde_dispatch_parent(struct thread
*);
45 static __inline
int lde_nbr_compare(const struct lde_nbr
*,
46 const struct lde_nbr
*);
47 static struct lde_nbr
*lde_nbr_new(uint32_t, struct lde_nbr
*);
48 static void lde_nbr_del(struct lde_nbr
*);
49 static struct lde_nbr
*lde_nbr_find(uint32_t);
50 static void lde_nbr_clear(void);
51 static void lde_nbr_addr_update(struct lde_nbr
*,
52 struct lde_addr
*, int);
53 static __inline
int lde_map_compare(const struct lde_map
*,
54 const struct lde_map
*);
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 static void zclient_sync_init(void);
60 static void lde_label_list_init(void);
61 static int lde_get_label_chunk(void);
62 static void on_get_label_chunk_response(uint32_t start
, uint32_t end
);
63 static uint32_t lde_get_next_label(void);
64 static bool lde_fec_connected(const struct fec_node
*);
65 static bool lde_fec_outside_mpls_network(const struct fec_node
*);
66 static void lde_check_filter_af(int, struct ldpd_af_conf
*,
69 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
70 RB_GENERATE(lde_map_head
, lde_map
, entry
, lde_map_compare
)
72 struct ldpd_conf
*ldeconf
;
73 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
75 static struct imsgev
*iev_ldpe
;
76 static struct imsgev
*iev_main
, *iev_main_sync
;
79 static zebra_capabilities_t _caps_p
[] =
84 static struct zebra_privs_t lde_privs
=
86 #if defined(VTY_GROUP)
87 .vty_group
= VTY_GROUP
,
90 .cap_num_p
= array_size(_caps_p
),
94 /* List of chunks of labels externally assigned by Zebra */
95 static struct list
*label_chunk_list
;
96 static struct listnode
*current_label_chunk
;
98 /* Synchronous zclient to request labels */
99 static struct zclient
*zclient_sync
;
101 /* SIGINT / SIGTERM handler. */
108 static struct quagga_signal_t lde_signals
[] =
124 /* label decision engine */
128 struct thread thread
;
130 #ifdef HAVE_SETPROCTITLE
131 setproctitle("label decision engine");
133 ldpd_process
= PROC_LDE_ENGINE
;
134 log_procname
= log_procnames
[PROC_LDE_ENGINE
];
136 master
= thread_master_create(NULL
);
138 /* setup signal handler */
139 signal_init(master
, array_size(lde_signals
), lde_signals
);
141 /* setup pipes and event handlers to the parent process */
142 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
144 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
145 iev_main
->handler_read
= lde_dispatch_parent
;
146 iev_main
->ev_read
= NULL
;
147 thread_add_read(master
, iev_main
->handler_read
, iev_main
, iev_main
->ibuf
.fd
,
149 iev_main
->handler_write
= ldp_write_handler
;
151 if ((iev_main_sync
= calloc(1, sizeof(struct imsgev
))) == NULL
)
153 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
155 /* create base configuration */
156 ldeconf
= config_new_empty();
158 /* Fetch next active thread. */
159 while (thread_fetch(master
, &thread
))
160 thread_call(&thread
);
164 lde_init(struct ldpd_init
*init
)
166 /* drop privileges */
167 lde_privs
.user
= init
->user
;
168 lde_privs
.group
= init
->group
;
169 zprivs_preinit(&lde_privs
);
170 zprivs_init(&lde_privs
);
172 /* start the LIB garbage collector */
173 lde_gc_start_timer();
175 /* Init synchronous zclient and label list */
176 frr_zclient_addr(&zclient_addr
, &zclient_addr_len
,
177 init
->zclient_serv_path
);
186 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
187 close(iev_ldpe
->ibuf
.fd
);
188 iev_ldpe
->ibuf
.fd
= -1;
190 msgbuf_clear(&iev_main
->ibuf
.w
);
191 close(iev_main
->ibuf
.fd
);
192 iev_main
->ibuf
.fd
= -1;
193 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
194 close(iev_main_sync
->ibuf
.fd
);
195 iev_main_sync
->ibuf
.fd
= -1;
201 config_clear(ldeconf
);
208 log_info("label decision engine exiting");
216 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
218 if (iev_main
->ibuf
.fd
== -1)
220 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
224 lde_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
226 if (iev_main_sync
->ibuf
.fd
== -1)
228 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
229 imsg_flush(&iev_main_sync
->ibuf
);
233 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
236 if (iev_ldpe
->ibuf
.fd
== -1)
238 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
244 lde_dispatch_imsg(struct thread
*thread
)
246 struct imsgev
*iev
= THREAD_ARG(thread
);
247 struct imsgbuf
*ibuf
= &iev
->ibuf
;
251 struct lde_addr
*lde_addr
;
252 struct notify_msg
*nm
;
258 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
259 fatal("imsg_read error");
260 if (n
== 0) /* connection closed */
264 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
265 fatal("lde_dispatch_imsg: imsg_get error");
269 switch (imsg
.hdr
.type
) {
270 case IMSG_LABEL_MAPPING_FULL
:
271 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
273 log_debug("%s: cannot find lde neighbor",
280 case IMSG_LABEL_MAPPING
:
281 case IMSG_LABEL_REQUEST
:
282 case IMSG_LABEL_RELEASE
:
283 case IMSG_LABEL_WITHDRAW
:
284 case IMSG_LABEL_ABORT
:
285 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
287 fatalx("lde_dispatch_imsg: wrong imsg len");
290 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
292 log_debug("%s: cannot find lde neighbor",
297 switch (imsg
.hdr
.type
) {
298 case IMSG_LABEL_MAPPING
:
299 lde_check_mapping(map
, ln
, 1);
301 case IMSG_LABEL_REQUEST
:
302 lde_check_request(map
, ln
);
304 case IMSG_LABEL_RELEASE
:
305 lde_check_release(map
, ln
);
307 case IMSG_LABEL_WITHDRAW
:
308 lde_check_withdraw(map
, ln
);
310 case IMSG_LABEL_ABORT
:
315 case IMSG_ADDRESS_ADD
:
316 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
317 sizeof(struct lde_addr
))
318 fatalx("lde_dispatch_imsg: wrong imsg len");
319 lde_addr
= imsg
.data
;
321 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
323 log_debug("%s: cannot find lde neighbor",
327 if (lde_address_add(ln
, lde_addr
) < 0) {
328 log_debug("%s: cannot add address %s, it already exists", __func__
,
329 log_addr(lde_addr
->af
, &lde_addr
->addr
));
332 case IMSG_ADDRESS_DEL
:
333 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
334 sizeof(struct lde_addr
))
335 fatalx("lde_dispatch_imsg: wrong imsg len");
336 lde_addr
= imsg
.data
;
338 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
340 log_debug("%s: cannot find lde neighbor",
344 if (lde_address_del(ln
, lde_addr
) < 0) {
345 log_debug("%s: cannot delete address %s, it does not exist", __func__
,
346 log_addr(lde_addr
->af
, &lde_addr
->addr
));
349 case IMSG_NOTIFICATION
:
350 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
351 sizeof(struct notify_msg
))
352 fatalx("lde_dispatch_imsg: wrong imsg len");
355 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
357 log_debug("%s: cannot find lde neighbor",
362 switch (nm
->status_code
) {
364 l2vpn_recv_pw_status(ln
, nm
);
368 * Do nothing for now. Should be useful in
369 * the future when we implement LDP-IGP
370 * Synchronization (RFC 5443) and Graceful
371 * Restart (RFC 3478).
377 case IMSG_NEIGHBOR_UP
:
378 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
379 sizeof(struct lde_nbr
))
380 fatalx("lde_dispatch_imsg: wrong imsg len");
382 if (lde_nbr_find(imsg
.hdr
.peerid
))
383 fatalx("lde_dispatch_imsg: neighbor already exists");
384 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
386 case IMSG_NEIGHBOR_DOWN
:
387 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
389 case IMSG_CTL_SHOW_LIB
:
390 rt_dump(imsg
.hdr
.pid
);
392 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
393 imsg
.hdr
.pid
, NULL
, 0);
395 case IMSG_CTL_SHOW_L2VPN_PW
:
396 l2vpn_pw_ctl(imsg
.hdr
.pid
);
398 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
399 imsg
.hdr
.pid
, NULL
, 0);
401 case IMSG_CTL_SHOW_L2VPN_BINDING
:
402 l2vpn_binding_ctl(imsg
.hdr
.pid
);
404 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
405 imsg
.hdr
.pid
, NULL
, 0);
408 log_debug("%s: unexpected imsg %d", __func__
,
417 /* this pipe is dead, so remove the event handlers and exit */
418 THREAD_READ_OFF(iev
->ev_read
);
419 THREAD_WRITE_OFF(iev
->ev_write
);
428 lde_dispatch_parent(struct thread
*thread
)
430 static struct ldpd_conf
*nconf
;
431 struct iface
*iface
, *niface
;
433 struct nbr_params
*nnbrp
;
434 static struct l2vpn
*l2vpn
, *nl2vpn
;
435 struct l2vpn_if
*lif
, *nlif
;
436 struct l2vpn_pw
*pw
, *npw
;
441 struct imsgev
*iev
= THREAD_ARG(thread
);
442 struct imsgbuf
*ibuf
= &iev
->ibuf
;
446 struct ldp_access
*laccess
;
450 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
451 fatal("imsg_read error");
452 if (n
== 0) /* connection closed */
456 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
457 fatal("lde_dispatch_parent: imsg_get error");
461 switch (imsg
.hdr
.type
) {
463 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
465 fatalx("IFSTATUS imsg with wrong len");
468 iface
= if_lookup_name(ldeconf
, kif
->ifname
);
470 if_update_info(iface
, kif
);
472 /* if up see if any labels need to be updated */
474 lde_route_update(iface
, AF_UNSPEC
);
478 RB_FOREACH(l2vpn
, l2vpn_head
, &ldeconf
->l2vpn_tree
) {
479 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
481 l2vpn_if_update_info(lif
, kif
);
484 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
486 l2vpn_pw_update_info(pw
, kif
);
492 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
493 sizeof(struct zapi_pw_status
))
494 fatalx("PW_UPDATE imsg with wrong len");
496 if (l2vpn_pw_status_update(imsg
.data
) != 0)
497 log_warnx("%s: error updating PW status",
500 case IMSG_NETWORK_ADD
:
501 case IMSG_NETWORK_UPDATE
:
502 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
503 sizeof(struct kroute
)) {
504 log_warnx("%s: wrong imsg len", __func__
);
511 fec
.type
= FEC_TYPE_IPV4
;
512 fec
.u
.ipv4
.prefix
= kr
->prefix
.v4
;
513 fec
.u
.ipv4
.prefixlen
= kr
->prefixlen
;
516 fec
.type
= FEC_TYPE_IPV6
;
517 fec
.u
.ipv6
.prefix
= kr
->prefix
.v6
;
518 fec
.u
.ipv6
.prefixlen
= kr
->prefixlen
;
521 fatalx("lde_dispatch_parent: unknown af");
524 switch (imsg
.hdr
.type
) {
525 case IMSG_NETWORK_ADD
:
526 lde_kernel_insert(&fec
, kr
->af
, &kr
->nexthop
,
527 kr
->ifindex
, kr
->route_type
,
529 kr
->flags
& F_CONNECTED
, NULL
);
531 case IMSG_NETWORK_UPDATE
:
532 lde_kernel_update(&fec
);
536 case IMSG_SOCKET_IPC
:
538 log_warnx("%s: received unexpected imsg fd to ldpe", __func__
);
541 if ((fd
= imsg
.fd
) == -1) {
542 log_warnx("%s: expected to receive imsg fd to ldpe but didn't receive any", __func__
);
546 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
548 imsg_init(&iev_ldpe
->ibuf
, fd
);
549 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
550 iev_ldpe
->ev_read
= NULL
;
551 thread_add_read(master
, iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
,
553 iev_ldpe
->handler_write
= ldp_write_handler
;
554 iev_ldpe
->ev_write
= NULL
;
557 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
558 sizeof(struct ldpd_init
))
559 fatalx("INIT imsg with wrong len");
561 memcpy(&init
, imsg
.data
, sizeof(init
));
564 case IMSG_RECONF_CONF
:
565 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
568 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
570 RB_INIT(iface_head
, &nconf
->iface_tree
);
571 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
572 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
573 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
575 case IMSG_RECONF_IFACE
:
576 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
578 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
580 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
582 case IMSG_RECONF_TNBR
:
583 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
585 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
587 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
589 case IMSG_RECONF_NBRP
:
590 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
592 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
594 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
596 case IMSG_RECONF_L2VPN
:
597 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
599 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
601 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
602 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
603 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
605 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
607 case IMSG_RECONF_L2VPN_IF
:
608 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
610 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
612 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
614 case IMSG_RECONF_L2VPN_PW
:
615 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
617 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
619 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
621 case IMSG_RECONF_L2VPN_IPW
:
622 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
624 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
626 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
628 case IMSG_RECONF_END
:
629 merge_config(ldeconf
, nconf
);
630 ldp_clear_config(nconf
);
633 case IMSG_DEBUG_UPDATE
:
634 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
636 log_warnx("%s: wrong imsg len", __func__
);
639 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
641 case IMSG_FILTER_UPDATE
:
642 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
643 sizeof(struct ldp_access
)) {
644 log_warnx("%s: wrong imsg len", __func__
);
648 lde_check_filter_af(AF_INET
, &ldeconf
->ipv4
,
650 lde_check_filter_af(AF_INET6
, &ldeconf
->ipv6
,
654 log_debug("%s: unexpected imsg %d", __func__
,
663 /* this pipe is dead, so remove the event handlers and exit */
664 THREAD_READ_OFF(iev
->ev_read
);
665 THREAD_WRITE_OFF(iev
->ev_write
);
673 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
675 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
678 static bool lde_fec_connected(const struct fec_node
*fn
)
682 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
683 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
689 static bool lde_fec_outside_mpls_network(const struct fec_node
*fn
)
693 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
694 if (!(fnh
->flags
& F_FEC_NH_NO_LDP
))
701 lde_update_label(struct fec_node
*fn
)
704 /* should we allocate a label for this fec? */
705 switch (fn
->fec
.type
) {
707 if ((ldeconf
->ipv4
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
708 fn
->fec
.u
.ipv4
.prefixlen
!= 32)
710 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
711 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
712 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
716 if ((ldeconf
->ipv6
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
717 fn
->fec
.u
.ipv6
.prefixlen
!= 128)
719 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
720 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
721 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
729 * If connected interface act as egress for fec.
730 * If LDP is not configured on an interface but there
731 * are other NHs with interfaces configured with LDP
732 * then don't act as an egress for the fec, otherwise
733 * act as an egress for the fec
735 if (lde_fec_connected(fn
) || lde_fec_outside_mpls_network(fn
)) {
736 /* choose implicit or explicit-null depending on configuration */
737 switch (fn
->fec
.type
) {
739 if (!(ldeconf
->ipv4
.flags
& F_LDPD_AF_EXPNULL
))
740 return (MPLS_LABEL_IMPLICIT_NULL
);
741 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
742 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
743 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
744 return (MPLS_LABEL_IMPLICIT_NULL
);
745 return MPLS_LABEL_IPV4_EXPLICIT_NULL
;
747 if (!(ldeconf
->ipv6
.flags
& F_LDPD_AF_EXPNULL
))
748 return (MPLS_LABEL_IMPLICIT_NULL
);
749 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
750 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
751 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
752 return (MPLS_LABEL_IMPLICIT_NULL
);
753 return MPLS_LABEL_IPV6_EXPLICIT_NULL
;
759 /* preserve current label if there's no need to update it */
760 if (fn
->local_label
!= NO_LABEL
&&
761 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
762 return (fn
->local_label
);
764 return (lde_get_next_label());
768 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
775 * Ordered Control: don't program label into HW until a
776 * labelmap msg has been received from upstream router
778 if (fnh
->flags
& F_FEC_NH_DEFER
)
781 switch (fn
->fec
.type
) {
783 memset(&kr
, 0, sizeof(kr
));
785 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
786 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
787 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
788 kr
.ifindex
= fnh
->ifindex
;
789 kr
.local_label
= fn
->local_label
;
790 kr
.remote_label
= fnh
->remote_label
;
791 kr
.route_type
= fnh
->route_type
;
792 kr
.route_instance
= fnh
->route_instance
;
793 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
797 memset(&kr
, 0, sizeof(kr
));
799 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
800 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
801 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
802 kr
.ifindex
= fnh
->ifindex
;
803 kr
.local_label
= fn
->local_label
;
804 kr
.remote_label
= fnh
->remote_label
;
805 kr
.route_type
= fnh
->route_type
;
806 kr
.route_instance
= fnh
->route_instance
;
808 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
812 pw
= (struct l2vpn_pw
*) fn
->data
;
813 if (!pw
|| fn
->local_label
== NO_LABEL
||
814 fnh
->remote_label
== NO_LABEL
)
819 zpw
.local_label
= fn
->local_label
;
820 zpw
.remote_label
= fnh
->remote_label
;
821 lde_imsg_compose_parent(IMSG_KPW_SET
, 0, &zpw
, sizeof(zpw
));
827 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
833 switch (fn
->fec
.type
) {
835 memset(&kr
, 0, sizeof(kr
));
837 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
838 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
839 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
840 kr
.ifindex
= fnh
->ifindex
;
841 kr
.local_label
= fn
->local_label
;
842 kr
.remote_label
= fnh
->remote_label
;
843 kr
.route_type
= fnh
->route_type
;
844 kr
.route_instance
= fnh
->route_instance
;
846 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
850 memset(&kr
, 0, sizeof(kr
));
852 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
853 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
854 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
855 kr
.ifindex
= fnh
->ifindex
;
856 kr
.local_label
= fn
->local_label
;
857 kr
.remote_label
= fnh
->remote_label
;
858 kr
.route_type
= fnh
->route_type
;
859 kr
.route_instance
= fnh
->route_instance
;
861 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
865 pw
= (struct l2vpn_pw
*) fn
->data
;
871 zpw
.local_label
= fn
->local_label
;
872 zpw
.remote_label
= fnh
->remote_label
;
873 lde_imsg_compose_parent(IMSG_KPW_UNSET
, 0, &zpw
, sizeof(zpw
));
879 lde_fec2map(struct fec
*fec
, struct map
*map
)
881 memset(map
, 0, sizeof(*map
));
885 map
->type
= MAP_TYPE_PREFIX
;
886 map
->fec
.prefix
.af
= AF_INET
;
887 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
888 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
891 map
->type
= MAP_TYPE_PREFIX
;
892 map
->fec
.prefix
.af
= AF_INET6
;
893 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
894 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
897 map
->type
= MAP_TYPE_PWID
;
898 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
899 map
->fec
.pwid
.group_id
= 0;
900 map
->flags
|= F_MAP_PW_ID
;
901 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
907 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
909 memset(fec
, 0, sizeof(*fec
));
912 case MAP_TYPE_PREFIX
:
913 switch (map
->fec
.prefix
.af
) {
915 fec
->type
= FEC_TYPE_IPV4
;
916 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
917 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
920 fec
->type
= FEC_TYPE_IPV6
;
921 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
922 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
925 fatalx("lde_map2fec: unknown af");
930 fec
->type
= FEC_TYPE_PWID
;
931 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
932 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
933 fec
->u
.pwid
.lsr_id
= lsr_id
;
939 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
941 struct lde_wdraw
*lw
;
950 * Ordered Control: do not send a labelmap msg until
951 * a labelmap message is received from downstream router
952 * and don't send labelmap back to downstream router
954 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
955 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
956 if (fnh
->flags
& F_FEC_NH_DEFER
)
959 if (lde_address_find(ln
, fnh
->af
, &fnh
->nexthop
))
969 * We shouldn't send a new label mapping if we have a pending
970 * label release to receive. In this case, schedule to send a
971 * label mapping as soon as a label release is received.
973 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
975 if (!fec_find(&ln
->sent_map_pending
, &fn
->fec
)) {
976 debug_evt("%s: FEC %s: scheduling to send label mapping later (waiting for pending label release)",
977 __func__
, log_fec(&fn
->fec
));
978 lde_map_pending_add(ln
, fn
);
984 * This function skips SL.1 - 3 and SL.9 - 14 because the label
985 * allocation is done way earlier (because of the merging nature of
989 lde_fec2map(&fn
->fec
, &map
);
990 switch (fn
->fec
.type
) {
994 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
995 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
997 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
998 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
999 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
1003 if (!ln
->v6_enabled
)
1005 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
1006 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1008 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
1009 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
1010 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
1014 pw
= (struct l2vpn_pw
*) fn
->data
;
1015 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1016 /* not the remote end of the pseudowire */
1019 map
.flags
|= F_MAP_PW_IFMTU
;
1020 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
1021 if (pw
->flags
& F_PW_CWORD
)
1022 map
.flags
|= F_MAP_PW_CWORD
;
1023 if (pw
->flags
& F_PW_STATUSTLV
) {
1024 map
.flags
|= F_MAP_PW_STATUS
;
1025 map
.pw_status
= pw
->local_status
;
1029 map
.label
= fn
->local_label
;
1031 /* SL.6: is there a pending request for this mapping? */
1032 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
1034 /* set label request msg id in the mapping response. */
1035 map
.requestid
= lre
->msg_id
;
1036 map
.flags
= F_MAP_REQ_ID
;
1038 /* SL.7: delete record of pending request */
1039 lde_req_del(ln
, lre
, 0);
1042 /* SL.4: send label mapping */
1043 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
1046 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1049 /* SL.5: record sent label mapping */
1050 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1052 me
= lde_map_add(ln
, fn
, 1);
1057 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
,
1058 struct map
*wcard
, struct status_tlv
*st
)
1060 struct lde_wdraw
*lw
;
1063 struct l2vpn_pw
*pw
;
1066 lde_fec2map(&fn
->fec
, &map
);
1067 switch (fn
->fec
.type
) {
1069 if (!ln
->v4_enabled
)
1073 if (!ln
->v6_enabled
)
1077 pw
= (struct l2vpn_pw
*) fn
->data
;
1078 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1079 /* not the remote end of the pseudowire */
1082 if (pw
->flags
& F_PW_CWORD
)
1083 map
.flags
|= F_MAP_PW_CWORD
;
1086 map
.label
= fn
->local_label
;
1088 memcpy(&map
, wcard
, sizeof(map
));
1091 map
.st
.status_code
= st
->status_code
;
1092 map
.st
.msg_id
= st
->msg_id
;
1093 map
.st
.msg_type
= st
->msg_type
;
1094 map
.flags
|= F_MAP_STATUS
;
1097 /* SWd.1: send label withdraw. */
1098 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
1100 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1102 /* SWd.2: record label withdraw. */
1104 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1106 lw
= lde_wdraw_add(ln
, fn
);
1107 lw
->label
= map
.label
;
1111 RB_FOREACH(f
, fec_tree
, &ft
) {
1112 fn
= (struct fec_node
*)f
;
1113 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1114 if (lde_wildcard_apply(wcard
, &fn
->fec
, me
) == 0)
1117 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
1120 lw
= lde_wdraw_add(ln
, fn
);
1121 lw
->label
= map
.label
;
1127 lde_send_labelwithdraw_wcard(struct lde_nbr
*ln
, uint32_t label
)
1131 memset(&wcard
, 0, sizeof(wcard
));
1132 wcard
.type
= MAP_TYPE_WILDCARD
;
1133 wcard
.label
= label
;
1134 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1138 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr
*ln
, uint16_t af
,
1143 memset(&wcard
, 0, sizeof(wcard
));
1144 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1145 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1146 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1147 wcard
.label
= label
;
1148 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1152 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr
*ln
, uint16_t pw_type
,
1157 memset(&wcard
, 0, sizeof(wcard
));
1158 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1159 wcard
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1160 wcard
.fec
.twcard
.u
.pw_type
= pw_type
;
1161 wcard
.label
= label
;
1162 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1166 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr
*ln
, uint16_t pw_type
,
1171 memset(&wcard
, 0, sizeof(wcard
));
1172 wcard
.type
= MAP_TYPE_PWID
;
1173 wcard
.fec
.pwid
.type
= pw_type
;
1174 wcard
.fec
.pwid
.group_id
= group_id
;
1175 /* we can not append a Label TLV when using PWid group wildcards. */
1176 wcard
.label
= NO_LABEL
;
1177 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1181 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
,
1182 struct map
*wcard
, uint32_t label
)
1185 struct l2vpn_pw
*pw
;
1188 lde_fec2map(&fn
->fec
, &map
);
1189 switch (fn
->fec
.type
) {
1191 if (!ln
->v4_enabled
)
1195 if (!ln
->v6_enabled
)
1199 pw
= (struct l2vpn_pw
*) fn
->data
;
1200 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1201 /* not the remote end of the pseudowire */
1204 if (pw
->flags
& F_PW_CWORD
)
1205 map
.flags
|= F_MAP_PW_CWORD
;
1209 memcpy(&map
, wcard
, sizeof(map
));
1212 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1214 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1218 lde_send_labelrequest(struct lde_nbr
*ln
, struct fec_node
*fn
,
1219 struct map
*wcard
, int single
)
1223 struct lde_req
*lre
;
1226 lde_fec2map(&fn
->fec
, &map
);
1227 switch (fn
->fec
.type
) {
1229 if (!ln
->v4_enabled
)
1233 if (!ln
->v6_enabled
)
1237 fatalx("lde_send_labelrequest: unknown af");
1240 memcpy(&map
, wcard
, sizeof(map
));
1242 map
.label
= NO_LABEL
;
1245 /* SLR1.1: has label request for FEC been previously sent
1246 * and still outstanding just return,
1248 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1250 /* SLRq.3: send label request */
1251 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
, ln
->peerid
, 0,
1254 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1255 ln
->peerid
, 0, NULL
, 0);
1257 /* SLRq.4: record sent request */
1258 lde_req_add(ln
, &fn
->fec
, 1);
1261 /* if Wilcard just send label request */
1262 /* SLRq.3: send label request */
1263 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
,
1264 ln
->peerid
, 0, &map
, sizeof(map
));
1266 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1267 ln
->peerid
, 0, NULL
, 0);
1269 /* SLRq.4: record sent request */
1270 RB_FOREACH(f
, fec_tree
, &ft
) {
1271 fn
= (struct fec_node
*)f
;
1272 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1273 if (lde_wildcard_apply(wcard
, &fn
->fec
, NULL
) == 0)
1276 lde_req_add(ln
, f
, 1);
1282 lde_send_labelrequest_wcard(struct lde_nbr
*ln
, uint16_t af
)
1286 memset(&wcard
, 0, sizeof(wcard
));
1287 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1288 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1289 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1290 lde_send_labelrequest(ln
, NULL
, &wcard
, 1);
1294 lde_send_notification(struct lde_nbr
*ln
, uint32_t status_code
, uint32_t msg_id
,
1297 struct notify_msg nm
;
1299 memset(&nm
, 0, sizeof(nm
));
1300 nm
.status_code
= status_code
;
1301 /* 'msg_id' and 'msg_type' should be in network byte order */
1303 nm
.msg_type
= msg_type
;
1305 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1310 lde_send_notification_eol_prefix(struct lde_nbr
*ln
, int af
)
1312 struct notify_msg nm
;
1314 memset(&nm
, 0, sizeof(nm
));
1315 nm
.status_code
= S_ENDOFLIB
;
1316 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1317 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1318 nm
.fec
.fec
.twcard
.u
.prefix_af
= af
;
1319 nm
.flags
|= F_NOTIF_FEC
;
1321 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1326 lde_send_notification_eol_pwid(struct lde_nbr
*ln
, uint16_t pw_type
)
1328 struct notify_msg nm
;
1330 memset(&nm
, 0, sizeof(nm
));
1331 nm
.status_code
= S_ENDOFLIB
;
1332 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1333 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1334 nm
.fec
.fec
.twcard
.u
.pw_type
= pw_type
;
1335 nm
.flags
|= F_NOTIF_FEC
;
1337 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1342 lde_nbr_compare(const struct lde_nbr
*a
, const struct lde_nbr
*b
)
1344 return (a
->peerid
- b
->peerid
);
1347 static struct lde_nbr
*
1348 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1352 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1356 ln
->v4_enabled
= new->v4_enabled
;
1357 ln
->v6_enabled
= new->v6_enabled
;
1358 ln
->flags
= new->flags
;
1359 ln
->peerid
= peerid
;
1360 fec_init(&ln
->recv_map
);
1361 fec_init(&ln
->sent_map
);
1362 fec_init(&ln
->sent_map_pending
);
1363 fec_init(&ln
->recv_req
);
1364 fec_init(&ln
->sent_req
);
1365 fec_init(&ln
->sent_wdraw
);
1367 TAILQ_INIT(&ln
->addr_list
);
1369 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1370 fatalx("lde_nbr_new: RB_INSERT failed");
1376 lde_nbr_del(struct lde_nbr
*ln
)
1379 struct fec_node
*fn
;
1381 struct l2vpn_pw
*pw
;
1382 struct lde_nbr
*lnbr
;
1387 /* uninstall received mappings */
1388 RB_FOREACH(f
, fec_tree
, &ft
) {
1389 fn
= (struct fec_node
*)f
;
1391 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1395 if (!lde_address_find(ln
, fnh
->af
,
1400 * Ordered Control: must mark any non-connected
1401 * NH to wait until we receive a labelmap msg
1402 * before installing in kernel and sending to
1403 * peer, must do this as NHs are not removed
1404 * when lsps go down. Also send label withdraw
1405 * to other neighbors for all fecs from neighbor
1408 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
1409 fnh
->flags
|= F_FEC_NH_DEFER
;
1411 RB_FOREACH(lnbr
, nbr_tree
, &lde_nbrs
) {
1412 if (ln
->peerid
== lnbr
->peerid
)
1414 lde_send_labelwithdraw(lnbr
, fn
, NULL
, NULL
);
1419 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1421 pw
= (struct l2vpn_pw
*) fn
->data
;
1423 pw
->reason
= F_PW_NO_REMOTE_LABEL
;
1431 lde_send_delete_klabel(fn
, fnh
);
1432 fnh
->remote_label
= NO_LABEL
;
1436 lde_address_list_free(ln
);
1438 fec_clear(&ln
->recv_map
, lde_map_free
);
1439 fec_clear(&ln
->sent_map
, lde_map_free
);
1440 fec_clear(&ln
->sent_map_pending
, free
);
1441 fec_clear(&ln
->recv_req
, free
);
1442 fec_clear(&ln
->sent_req
, free
);
1443 fec_clear(&ln
->sent_wdraw
, free
);
1445 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1450 static struct lde_nbr
*
1451 lde_nbr_find(uint32_t peerid
)
1457 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1461 lde_nbr_find_by_lsrid(struct in_addr addr
)
1465 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1466 if (ln
->id
.s_addr
== addr
.s_addr
)
1473 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1477 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1478 if (lde_address_find(ln
, af
, addr
) != NULL
)
1489 while (!RB_EMPTY(nbr_tree
, &lde_nbrs
)) {
1490 ln
= RB_ROOT(nbr_tree
, &lde_nbrs
);
1497 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1500 struct fec_node
*fn
;
1504 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1505 switch (fec
->type
) {
1507 if (lde_addr
->af
!= AF_INET
)
1511 if (lde_addr
->af
!= AF_INET6
)
1518 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1520 /* shouldn't happen */
1523 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1524 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1529 lde_send_delete_klabel(fn
, fnh
);
1530 fnh
->remote_label
= NO_LABEL
;
1532 me
= (struct lde_map
*)fec
;
1533 fnh
->remote_label
= me
->map
.label
;
1534 lde_send_change_klabel(fn
, fnh
);
1542 lde_map_compare(const struct lde_map
*a
, const struct lde_map
*b
)
1544 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1545 (union ldpd_addr
*)&b
->nexthop
->id
));
1549 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1553 me
= calloc(1, sizeof(*me
));
1561 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1562 me
->head
= &fn
->upstream
;
1563 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1564 log_warnx("failed to add %s to sent map",
1566 /* XXX on failure more cleanup is needed */
1568 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1569 me
->head
= &fn
->downstream
;
1570 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1571 log_warnx("failed to add %s to recv map",
1579 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1582 fec_remove(&ln
->sent_map
, &me
->fec
);
1584 fec_remove(&ln
->recv_map
, &me
->fec
);
1590 lde_map_free(void *ptr
)
1592 struct lde_map
*map
= ptr
;
1594 RB_REMOVE(lde_map_head
, map
->head
, map
);
1599 lde_map_pending_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1603 map
= calloc(1, sizeof(*map
));
1608 if (fec_insert(&ln
->sent_map_pending
, map
))
1609 log_warnx("failed to add %s to sent map (pending)",
1616 lde_map_pending_del(struct lde_nbr
*ln
, struct fec
*map
)
1618 fec_remove(&ln
->sent_map_pending
, map
);
1623 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1626 struct lde_req
*lre
;
1628 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1630 lre
= calloc(1, sizeof(*lre
));
1634 if (fec_insert(t
, &lre
->fec
)) {
1635 log_warnx("failed to add %s to %s req",
1636 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1646 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1649 fec_remove(&ln
->sent_req
, &lre
->fec
);
1651 fec_remove(&ln
->recv_req
, &lre
->fec
);
1657 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1659 struct lde_wdraw
*lw
;
1661 lw
= calloc(1, sizeof(*lw
));
1667 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1668 log_warnx("failed to add %s to sent wdraw",
1675 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1677 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1682 lde_change_egress_label(int af
)
1686 struct fec_node
*fn
;
1688 /* explicitly withdraw all null labels */
1689 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1690 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IMPLICIT_NULL
);
1692 lde_send_labelwithdraw_wcard(
1694 MPLS_LABEL_IPV4_EXPLICIT_NULL
);
1696 lde_send_labelwithdraw_wcard(
1698 MPLS_LABEL_IPV6_EXPLICIT_NULL
);
1701 /* update label of connected routes */
1702 RB_FOREACH(f
, fec_tree
, &ft
) {
1703 fn
= (struct fec_node
*)f
;
1704 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1709 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1713 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1717 fatalx("lde_change_egress_label: unknown af");
1720 fn
->local_label
= lde_update_label(fn
);
1721 if (fn
->local_label
!= NO_LABEL
)
1722 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1723 lde_send_labelmapping(ln
, fn
, 0);
1725 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1726 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1731 lde_change_allocate_filter(int af
)
1735 struct fec_node
*fn
;
1738 /* reallocate labels for fecs that match this filter */
1739 RB_FOREACH(f
, fec_tree
, &ft
) {
1740 fn
= (struct fec_node
*)f
;
1744 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1748 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1752 fatalx("lde_change_allocate_filter: unknown af");
1756 * If the local label has changed to NO_LABEL, send a label
1757 * withdraw to all peers.
1758 * If the local label has changed and it's different from
1759 * NO_LABEL, send a label mapping to all peers advertising
1761 * If the local label hasn't changed, do nothing
1763 new_label
= lde_update_label(fn
);
1764 if (fn
->local_label
!= new_label
) {
1765 if (new_label
== NO_LABEL
)
1766 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1767 lde_send_labelwithdraw(ln
, fn
,
1770 fn
->local_label
= new_label
;
1771 if (fn
->local_label
!= NO_LABEL
)
1772 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1773 lde_send_labelmapping(ln
, fn
, 0);
1776 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1777 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1782 lde_change_advertise_filter(int af
)
1786 struct fec_node
*fn
;
1787 char *acl_to_filter
;
1788 char *acl_for_filter
;
1789 union ldpd_addr
*prefix
;
1793 /* advertise label for fecs to neighbors if matches advertise filters */
1796 acl_to_filter
= ldeconf
->ipv4
.acl_label_advertise_to
;
1797 acl_for_filter
= ldeconf
->ipv4
.acl_label_advertise_for
;
1800 acl_to_filter
= ldeconf
->ipv6
.acl_label_advertise_to
;
1801 acl_for_filter
= ldeconf
->ipv6
.acl_label_advertise_for
;
1804 fatalx("lde_change_advertise_filter: unknown af");
1807 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1808 if (lde_acl_check(acl_to_filter
, af
, (union ldpd_addr
*)&ln
->id
,
1809 IPV4_MAX_BITLEN
) != FILTER_PERMIT
)
1810 lde_send_labelwithdraw_wcard(ln
, NO_LABEL
);
1812 /* This neighbor is allowed in to_filter, so
1813 * send labels if fec also matches for_filter
1815 RB_FOREACH(f
, fec_tree
, &ft
) {
1816 fn
= (struct fec_node
*)f
;
1819 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1821 prefix
= (union ldpd_addr
*)
1822 &fn
->fec
.u
.ipv4
.prefix
;
1823 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1826 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1828 prefix
= (union ldpd_addr
*)
1829 &fn
->fec
.u
.ipv6
.prefix
;
1830 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1835 if (lde_acl_check(acl_for_filter
, af
,
1836 prefix
, plen
) != FILTER_PERMIT
) {
1837 me
= (struct lde_map
*)fec_find(
1838 &ln
->sent_map
, &fn
->fec
);
1840 /* fec filtered withdraw */
1841 lde_send_labelwithdraw(ln
, fn
,
1844 /* fec allowed send map */
1845 lde_send_labelmapping(ln
, fn
, 0);
1847 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
,
1848 ln
->peerid
, 0, NULL
, 0);
1855 lde_change_accept_filter(int af
)
1859 struct fec_node
*fn
;
1860 char *acl_for_filter
;
1861 char *acl_from_filter
;
1862 union ldpd_addr
*prefix
;
1867 /* accept labels from neighbors specified in the from_filter and for
1868 * fecs defined in the for_filter
1872 acl_for_filter
= ldeconf
->ipv4
.acl_label_accept_for
;
1873 acl_from_filter
= ldeconf
->ipv4
.acl_label_accept_from
;
1874 type
= FEC_TYPE_IPV4
;
1877 acl_for_filter
= ldeconf
->ipv6
.acl_label_accept_for
;
1878 acl_from_filter
= ldeconf
->ipv6
.acl_label_accept_from
;
1879 type
= FEC_TYPE_IPV6
;
1882 fatalx("lde_change_accept_filter: unknown af");
1885 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1886 if (lde_acl_check(acl_from_filter
, AF_INET
, (union ldpd_addr
*)
1887 &ln
->id
, IPV4_MAX_BITLEN
) != FILTER_PERMIT
) {
1888 /* This neighbor is now filtered so remove fecs from
1891 RB_FOREACH(f
, fec_tree
, &ft
) {
1892 fn
= (struct fec_node
*)f
;
1893 if (fn
->fec
.type
== type
) {
1894 me
= (struct lde_map
*)fec_find(
1895 &ln
->recv_map
, &fn
->fec
);
1897 lde_map_del(ln
, me
, 0);
1900 } else if (ln
->flags
& F_NBR_CAP_TWCARD
) {
1901 /* This neighbor is allowed and supports type
1902 * wildcard so send a labelrequest
1903 * to get any new labels from neighbor
1904 * and make sure any fecs we currently have
1907 RB_FOREACH(f
, fec_tree
, &ft
) {
1908 fn
= (struct fec_node
*)f
;
1911 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1913 prefix
= (union ldpd_addr
*)
1914 &fn
->fec
.u
.ipv4
.prefix
;
1915 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1918 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1920 prefix
= (union ldpd_addr
*)
1921 &fn
->fec
.u
.ipv6
.prefix
;
1922 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1927 if (lde_acl_check(acl_for_filter
, af
,
1928 prefix
, plen
) != FILTER_PERMIT
) {
1929 me
= (struct lde_map
*)fec_find(
1930 &ln
->recv_map
, &fn
->fec
);
1932 lde_map_del(ln
, me
, 0);
1935 lde_send_labelrequest_wcard(ln
, af
);
1937 /* Type Wildcard is not supported so restart session */
1938 lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN
, ln
->peerid
, 0,
1944 lde_change_expnull_for_filter(int af
)
1948 struct fec_node
*fn
;
1951 union ldpd_addr
*prefix
;
1954 /* Configure explicit-null advertisement for all fecs in this filter */
1955 RB_FOREACH(f
, fec_tree
, &ft
) {
1956 fn
= (struct fec_node
*)f
;
1960 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1962 acl_name
= ldeconf
->ipv4
.acl_label_expnull_for
;
1963 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
1964 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1965 exp_label
= MPLS_LABEL_IPV4_EXPLICIT_NULL
;
1968 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1970 acl_name
= ldeconf
->ipv6
.acl_label_expnull_for
;
1971 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
1972 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1973 exp_label
= MPLS_LABEL_IPV6_EXPLICIT_NULL
;
1976 fatalx("lde_change_expnull_for_filter: unknown af");
1979 if (lde_acl_check(acl_name
, af
, prefix
, plen
) == FILTER_PERMIT
) {
1980 /* for this fec change any imp-null to exp-null */
1981 if (fn
->local_label
== MPLS_LABEL_IMPLICIT_NULL
) {
1982 fn
->local_label
= lde_update_label(fn
);
1983 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1984 lde_send_labelmapping(ln
, fn
, 0);
1987 /* for this fec change any exp-null back to imp-null */
1988 if (fn
->local_label
== exp_label
) {
1989 fn
->local_label
= lde_update_label(fn
);
1990 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1991 lde_send_labelmapping(ln
, fn
, 0);
1995 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1996 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
2001 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2003 struct lde_addr
*new;
2005 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
2008 if ((new = calloc(1, sizeof(*new))) == NULL
)
2011 new->af
= lde_addr
->af
;
2012 new->addr
= lde_addr
->addr
;
2013 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
2015 /* reevaluate the previously received mappings from this neighbor */
2016 lde_nbr_addr_update(ln
, lde_addr
, 0);
2022 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2024 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
2025 if (lde_addr
== NULL
)
2028 /* reevaluate the previously received mappings from this neighbor */
2029 lde_nbr_addr_update(ln
, lde_addr
, 1);
2031 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
2038 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
2040 struct lde_addr
*lde_addr
;
2042 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
2043 if (lde_addr
->af
== af
&&
2044 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
2051 lde_address_list_free(struct lde_nbr
*ln
)
2053 struct lde_addr
*lde_addr
;
2055 while ((lde_addr
= TAILQ_POP_FIRST(&ln
->addr_list
, entry
)) != NULL
)
2060 * Event callback used to retry the label-manager sync zapi session.
2062 static int zclient_sync_retry(struct thread
*thread
)
2064 zclient_sync_init();
2070 * Initialize and open a synchronous zapi session. This is used by label chunk
2071 * management code, which acquires and releases blocks of labels from the
2072 * zebra label-manager module.
2074 static void zclient_sync_init(void)
2076 struct zclient_options options
= zclient_options_default
;
2078 options
.synchronous
= true;
2080 /* Initialize special zclient for synchronous message exchanges. */
2081 zclient_sync
= zclient_new(master
, &options
);
2082 zclient_sync
->sock
= -1;
2083 zclient_sync
->redist_default
= ZEBRA_ROUTE_LDP
;
2084 zclient_sync
->session_id
= 1; /* Distinguish from main session */
2085 zclient_sync
->privs
= &lde_privs
;
2087 if (zclient_socket_connect(zclient_sync
) < 0) {
2088 log_warnx("Error connecting synchronous zclient!");
2091 /* make socket non-blocking */
2092 sock_set_nonblock(zclient_sync
->sock
);
2094 /* Send hello to notify zebra this is a synchronous client */
2095 if (zclient_send_hello(zclient_sync
) < 0) {
2096 log_warnx("Error sending hello for synchronous zclient!");
2100 /* Connect to label manager */
2101 if (lm_label_manager_connect(zclient_sync
, 0) != 0) {
2102 log_warnx("Error connecting to label manager!");
2106 /* Finish label-manager init once the LM session is running */
2107 lde_label_list_init();
2113 /* Discard failed zclient object */
2114 zclient_stop(zclient_sync
);
2115 zclient_free(zclient_sync
);
2116 zclient_sync
= NULL
;
2118 /* Retry using a timer */
2119 thread_add_timer(master
, zclient_sync_retry
, NULL
, 1, NULL
);
2123 lde_del_label_chunk(void *val
)
2129 lde_release_label_chunk(uint32_t start
, uint32_t end
)
2133 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
2135 log_warnx("Error releasing label chunk!");
2142 lde_get_label_chunk(void)
2145 uint32_t start
, end
;
2147 debug_labels("getting label chunk (size %u)", CHUNK_SIZE
);
2148 ret
= lm_get_label_chunk(zclient_sync
, 0, MPLS_LABEL_BASE_ANY
,
2149 CHUNK_SIZE
, &start
, &end
);
2151 log_warnx("Error getting label chunk!");
2155 on_get_label_chunk_response(start
, end
);
2161 lde_label_list_init(void)
2163 label_chunk_list
= list_new();
2164 label_chunk_list
->del
= lde_del_label_chunk
;
2166 /* get first chunk */
2167 while (lde_get_label_chunk () != 0) {
2168 log_warnx("Error getting first label chunk!");
2174 on_get_label_chunk_response(uint32_t start
, uint32_t end
)
2176 struct label_chunk
*new_label_chunk
;
2178 debug_labels("label chunk assign: %u - %u", start
, end
);
2180 new_label_chunk
= calloc(1, sizeof(struct label_chunk
));
2181 if (!new_label_chunk
) {
2182 log_warn("Error trying to allocate label chunk %u - %u", start
, end
);
2186 new_label_chunk
->start
= start
;
2187 new_label_chunk
->end
= end
;
2188 new_label_chunk
->used_mask
= 0;
2190 listnode_add(label_chunk_list
, (void *)new_label_chunk
);
2192 /* let's update current if needed */
2193 if (!current_label_chunk
)
2194 current_label_chunk
= listtail(label_chunk_list
);
2198 lde_free_label(uint32_t label
)
2200 struct listnode
*node
;
2201 struct label_chunk
*label_chunk
;
2204 for (ALL_LIST_ELEMENTS_RO(label_chunk_list
, node
, label_chunk
)) {
2205 if (label
<= label_chunk
->end
&& label
>= label_chunk
->start
) {
2206 pos
= 1ULL << (label
- label_chunk
->start
);
2207 label_chunk
->used_mask
&= ~pos
;
2208 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
2209 if (!label_chunk
->used_mask
&& (current_label_chunk
!= node
)) {
2210 if (lde_release_label_chunk(label_chunk
->start
, label_chunk
->end
) != 0)
2211 log_warnx("%s: Error releasing label chunk!", __func__
);
2213 listnode_delete(label_chunk_list
, label_chunk
);
2214 lde_del_label_chunk(label_chunk
);
2224 lde_get_next_label(void)
2226 struct label_chunk
*label_chunk
;
2229 uint32_t label
= NO_LABEL
;
2231 while (current_label_chunk
) {
2232 label_chunk
= listgetdata(current_label_chunk
);
2236 /* try to get next free label in currently used label chunk */
2237 size
= label_chunk
->end
- label_chunk
->start
+ 1;
2238 for (i
= 0, pos
= 1; i
< size
; i
++, pos
<<= 1) {
2239 if (!(pos
& label_chunk
->used_mask
)) {
2240 label_chunk
->used_mask
|= pos
;
2241 label
= label_chunk
->start
+ i
;
2245 current_label_chunk
= listnextnode(current_label_chunk
);
2249 /* we moved till the last chunk, or were not able to find a label,
2250 so let's ask for another one */
2251 if (!current_label_chunk
||
2252 current_label_chunk
== listtail(label_chunk_list
) ||
2253 label
== NO_LABEL
) {
2254 if (lde_get_label_chunk() != 0)
2255 log_warn("%s: Error getting label chunk!", __func__
);
2263 lde_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
2264 const char *filter_name
)
2266 if (strcmp(af_conf
->acl_label_allocate_for
, filter_name
) == 0)
2267 lde_change_allocate_filter(af
);
2268 if ((strcmp(af_conf
->acl_label_advertise_to
, filter_name
) == 0)
2269 || (strcmp(af_conf
->acl_label_advertise_for
, filter_name
) == 0))
2270 lde_change_advertise_filter(af
);
2271 if ((strcmp(af_conf
->acl_label_accept_for
, filter_name
) == 0)
2272 || (strcmp(af_conf
->acl_label_accept_from
, filter_name
) == 0))
2273 lde_change_accept_filter(af
);
2274 if (strcmp(af_conf
->acl_label_expnull_for
, filter_name
) == 0)
2275 lde_change_expnull_for_filter(af
);
2278 void lde_route_update(struct iface
*iface
, int af
)
2281 struct fec_node
*fn
;
2285 /* update label of non-connected routes */
2286 log_debug("update labels for interface %s", iface
->name
);
2287 RB_FOREACH(f
, fec_tree
, &ft
) {
2288 fn
= (struct fec_node
*)f
;
2289 if (IS_MPLS_UNRESERVED_LABEL(fn
->local_label
))
2294 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2298 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2302 /* unspecified so process both address families */
2306 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2308 * If connected leave existing label. If LDP
2309 * configured on interface or a static route
2310 * may need new label. If no LDP configured
2311 * treat fec as a connected route
2313 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2316 if (fnh
->ifindex
!= iface
->ifindex
)
2319 fnh
->flags
&= ~F_FEC_NH_NO_LDP
;
2320 if (IS_MPLS_RESERVED_LABEL(fn
->local_label
)) {
2321 fn
->local_label
= NO_LABEL
;
2322 fn
->local_label
= lde_update_label(fn
);
2323 if (fn
->local_label
!= NO_LABEL
)
2324 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2325 lde_send_labelmapping(
2331 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2332 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2336 void lde_route_update_release(struct iface
*iface
, int af
)
2340 struct fec_node
*fn
;
2343 /* update label of interfaces no longer running LDP */
2344 log_debug("release all labels for interface %s af %s", iface
->name
,
2345 af
== AF_INET
? "ipv4" : "ipv6");
2346 RB_FOREACH(f
, fec_tree
, &ft
) {
2347 fn
= (struct fec_node
*)f
;
2351 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2355 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2359 fatalx("lde_route_update_release: unknown af");
2362 if (fn
->local_label
== NO_LABEL
)
2365 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2367 * If connected leave existing label. If LDP
2368 * removed from interface may need new label
2369 * and would be treated as a connected route
2371 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2374 if (fnh
->ifindex
!= iface
->ifindex
)
2377 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2378 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2379 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2380 lde_free_label(fn
->local_label
);
2381 fn
->local_label
= NO_LABEL
;
2382 fn
->local_label
= lde_update_label(fn
);
2383 if (fn
->local_label
!= NO_LABEL
)
2384 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2385 lde_send_labelmapping(ln
, fn
, 0);
2389 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2390 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2394 void lde_route_update_release_all(int af
)
2398 struct fec_node
*fn
;
2401 /* remove labels from all interfaces as LDP is no longer running for
2402 * this address family
2404 log_debug("release all labels for address family %s",
2405 af
== AF_INET
? "ipv4" : "ipv6");
2406 RB_FOREACH(f
, fec_tree
, &ft
) {
2407 fn
= (struct fec_node
*)f
;
2410 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2414 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2418 fatalx("lde_route_update_release: unknown af");
2421 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2422 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2424 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2425 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2426 lde_send_delete_klabel(fn
, fnh
);