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"
37 #include <lib/linklist.h>
43 static void lde_shutdown(void);
44 static int lde_dispatch_imsg(struct thread
*);
45 static int lde_dispatch_parent(struct thread
*);
46 static __inline
int lde_nbr_compare(const struct lde_nbr
*,
47 const struct lde_nbr
*);
48 static struct lde_nbr
*lde_nbr_new(uint32_t, struct lde_nbr
*);
49 static void lde_nbr_del(struct lde_nbr
*);
50 static struct lde_nbr
*lde_nbr_find(uint32_t);
51 static void lde_nbr_clear(void);
52 static void lde_nbr_addr_update(struct lde_nbr
*,
53 struct lde_addr
*, int);
54 static __inline
int lde_map_compare(const struct lde_map
*,
55 const struct lde_map
*);
56 static void lde_map_free(void *);
57 static int lde_address_add(struct lde_nbr
*, struct lde_addr
*);
58 static int lde_address_del(struct lde_nbr
*, struct lde_addr
*);
59 static void lde_address_list_free(struct lde_nbr
*);
60 static void zclient_sync_init(void);
61 static void lde_label_list_init(void);
62 static int lde_get_label_chunk(void);
63 static void on_get_label_chunk_response(uint32_t start
, uint32_t end
);
64 static uint32_t lde_get_next_label(void);
65 static bool lde_fec_connected(const struct fec_node
*);
66 static bool lde_fec_outside_mpls_network(const struct fec_node
*);
67 static void lde_check_filter_af(int, struct ldpd_af_conf
*,
70 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
71 RB_GENERATE(lde_map_head
, lde_map
, entry
, lde_map_compare
)
73 struct ldpd_conf
*ldeconf
;
74 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
76 static struct imsgev
*iev_ldpe
;
77 static struct imsgev iev_main_sync_data
;
78 static struct imsgev
*iev_main
, *iev_main_sync
;
81 static zebra_capabilities_t _caps_p
[] =
86 static struct zebra_privs_t lde_privs
=
88 #if defined(VTY_GROUP)
89 .vty_group
= VTY_GROUP
,
92 .cap_num_p
= array_size(_caps_p
),
96 /* List of chunks of labels externally assigned by Zebra */
97 static struct list
*label_chunk_list
;
98 static struct listnode
*current_label_chunk
;
100 /* Synchronous zclient to request labels */
101 static struct zclient
*zclient_sync
;
103 /* SIGINT / SIGTERM handler. */
110 static struct frr_signal_t lde_signals
[] =
126 /* label decision engine */
130 #ifdef HAVE_SETPROCTITLE
131 setproctitle("label decision engine");
133 ldpd_process
= PROC_LDE_ENGINE
;
134 log_procname
= log_procnames
[PROC_LDE_ENGINE
];
137 /* no frr_config_fork() here, allow frr_pthread to create threads */
138 frr_is_after_fork
= true;
140 /* setup signal handler */
141 signal_init(master
, array_size(lde_signals
), lde_signals
);
143 /* setup pipes and event handlers to the parent process */
144 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
146 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
147 iev_main
->handler_read
= lde_dispatch_parent
;
148 thread_add_read(master
, iev_main
->handler_read
, iev_main
, iev_main
->ibuf
.fd
,
150 iev_main
->handler_write
= ldp_write_handler
;
152 memset(&iev_main_sync_data
, 0, sizeof(iev_main_sync_data
));
153 iev_main_sync
= &iev_main_sync_data
;
154 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
156 /* create base configuration */
157 ldeconf
= config_new_empty();
159 struct thread thread
;
160 while (thread_fetch(master
, &thread
))
161 thread_call(&thread
);
168 lde_init(struct ldpd_init
*init
)
170 /* drop privileges */
171 lde_privs
.user
= init
->user
;
172 lde_privs
.group
= init
->group
;
173 zprivs_preinit(&lde_privs
);
174 zprivs_init(&lde_privs
);
176 /* start the LIB garbage collector */
177 lde_gc_start_timer();
179 /* Init synchronous zclient and label list */
180 frr_zclient_addr(&zclient_addr
, &zclient_addr_len
,
181 init
->zclient_serv_path
);
190 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
191 close(iev_ldpe
->ibuf
.fd
);
192 iev_ldpe
->ibuf
.fd
= -1;
194 msgbuf_clear(&iev_main
->ibuf
.w
);
195 close(iev_main
->ibuf
.fd
);
196 iev_main
->ibuf
.fd
= -1;
197 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
198 close(iev_main_sync
->ibuf
.fd
);
199 iev_main_sync
->ibuf
.fd
= -1;
205 config_clear(ldeconf
);
211 log_info("label decision engine exiting");
219 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
221 if (iev_main
->ibuf
.fd
== -1)
223 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
227 lde_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
229 if (iev_main_sync
->ibuf
.fd
== -1)
231 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
232 imsg_flush(&iev_main_sync
->ibuf
);
236 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
239 if (iev_ldpe
->ibuf
.fd
== -1)
241 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
247 lde_dispatch_imsg(struct thread
*thread
)
249 struct imsgev
*iev
= THREAD_ARG(thread
);
250 struct imsgbuf
*ibuf
= &iev
->ibuf
;
254 struct lde_addr
*lde_addr
;
255 struct notify_msg
*nm
;
261 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
262 fatal("imsg_read error");
263 if (n
== 0) /* connection closed */
267 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
268 fatal("lde_dispatch_imsg: imsg_get error");
272 switch (imsg
.hdr
.type
) {
273 case IMSG_LABEL_MAPPING_FULL
:
274 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
276 log_debug("%s: cannot find lde neighbor",
283 case IMSG_LABEL_MAPPING
:
284 case IMSG_LABEL_REQUEST
:
285 case IMSG_LABEL_RELEASE
:
286 case IMSG_LABEL_WITHDRAW
:
287 case IMSG_LABEL_ABORT
:
288 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
290 fatalx("lde_dispatch_imsg: wrong imsg len");
293 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
295 log_debug("%s: cannot find lde neighbor",
300 switch (imsg
.hdr
.type
) {
301 case IMSG_LABEL_MAPPING
:
302 lde_check_mapping(map
, ln
, 1);
304 case IMSG_LABEL_REQUEST
:
305 lde_check_request(map
, ln
);
307 case IMSG_LABEL_RELEASE
:
308 lde_check_release(map
, ln
);
310 case IMSG_LABEL_WITHDRAW
:
311 lde_check_withdraw(map
, ln
);
313 case IMSG_LABEL_ABORT
:
318 case IMSG_ADDRESS_ADD
:
319 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
320 sizeof(struct lde_addr
))
321 fatalx("lde_dispatch_imsg: wrong imsg len");
322 lde_addr
= imsg
.data
;
324 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
326 log_debug("%s: cannot find lde neighbor",
330 if (lde_address_add(ln
, lde_addr
) < 0) {
331 log_debug("%s: cannot add address %s, it already exists", __func__
,
332 log_addr(lde_addr
->af
, &lde_addr
->addr
));
335 case IMSG_ADDRESS_DEL
:
336 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
337 sizeof(struct lde_addr
))
338 fatalx("lde_dispatch_imsg: wrong imsg len");
339 lde_addr
= imsg
.data
;
341 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
343 log_debug("%s: cannot find lde neighbor",
347 if (lde_address_del(ln
, lde_addr
) < 0) {
348 log_debug("%s: cannot delete address %s, it does not exist", __func__
,
349 log_addr(lde_addr
->af
, &lde_addr
->addr
));
352 case IMSG_NOTIFICATION
:
353 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
354 sizeof(struct notify_msg
))
355 fatalx("lde_dispatch_imsg: wrong imsg len");
358 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
360 log_debug("%s: cannot find lde neighbor",
365 switch (nm
->status_code
) {
367 l2vpn_recv_pw_status(ln
, nm
);
371 * Do nothing for now. Should be useful in
372 * the future when we implement LDP-IGP
373 * Synchronization (RFC 5443) and Graceful
374 * Restart (RFC 3478).
380 case IMSG_NEIGHBOR_UP
:
381 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
382 sizeof(struct lde_nbr
))
383 fatalx("lde_dispatch_imsg: wrong imsg len");
385 if (lde_nbr_find(imsg
.hdr
.peerid
))
386 fatalx("lde_dispatch_imsg: neighbor already exists");
387 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
389 case IMSG_NEIGHBOR_DOWN
:
390 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
392 case IMSG_CTL_SHOW_LIB
:
393 rt_dump(imsg
.hdr
.pid
);
395 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
396 imsg
.hdr
.pid
, NULL
, 0);
398 case IMSG_CTL_SHOW_L2VPN_PW
:
399 l2vpn_pw_ctl(imsg
.hdr
.pid
);
401 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
402 imsg
.hdr
.pid
, NULL
, 0);
404 case IMSG_CTL_SHOW_L2VPN_BINDING
:
405 l2vpn_binding_ctl(imsg
.hdr
.pid
);
407 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
408 imsg
.hdr
.pid
, NULL
, 0);
411 log_debug("%s: unexpected imsg %d", __func__
,
420 /* this pipe is dead, so remove the event handlers and exit */
421 thread_cancel(&iev
->ev_read
);
422 thread_cancel(&iev
->ev_write
);
431 lde_dispatch_parent(struct thread
*thread
)
433 static struct ldpd_conf
*nconf
;
434 struct iface
*iface
, *niface
;
436 struct nbr_params
*nnbrp
;
437 static struct l2vpn
*l2vpn
, *nl2vpn
;
438 struct l2vpn_if
*lif
, *nlif
;
439 struct l2vpn_pw
*pw
, *npw
;
444 struct imsgev
*iev
= THREAD_ARG(thread
);
445 struct imsgbuf
*ibuf
= &iev
->ibuf
;
449 struct ldp_access
*laccess
;
450 struct ldp_rlfa_node
*rnode
, *rntmp
;
451 struct ldp_rlfa_client
*rclient
;
452 struct zapi_rlfa_request
*rlfa_req
;
453 struct zapi_rlfa_igp
*rlfa_igp
;
457 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
458 fatal("imsg_read error");
459 if (n
== 0) /* connection closed */
463 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
464 fatal("lde_dispatch_parent: imsg_get error");
468 switch (imsg
.hdr
.type
) {
470 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
472 fatalx("IFSTATUS imsg with wrong len");
475 iface
= if_lookup_name(ldeconf
, kif
->ifname
);
477 if_update_info(iface
, kif
);
479 /* if up see if any labels need to be updated */
481 lde_route_update(iface
, AF_UNSPEC
);
485 RB_FOREACH(l2vpn
, l2vpn_head
, &ldeconf
->l2vpn_tree
) {
486 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
488 l2vpn_if_update_info(lif
, kif
);
491 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
493 l2vpn_pw_update_info(pw
, kif
);
499 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
500 sizeof(struct zapi_pw_status
))
501 fatalx("PW_UPDATE imsg with wrong len");
503 if (l2vpn_pw_status_update(imsg
.data
) != 0)
504 log_warnx("%s: error updating PW status",
507 case IMSG_NETWORK_ADD
:
508 case IMSG_NETWORK_UPDATE
:
509 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
510 sizeof(struct kroute
)) {
511 log_warnx("%s: wrong imsg len", __func__
);
518 fec
.type
= FEC_TYPE_IPV4
;
519 fec
.u
.ipv4
.prefix
= kr
->prefix
.v4
;
520 fec
.u
.ipv4
.prefixlen
= kr
->prefixlen
;
523 fec
.type
= FEC_TYPE_IPV6
;
524 fec
.u
.ipv6
.prefix
= kr
->prefix
.v6
;
525 fec
.u
.ipv6
.prefixlen
= kr
->prefixlen
;
528 fatalx("lde_dispatch_parent: unknown af");
531 switch (imsg
.hdr
.type
) {
532 case IMSG_NETWORK_ADD
:
533 lde_kernel_insert(&fec
, kr
->af
, &kr
->nexthop
,
534 kr
->ifindex
, kr
->route_type
,
536 kr
->flags
& F_CONNECTED
, NULL
);
538 case IMSG_NETWORK_UPDATE
:
539 lde_kernel_update(&fec
);
543 case IMSG_SOCKET_IPC
:
545 log_warnx("%s: received unexpected imsg fd to ldpe", __func__
);
548 if ((fd
= imsg
.fd
) == -1) {
549 log_warnx("%s: expected to receive imsg fd to ldpe but didn't receive any", __func__
);
553 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
555 imsg_init(&iev_ldpe
->ibuf
, fd
);
556 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
557 thread_add_read(master
, iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
,
559 iev_ldpe
->handler_write
= ldp_write_handler
;
560 iev_ldpe
->ev_write
= NULL
;
563 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
564 sizeof(struct ldpd_init
))
565 fatalx("INIT imsg with wrong len");
567 memcpy(&init
, imsg
.data
, sizeof(init
));
570 case IMSG_AGENTX_ENABLED
:
571 ldp_agentx_enabled();
573 case IMSG_RECONF_CONF
:
574 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
577 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
579 RB_INIT(iface_head
, &nconf
->iface_tree
);
580 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
581 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
582 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
584 case IMSG_RECONF_IFACE
:
585 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
587 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
589 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
591 case IMSG_RECONF_TNBR
:
592 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
594 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
596 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
598 case IMSG_RECONF_NBRP
:
599 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
601 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
603 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
605 case IMSG_RECONF_L2VPN
:
606 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
608 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
610 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
611 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
612 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
614 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
616 case IMSG_RECONF_L2VPN_IF
:
617 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
619 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
621 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
623 case IMSG_RECONF_L2VPN_PW
:
624 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
626 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
628 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
630 case IMSG_RECONF_L2VPN_IPW
:
631 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
633 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
635 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
637 case IMSG_RECONF_END
:
638 merge_config(ldeconf
, nconf
);
639 ldp_clear_config(nconf
);
642 case IMSG_DEBUG_UPDATE
:
643 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
645 log_warnx("%s: wrong imsg len", __func__
);
648 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
650 case IMSG_FILTER_UPDATE
:
651 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
652 sizeof(struct ldp_access
)) {
653 log_warnx("%s: wrong imsg len", __func__
);
657 lde_check_filter_af(AF_INET
, &ldeconf
->ipv4
,
659 lde_check_filter_af(AF_INET6
, &ldeconf
->ipv6
,
663 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
664 sizeof(struct zapi_rlfa_request
)) {
665 log_warnx("%s: wrong imsg len", __func__
);
668 rlfa_req
= imsg
.data
;
669 rnode
= rlfa_node_find(&rlfa_req
->destination
,
670 rlfa_req
->pq_address
);
672 rnode
= rlfa_node_new(&rlfa_req
->destination
,
673 rlfa_req
->pq_address
);
674 rclient
= rlfa_client_find(rnode
, &rlfa_req
->igp
);
676 /* RLFA already registered - do nothing */
678 rclient
= rlfa_client_new(rnode
, &rlfa_req
->igp
);
679 lde_rlfa_check(rclient
);
681 case IMSG_RLFA_UNREG_ALL
:
682 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
683 sizeof(struct zapi_rlfa_igp
)) {
684 log_warnx("%s: wrong imsg len", __func__
);
687 rlfa_igp
= imsg
.data
;
689 RB_FOREACH_SAFE (rnode
, ldp_rlfa_node_head
,
690 &rlfa_node_tree
, rntmp
) {
691 rclient
= rlfa_client_find(rnode
, rlfa_igp
);
695 rlfa_client_del(rclient
);
699 log_debug("%s: unexpected imsg %d", __func__
,
708 /* this pipe is dead, so remove the event handlers and exit */
709 thread_cancel(&iev
->ev_read
);
710 thread_cancel(&iev
->ev_write
);
718 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
720 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
723 static bool lde_fec_connected(const struct fec_node
*fn
)
727 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
728 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
734 static bool lde_fec_outside_mpls_network(const struct fec_node
*fn
)
738 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
739 if (!(fnh
->flags
& F_FEC_NH_NO_LDP
))
746 lde_update_label(struct fec_node
*fn
)
749 /* should we allocate a label for this fec? */
750 switch (fn
->fec
.type
) {
752 if ((ldeconf
->ipv4
.flags
& F_LDPD_AF_ALLOCHOSTONLY
)
753 && fn
->fec
.u
.ipv4
.prefixlen
!= IPV4_MAX_BITLEN
)
755 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
756 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
757 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
761 if ((ldeconf
->ipv6
.flags
& F_LDPD_AF_ALLOCHOSTONLY
)
762 && fn
->fec
.u
.ipv6
.prefixlen
!= IPV6_MAX_BITLEN
)
764 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
765 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
766 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
774 * If connected interface act as egress for fec.
775 * If LDP is not configured on an interface but there
776 * are other NHs with interfaces configured with LDP
777 * then don't act as an egress for the fec, otherwise
778 * act as an egress for the fec
780 if (lde_fec_connected(fn
) || lde_fec_outside_mpls_network(fn
)) {
781 /* choose implicit or explicit-null depending on configuration */
782 switch (fn
->fec
.type
) {
784 if (!(ldeconf
->ipv4
.flags
& F_LDPD_AF_EXPNULL
))
785 return (MPLS_LABEL_IMPLICIT_NULL
);
786 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
787 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
788 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
789 return (MPLS_LABEL_IMPLICIT_NULL
);
790 return MPLS_LABEL_IPV4_EXPLICIT_NULL
;
792 if (!(ldeconf
->ipv6
.flags
& F_LDPD_AF_EXPNULL
))
793 return (MPLS_LABEL_IMPLICIT_NULL
);
794 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
795 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
796 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
797 return (MPLS_LABEL_IMPLICIT_NULL
);
798 return MPLS_LABEL_IPV6_EXPLICIT_NULL
;
804 /* preserve current label if there's no need to update it */
805 if (fn
->local_label
!= NO_LABEL
&&
806 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
807 return (fn
->local_label
);
809 return (lde_get_next_label());
813 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
820 * Ordered Control: don't program label into HW until a
821 * labelmap msg has been received from upstream router
823 if (fnh
->flags
& F_FEC_NH_DEFER
)
826 switch (fn
->fec
.type
) {
828 memset(&kr
, 0, sizeof(kr
));
830 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
831 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
832 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
833 kr
.ifindex
= fnh
->ifindex
;
834 kr
.local_label
= fn
->local_label
;
835 kr
.remote_label
= fnh
->remote_label
;
836 kr
.route_type
= fnh
->route_type
;
837 kr
.route_instance
= fnh
->route_instance
;
838 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
842 memset(&kr
, 0, sizeof(kr
));
844 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
845 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
846 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
847 kr
.ifindex
= fnh
->ifindex
;
848 kr
.local_label
= fn
->local_label
;
849 kr
.remote_label
= fnh
->remote_label
;
850 kr
.route_type
= fnh
->route_type
;
851 kr
.route_instance
= fnh
->route_instance
;
853 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
857 pw
= (struct l2vpn_pw
*) fn
->data
;
858 if (!pw
|| fn
->local_label
== NO_LABEL
||
859 fnh
->remote_label
== NO_LABEL
)
864 zpw
.local_label
= fn
->local_label
;
865 zpw
.remote_label
= fnh
->remote_label
;
866 lde_imsg_compose_parent(IMSG_KPW_SET
, 0, &zpw
, sizeof(zpw
));
872 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
878 switch (fn
->fec
.type
) {
880 memset(&kr
, 0, sizeof(kr
));
882 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
883 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
884 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
885 kr
.ifindex
= fnh
->ifindex
;
886 kr
.local_label
= fn
->local_label
;
887 kr
.remote_label
= fnh
->remote_label
;
888 kr
.route_type
= fnh
->route_type
;
889 kr
.route_instance
= fnh
->route_instance
;
891 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
895 memset(&kr
, 0, sizeof(kr
));
897 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
898 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
899 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
900 kr
.ifindex
= fnh
->ifindex
;
901 kr
.local_label
= fn
->local_label
;
902 kr
.remote_label
= fnh
->remote_label
;
903 kr
.route_type
= fnh
->route_type
;
904 kr
.route_instance
= fnh
->route_instance
;
906 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
910 pw
= (struct l2vpn_pw
*) fn
->data
;
916 zpw
.local_label
= fn
->local_label
;
917 zpw
.remote_label
= fnh
->remote_label
;
918 lde_imsg_compose_parent(IMSG_KPW_UNSET
, 0, &zpw
, sizeof(zpw
));
924 lde_fec2prefix(const struct fec
*fec
, struct prefix
*prefix
)
926 memset(prefix
, 0, sizeof(*prefix
));
929 prefix
->family
= AF_INET
;
930 prefix
->u
.prefix4
= fec
->u
.ipv4
.prefix
;
931 prefix
->prefixlen
= fec
->u
.ipv4
.prefixlen
;
934 prefix
->family
= AF_INET6
;
935 prefix
->u
.prefix6
= fec
->u
.ipv6
.prefix
;
936 prefix
->prefixlen
= fec
->u
.ipv6
.prefixlen
;
939 prefix
->family
= AF_UNSPEC
;
945 lde_prefix2fec(const struct prefix
*prefix
, struct fec
*fec
)
947 memset(fec
, 0, sizeof(*fec
));
948 switch (prefix
->family
) {
950 fec
->type
= FEC_TYPE_IPV4
;
951 fec
->u
.ipv4
.prefix
= prefix
->u
.prefix4
;
952 fec
->u
.ipv4
.prefixlen
= prefix
->prefixlen
;
955 fec
->type
= FEC_TYPE_IPV6
;
956 fec
->u
.ipv6
.prefix
= prefix
->u
.prefix6
;
957 fec
->u
.ipv6
.prefixlen
= prefix
->prefixlen
;
960 fatalx("lde_prefix2fec: unknown af");
966 lde_fec2map(struct fec
*fec
, struct map
*map
)
968 memset(map
, 0, sizeof(*map
));
972 map
->type
= MAP_TYPE_PREFIX
;
973 map
->fec
.prefix
.af
= AF_INET
;
974 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
975 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
978 map
->type
= MAP_TYPE_PREFIX
;
979 map
->fec
.prefix
.af
= AF_INET6
;
980 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
981 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
984 map
->type
= MAP_TYPE_PWID
;
985 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
986 map
->fec
.pwid
.group_id
= 0;
987 map
->flags
|= F_MAP_PW_ID
;
988 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
994 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
996 memset(fec
, 0, sizeof(*fec
));
999 case MAP_TYPE_PREFIX
:
1000 switch (map
->fec
.prefix
.af
) {
1002 fec
->type
= FEC_TYPE_IPV4
;
1003 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
1004 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
1007 fec
->type
= FEC_TYPE_IPV6
;
1008 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
1009 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
1012 fatalx("lde_map2fec: unknown af");
1017 fec
->type
= FEC_TYPE_PWID
;
1018 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
1019 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
1020 fec
->u
.pwid
.lsr_id
= lsr_id
;
1026 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
1028 struct lde_wdraw
*lw
;
1030 struct lde_req
*lre
;
1032 struct l2vpn_pw
*pw
;
1037 * Ordered Control: do not send a labelmap msg until
1038 * a labelmap message is received from downstream router
1039 * and don't send labelmap back to downstream router
1041 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
1042 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1043 if (fnh
->flags
& F_FEC_NH_DEFER
)
1046 if (lde_address_find(ln
, fnh
->af
, &fnh
->nexthop
))
1056 * We shouldn't send a new label mapping if we have a pending
1057 * label release to receive. In this case, schedule to send a
1058 * label mapping as soon as a label release is received.
1060 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1062 if (!fec_find(&ln
->sent_map_pending
, &fn
->fec
)) {
1063 debug_evt("%s: FEC %s: scheduling to send label mapping later (waiting for pending label release)",
1064 __func__
, log_fec(&fn
->fec
));
1065 lde_map_pending_add(ln
, fn
);
1071 * This function skips SL.1 - 3 and SL.9 - 14 because the label
1072 * allocation is done way earlier (because of the merging nature of
1076 lde_fec2map(&fn
->fec
, &map
);
1077 switch (fn
->fec
.type
) {
1079 if (!ln
->v4_enabled
)
1081 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
1082 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1084 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
1085 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
1086 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
1090 if (!ln
->v6_enabled
)
1092 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
1093 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1095 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
1096 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
1097 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
1101 pw
= (struct l2vpn_pw
*) fn
->data
;
1102 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1103 /* not the remote end of the pseudowire */
1106 map
.flags
|= F_MAP_PW_IFMTU
;
1107 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
1108 if (pw
->flags
& F_PW_CWORD
)
1109 map
.flags
|= F_MAP_PW_CWORD
;
1110 if (pw
->flags
& F_PW_STATUSTLV
) {
1111 map
.flags
|= F_MAP_PW_STATUS
;
1112 map
.pw_status
= pw
->local_status
;
1116 map
.label
= fn
->local_label
;
1118 /* SL.6: is there a pending request for this mapping? */
1119 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
1121 /* set label request msg id in the mapping response. */
1122 map
.requestid
= lre
->msg_id
;
1123 map
.flags
= F_MAP_REQ_ID
;
1125 /* SL.7: delete record of pending request */
1126 lde_req_del(ln
, lre
, 0);
1129 /* SL.4: send label mapping */
1130 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
1133 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1136 /* SL.5: record sent label mapping */
1137 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1139 me
= lde_map_add(ln
, fn
, 1);
1144 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
,
1145 struct map
*wcard
, struct status_tlv
*st
)
1147 struct lde_wdraw
*lw
;
1150 struct l2vpn_pw
*pw
;
1153 lde_fec2map(&fn
->fec
, &map
);
1154 switch (fn
->fec
.type
) {
1156 if (!ln
->v4_enabled
)
1160 if (!ln
->v6_enabled
)
1164 pw
= (struct l2vpn_pw
*) fn
->data
;
1165 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1166 /* not the remote end of the pseudowire */
1169 if (pw
->flags
& F_PW_CWORD
)
1170 map
.flags
|= F_MAP_PW_CWORD
;
1173 map
.label
= fn
->local_label
;
1175 memcpy(&map
, wcard
, sizeof(map
));
1178 map
.st
.status_code
= st
->status_code
;
1179 map
.st
.msg_id
= st
->msg_id
;
1180 map
.st
.msg_type
= st
->msg_type
;
1181 map
.flags
|= F_MAP_STATUS
;
1184 /* SWd.1: send label withdraw. */
1185 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
1187 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1189 /* SWd.2: record label withdraw. */
1191 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1193 lw
= lde_wdraw_add(ln
, fn
);
1194 lw
->label
= map
.label
;
1198 RB_FOREACH(f
, fec_tree
, &ft
) {
1199 fn
= (struct fec_node
*)f
;
1200 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1201 if (lde_wildcard_apply(wcard
, &fn
->fec
, me
) == 0)
1204 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
1207 lw
= lde_wdraw_add(ln
, fn
);
1208 lw
->label
= map
.label
;
1214 lde_send_labelwithdraw_wcard(struct lde_nbr
*ln
, uint32_t label
)
1218 memset(&wcard
, 0, sizeof(wcard
));
1219 wcard
.type
= MAP_TYPE_WILDCARD
;
1220 wcard
.label
= label
;
1221 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1225 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr
*ln
, uint16_t af
,
1230 memset(&wcard
, 0, sizeof(wcard
));
1231 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1232 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1233 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1234 wcard
.label
= label
;
1235 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1239 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr
*ln
, uint16_t pw_type
,
1244 memset(&wcard
, 0, sizeof(wcard
));
1245 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1246 wcard
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1247 wcard
.fec
.twcard
.u
.pw_type
= pw_type
;
1248 wcard
.label
= label
;
1249 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1253 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr
*ln
, uint16_t pw_type
,
1258 memset(&wcard
, 0, sizeof(wcard
));
1259 wcard
.type
= MAP_TYPE_PWID
;
1260 wcard
.fec
.pwid
.type
= pw_type
;
1261 wcard
.fec
.pwid
.group_id
= group_id
;
1262 /* we can not append a Label TLV when using PWid group wildcards. */
1263 wcard
.label
= NO_LABEL
;
1264 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1268 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
,
1269 struct map
*wcard
, uint32_t label
)
1272 struct l2vpn_pw
*pw
;
1275 lde_fec2map(&fn
->fec
, &map
);
1276 switch (fn
->fec
.type
) {
1278 if (!ln
->v4_enabled
)
1282 if (!ln
->v6_enabled
)
1286 pw
= (struct l2vpn_pw
*) fn
->data
;
1287 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1288 /* not the remote end of the pseudowire */
1291 if (pw
->flags
& F_PW_CWORD
)
1292 map
.flags
|= F_MAP_PW_CWORD
;
1296 memcpy(&map
, wcard
, sizeof(map
));
1299 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1301 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1305 lde_send_labelrequest(struct lde_nbr
*ln
, struct fec_node
*fn
,
1306 struct map
*wcard
, int single
)
1310 struct lde_req
*lre
;
1313 lde_fec2map(&fn
->fec
, &map
);
1314 switch (fn
->fec
.type
) {
1316 if (!ln
->v4_enabled
)
1320 if (!ln
->v6_enabled
)
1324 fatalx("lde_send_labelrequest: unknown af");
1327 memcpy(&map
, wcard
, sizeof(map
));
1329 map
.label
= NO_LABEL
;
1332 /* SLR1.1: has label request for FEC been previously sent
1333 * and still outstanding just return,
1335 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1337 /* SLRq.3: send label request */
1338 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
, ln
->peerid
, 0,
1341 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1342 ln
->peerid
, 0, NULL
, 0);
1344 /* SLRq.4: record sent request */
1345 lde_req_add(ln
, &fn
->fec
, 1);
1348 /* if Wilcard just send label request */
1349 /* SLRq.3: send label request */
1350 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
,
1351 ln
->peerid
, 0, &map
, sizeof(map
));
1353 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1354 ln
->peerid
, 0, NULL
, 0);
1356 /* SLRq.4: record sent request */
1357 RB_FOREACH(f
, fec_tree
, &ft
) {
1358 fn
= (struct fec_node
*)f
;
1359 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1360 if (lde_wildcard_apply(wcard
, &fn
->fec
, NULL
) == 0)
1363 lde_req_add(ln
, f
, 1);
1369 lde_send_labelrequest_wcard(struct lde_nbr
*ln
, uint16_t af
)
1373 memset(&wcard
, 0, sizeof(wcard
));
1374 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1375 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1376 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1377 lde_send_labelrequest(ln
, NULL
, &wcard
, 1);
1381 lde_send_notification(struct lde_nbr
*ln
, uint32_t status_code
, uint32_t msg_id
,
1384 struct notify_msg nm
;
1386 memset(&nm
, 0, sizeof(nm
));
1387 nm
.status_code
= status_code
;
1388 /* 'msg_id' and 'msg_type' should be in network byte order */
1390 nm
.msg_type
= msg_type
;
1392 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1397 lde_send_notification_eol_prefix(struct lde_nbr
*ln
, int af
)
1399 struct notify_msg nm
;
1401 memset(&nm
, 0, sizeof(nm
));
1402 nm
.status_code
= S_ENDOFLIB
;
1403 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1404 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1405 nm
.fec
.fec
.twcard
.u
.prefix_af
= af
;
1406 nm
.flags
|= F_NOTIF_FEC
;
1408 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1413 lde_send_notification_eol_pwid(struct lde_nbr
*ln
, uint16_t pw_type
)
1415 struct notify_msg nm
;
1417 memset(&nm
, 0, sizeof(nm
));
1418 nm
.status_code
= S_ENDOFLIB
;
1419 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1420 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1421 nm
.fec
.fec
.twcard
.u
.pw_type
= pw_type
;
1422 nm
.flags
|= F_NOTIF_FEC
;
1424 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1429 lde_nbr_compare(const struct lde_nbr
*a
, const struct lde_nbr
*b
)
1431 return (a
->peerid
- b
->peerid
);
1434 static struct lde_nbr
*
1435 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1439 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1443 ln
->v4_enabled
= new->v4_enabled
;
1444 ln
->v6_enabled
= new->v6_enabled
;
1445 ln
->flags
= new->flags
;
1446 ln
->peerid
= peerid
;
1447 fec_init(&ln
->recv_map
);
1448 fec_init(&ln
->sent_map
);
1449 fec_init(&ln
->sent_map_pending
);
1450 fec_init(&ln
->recv_req
);
1451 fec_init(&ln
->sent_req
);
1452 fec_init(&ln
->sent_wdraw
);
1454 TAILQ_INIT(&ln
->addr_list
);
1456 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1457 fatalx("lde_nbr_new: RB_INSERT failed");
1463 lde_nbr_del(struct lde_nbr
*ln
)
1466 struct fec_node
*fn
;
1468 struct l2vpn_pw
*pw
;
1469 struct lde_nbr
*lnbr
;
1474 /* uninstall received mappings */
1475 RB_FOREACH(f
, fec_tree
, &ft
) {
1476 fn
= (struct fec_node
*)f
;
1478 /* Update RLFA clients. */
1479 lde_rlfa_update_clients(f
, ln
, MPLS_INVALID_LABEL
);
1481 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1485 if (!lde_address_find(ln
, fnh
->af
,
1490 * Ordered Control: must mark any non-connected
1491 * NH to wait until we receive a labelmap msg
1492 * before installing in kernel and sending to
1493 * peer, must do this as NHs are not removed
1494 * when lsps go down. Also send label withdraw
1495 * to other neighbors for all fecs from neighbor
1498 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
1499 fnh
->flags
|= F_FEC_NH_DEFER
;
1501 RB_FOREACH(lnbr
, nbr_tree
, &lde_nbrs
) {
1502 if (ln
->peerid
== lnbr
->peerid
)
1504 lde_send_labelwithdraw(lnbr
, fn
, NULL
, NULL
);
1509 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1511 pw
= (struct l2vpn_pw
*) fn
->data
;
1513 pw
->reason
= F_PW_NO_REMOTE_LABEL
;
1521 lde_send_delete_klabel(fn
, fnh
);
1522 fnh
->remote_label
= NO_LABEL
;
1526 lde_address_list_free(ln
);
1528 fec_clear(&ln
->recv_map
, lde_map_free
);
1529 fec_clear(&ln
->sent_map
, lde_map_free
);
1530 fec_clear(&ln
->sent_map_pending
, free
);
1531 fec_clear(&ln
->recv_req
, free
);
1532 fec_clear(&ln
->sent_req
, free
);
1533 fec_clear(&ln
->sent_wdraw
, free
);
1535 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1540 static struct lde_nbr
*
1541 lde_nbr_find(uint32_t peerid
)
1547 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1551 lde_nbr_find_by_lsrid(struct in_addr addr
)
1555 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1556 if (ln
->id
.s_addr
== addr
.s_addr
)
1563 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1567 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1568 if (lde_address_find(ln
, af
, addr
) != NULL
)
1579 while (!RB_EMPTY(nbr_tree
, &lde_nbrs
)) {
1580 ln
= RB_ROOT(nbr_tree
, &lde_nbrs
);
1587 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1590 struct fec_node
*fn
;
1594 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1595 switch (fec
->type
) {
1597 if (lde_addr
->af
!= AF_INET
)
1601 if (lde_addr
->af
!= AF_INET6
)
1608 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1610 /* shouldn't happen */
1613 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1614 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1619 lde_send_delete_klabel(fn
, fnh
);
1620 fnh
->remote_label
= NO_LABEL
;
1622 me
= (struct lde_map
*)fec
;
1623 fnh
->remote_label
= me
->map
.label
;
1624 lde_send_change_klabel(fn
, fnh
);
1632 lde_allow_broken_lsp_update(int new_config
)
1634 struct fec_node
*fn
;
1638 RB_FOREACH(f
, fec_tree
, &ft
) {
1639 fn
= (struct fec_node
*)f
;
1641 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1642 /* allow-broken-lsp config is changing so
1643 * we need to reprogram labeled routes to
1644 * have proper top-level label
1646 if (!(new_config
& F_LDPD_ALLOW_BROKEN_LSP
))
1647 lde_send_delete_klabel(fn
, fnh
);
1649 if (fn
->local_label
!= NO_LABEL
)
1650 lde_send_change_klabel(fn
, fnh
);
1656 lde_map_compare(const struct lde_map
*a
, const struct lde_map
*b
)
1658 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1659 (union ldpd_addr
*)&b
->nexthop
->id
));
1663 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1667 me
= calloc(1, sizeof(*me
));
1675 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1676 me
->head
= &fn
->upstream
;
1677 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1678 log_warnx("failed to add %s to sent map",
1680 /* XXX on failure more cleanup is needed */
1682 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1683 me
->head
= &fn
->downstream
;
1684 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1685 log_warnx("failed to add %s to recv map",
1693 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1696 fec_remove(&ln
->sent_map
, &me
->fec
);
1698 fec_remove(&ln
->recv_map
, &me
->fec
);
1704 lde_map_free(void *ptr
)
1706 struct lde_map
*map
= ptr
;
1708 RB_REMOVE(lde_map_head
, map
->head
, map
);
1713 lde_map_pending_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1717 map
= calloc(1, sizeof(*map
));
1722 if (fec_insert(&ln
->sent_map_pending
, map
))
1723 log_warnx("failed to add %s to sent map (pending)",
1730 lde_map_pending_del(struct lde_nbr
*ln
, struct fec
*map
)
1732 fec_remove(&ln
->sent_map_pending
, map
);
1737 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1740 struct lde_req
*lre
;
1742 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1744 lre
= calloc(1, sizeof(*lre
));
1748 if (fec_insert(t
, &lre
->fec
)) {
1749 log_warnx("failed to add %s to %s req",
1750 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1760 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1763 fec_remove(&ln
->sent_req
, &lre
->fec
);
1765 fec_remove(&ln
->recv_req
, &lre
->fec
);
1771 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1773 struct lde_wdraw
*lw
;
1775 lw
= calloc(1, sizeof(*lw
));
1781 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1782 log_warnx("failed to add %s to sent wdraw",
1789 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1791 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1796 lde_change_egress_label(int af
)
1800 struct fec_node
*fn
;
1802 /* explicitly withdraw all null labels */
1803 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1804 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IMPLICIT_NULL
);
1806 lde_send_labelwithdraw_wcard(
1808 MPLS_LABEL_IPV4_EXPLICIT_NULL
);
1810 lde_send_labelwithdraw_wcard(
1812 MPLS_LABEL_IPV6_EXPLICIT_NULL
);
1815 /* update label of connected routes */
1816 RB_FOREACH(f
, fec_tree
, &ft
) {
1817 fn
= (struct fec_node
*)f
;
1818 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1823 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1827 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1831 fatalx("lde_change_egress_label: unknown af");
1834 fn
->local_label
= lde_update_label(fn
);
1835 if (fn
->local_label
!= NO_LABEL
)
1836 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1837 lde_send_labelmapping(ln
, fn
, 0);
1839 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1840 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1845 lde_change_allocate_filter(int af
)
1849 struct fec_node
*fn
;
1852 /* reallocate labels for fecs that match this filter */
1853 RB_FOREACH(f
, fec_tree
, &ft
) {
1854 fn
= (struct fec_node
*)f
;
1858 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1862 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1866 fatalx("lde_change_allocate_filter: unknown af");
1870 * If the local label has changed to NO_LABEL, send a label
1871 * withdraw to all peers.
1872 * If the local label has changed and it's different from
1873 * NO_LABEL, send a label mapping to all peers advertising
1875 * If the local label hasn't changed, do nothing
1877 new_label
= lde_update_label(fn
);
1878 if (fn
->local_label
!= new_label
) {
1879 if (new_label
== NO_LABEL
)
1880 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1881 lde_send_labelwithdraw(ln
, fn
,
1884 fn
->local_label
= new_label
;
1885 if (fn
->local_label
!= NO_LABEL
)
1886 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1887 lde_send_labelmapping(ln
, fn
, 0);
1890 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1891 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1896 lde_change_advertise_filter(int af
)
1900 struct fec_node
*fn
;
1901 char *acl_to_filter
;
1902 char *acl_for_filter
;
1903 union ldpd_addr
*prefix
;
1907 /* advertise label for fecs to neighbors if matches advertise filters */
1910 acl_to_filter
= ldeconf
->ipv4
.acl_label_advertise_to
;
1911 acl_for_filter
= ldeconf
->ipv4
.acl_label_advertise_for
;
1914 acl_to_filter
= ldeconf
->ipv6
.acl_label_advertise_to
;
1915 acl_for_filter
= ldeconf
->ipv6
.acl_label_advertise_for
;
1918 fatalx("lde_change_advertise_filter: unknown af");
1921 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1922 if (lde_acl_check(acl_to_filter
, af
, (union ldpd_addr
*)&ln
->id
,
1923 IPV4_MAX_BITLEN
) != FILTER_PERMIT
)
1924 lde_send_labelwithdraw_wcard(ln
, NO_LABEL
);
1926 /* This neighbor is allowed in to_filter, so
1927 * send labels if fec also matches for_filter
1929 RB_FOREACH(f
, fec_tree
, &ft
) {
1930 fn
= (struct fec_node
*)f
;
1933 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1935 prefix
= (union ldpd_addr
*)
1936 &fn
->fec
.u
.ipv4
.prefix
;
1937 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1940 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1942 prefix
= (union ldpd_addr
*)
1943 &fn
->fec
.u
.ipv6
.prefix
;
1944 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1949 if (lde_acl_check(acl_for_filter
, af
,
1950 prefix
, plen
) != FILTER_PERMIT
) {
1951 me
= (struct lde_map
*)fec_find(
1952 &ln
->sent_map
, &fn
->fec
);
1954 /* fec filtered withdraw */
1955 lde_send_labelwithdraw(ln
, fn
,
1958 /* fec allowed send map */
1959 lde_send_labelmapping(ln
, fn
, 0);
1961 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
,
1962 ln
->peerid
, 0, NULL
, 0);
1969 lde_change_accept_filter(int af
)
1973 struct fec_node
*fn
;
1974 char *acl_for_filter
;
1975 char *acl_from_filter
;
1976 union ldpd_addr
*prefix
;
1981 /* accept labels from neighbors specified in the from_filter and for
1982 * fecs defined in the for_filter
1986 acl_for_filter
= ldeconf
->ipv4
.acl_label_accept_for
;
1987 acl_from_filter
= ldeconf
->ipv4
.acl_label_accept_from
;
1988 type
= FEC_TYPE_IPV4
;
1991 acl_for_filter
= ldeconf
->ipv6
.acl_label_accept_for
;
1992 acl_from_filter
= ldeconf
->ipv6
.acl_label_accept_from
;
1993 type
= FEC_TYPE_IPV6
;
1996 fatalx("lde_change_accept_filter: unknown af");
1999 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
2000 if (lde_acl_check(acl_from_filter
, AF_INET
, (union ldpd_addr
*)
2001 &ln
->id
, IPV4_MAX_BITLEN
) != FILTER_PERMIT
) {
2002 /* This neighbor is now filtered so remove fecs from
2005 RB_FOREACH(f
, fec_tree
, &ft
) {
2006 fn
= (struct fec_node
*)f
;
2007 if (fn
->fec
.type
== type
) {
2008 me
= (struct lde_map
*)fec_find(
2009 &ln
->recv_map
, &fn
->fec
);
2011 lde_map_del(ln
, me
, 0);
2014 } else if (ln
->flags
& F_NBR_CAP_TWCARD
) {
2015 /* This neighbor is allowed and supports type
2016 * wildcard so send a labelrequest
2017 * to get any new labels from neighbor
2018 * and make sure any fecs we currently have
2021 RB_FOREACH(f
, fec_tree
, &ft
) {
2022 fn
= (struct fec_node
*)f
;
2025 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2027 prefix
= (union ldpd_addr
*)
2028 &fn
->fec
.u
.ipv4
.prefix
;
2029 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
2032 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2034 prefix
= (union ldpd_addr
*)
2035 &fn
->fec
.u
.ipv6
.prefix
;
2036 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
2041 if (lde_acl_check(acl_for_filter
, af
,
2042 prefix
, plen
) != FILTER_PERMIT
) {
2043 me
= (struct lde_map
*)fec_find(
2044 &ln
->recv_map
, &fn
->fec
);
2046 lde_map_del(ln
, me
, 0);
2049 lde_send_labelrequest_wcard(ln
, af
);
2051 /* Type Wildcard is not supported so restart session */
2052 lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN
, ln
->peerid
, 0,
2058 lde_change_expnull_for_filter(int af
)
2062 struct fec_node
*fn
;
2065 union ldpd_addr
*prefix
;
2068 /* Configure explicit-null advertisement for all fecs in this filter */
2069 RB_FOREACH(f
, fec_tree
, &ft
) {
2070 fn
= (struct fec_node
*)f
;
2074 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2076 acl_name
= ldeconf
->ipv4
.acl_label_expnull_for
;
2077 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
2078 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
2079 exp_label
= MPLS_LABEL_IPV4_EXPLICIT_NULL
;
2082 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2084 acl_name
= ldeconf
->ipv6
.acl_label_expnull_for
;
2085 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
2086 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
2087 exp_label
= MPLS_LABEL_IPV6_EXPLICIT_NULL
;
2090 fatalx("lde_change_expnull_for_filter: unknown af");
2093 if (lde_acl_check(acl_name
, af
, prefix
, plen
) == FILTER_PERMIT
) {
2094 /* for this fec change any imp-null to exp-null */
2095 if (fn
->local_label
== MPLS_LABEL_IMPLICIT_NULL
) {
2096 fn
->local_label
= lde_update_label(fn
);
2097 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2098 lde_send_labelmapping(ln
, fn
, 0);
2101 /* for this fec change any exp-null back to imp-null */
2102 if (fn
->local_label
== exp_label
) {
2103 fn
->local_label
= lde_update_label(fn
);
2104 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2105 lde_send_labelmapping(ln
, fn
, 0);
2109 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2110 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
2115 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2117 struct lde_addr
*new;
2119 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
2122 if ((new = calloc(1, sizeof(*new))) == NULL
)
2125 new->af
= lde_addr
->af
;
2126 new->addr
= lde_addr
->addr
;
2127 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
2129 /* reevaluate the previously received mappings from this neighbor */
2130 lde_nbr_addr_update(ln
, lde_addr
, 0);
2136 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2138 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
2139 if (lde_addr
== NULL
)
2142 /* reevaluate the previously received mappings from this neighbor */
2143 lde_nbr_addr_update(ln
, lde_addr
, 1);
2145 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
2152 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
2154 struct lde_addr
*lde_addr
;
2156 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
2157 if (lde_addr
->af
== af
&&
2158 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
2165 lde_address_list_free(struct lde_nbr
*ln
)
2167 struct lde_addr
*lde_addr
;
2169 while ((lde_addr
= TAILQ_POP_FIRST(&ln
->addr_list
, entry
)) != NULL
)
2174 * Event callback used to retry the label-manager sync zapi session.
2176 static int zclient_sync_retry(struct thread
*thread
)
2178 zclient_sync_init();
2184 * Initialize and open a synchronous zapi session. This is used by label chunk
2185 * management code, which acquires and releases blocks of labels from the
2186 * zebra label-manager module.
2188 static void zclient_sync_init(void)
2190 struct zclient_options options
= zclient_options_default
;
2192 options
.synchronous
= true;
2194 /* Initialize special zclient for synchronous message exchanges. */
2195 zclient_sync
= zclient_new(master
, &options
, NULL
, 0);
2196 zclient_sync
->sock
= -1;
2197 zclient_sync
->redist_default
= ZEBRA_ROUTE_LDP
;
2198 zclient_sync
->session_id
= 1; /* Distinguish from main session */
2199 zclient_sync
->privs
= &lde_privs
;
2201 if (zclient_socket_connect(zclient_sync
) < 0) {
2202 log_warnx("Error connecting synchronous zclient!");
2205 /* make socket non-blocking */
2206 sock_set_nonblock(zclient_sync
->sock
);
2208 /* Send hello to notify zebra this is a synchronous client */
2209 if (zclient_send_hello(zclient_sync
) == ZCLIENT_SEND_FAILURE
) {
2210 log_warnx("Error sending hello for synchronous zclient!");
2214 /* Connect to label manager */
2215 if (lm_label_manager_connect(zclient_sync
, 0) != 0) {
2216 log_warnx("Error connecting to label manager!");
2220 /* Finish label-manager init once the LM session is running */
2221 lde_label_list_init();
2227 /* Discard failed zclient object */
2228 zclient_stop(zclient_sync
);
2229 zclient_free(zclient_sync
);
2230 zclient_sync
= NULL
;
2232 /* Retry using a timer */
2233 thread_add_timer(master
, zclient_sync_retry
, NULL
, 1, NULL
);
2237 lde_del_label_chunk(void *val
)
2243 lde_release_label_chunk(uint32_t start
, uint32_t end
)
2247 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
2249 log_warnx("Error releasing label chunk!");
2256 lde_get_label_chunk(void)
2259 uint32_t start
, end
;
2261 debug_labels("getting label chunk (size %u)", CHUNK_SIZE
);
2262 ret
= lm_get_label_chunk(zclient_sync
, 0, MPLS_LABEL_BASE_ANY
,
2263 CHUNK_SIZE
, &start
, &end
);
2265 log_warnx("Error getting label chunk!");
2269 on_get_label_chunk_response(start
, end
);
2275 lde_label_list_init(void)
2277 label_chunk_list
= list_new();
2278 label_chunk_list
->del
= lde_del_label_chunk
;
2280 /* get first chunk */
2281 while (lde_get_label_chunk () != 0) {
2282 log_warnx("Error getting first label chunk!");
2288 on_get_label_chunk_response(uint32_t start
, uint32_t end
)
2290 struct label_chunk
*new_label_chunk
;
2292 debug_labels("label chunk assign: %u - %u", start
, end
);
2294 new_label_chunk
= calloc(1, sizeof(struct label_chunk
));
2295 if (!new_label_chunk
) {
2296 log_warn("Error trying to allocate label chunk %u - %u", start
, end
);
2300 new_label_chunk
->start
= start
;
2301 new_label_chunk
->end
= end
;
2302 new_label_chunk
->used_mask
= 0;
2304 listnode_add(label_chunk_list
, (void *)new_label_chunk
);
2306 /* let's update current if needed */
2307 if (!current_label_chunk
)
2308 current_label_chunk
= listtail(label_chunk_list
);
2312 lde_free_label(uint32_t label
)
2314 struct listnode
*node
;
2315 struct label_chunk
*label_chunk
;
2318 for (ALL_LIST_ELEMENTS_RO(label_chunk_list
, node
, label_chunk
)) {
2319 if (label
<= label_chunk
->end
&& label
>= label_chunk
->start
) {
2320 pos
= 1ULL << (label
- label_chunk
->start
);
2321 label_chunk
->used_mask
&= ~pos
;
2322 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
2323 if (!label_chunk
->used_mask
&& (current_label_chunk
!= node
)) {
2324 if (lde_release_label_chunk(label_chunk
->start
, label_chunk
->end
) != 0)
2325 log_warnx("%s: Error releasing label chunk!", __func__
);
2327 listnode_delete(label_chunk_list
, label_chunk
);
2328 lde_del_label_chunk(label_chunk
);
2338 lde_get_next_label(void)
2340 struct label_chunk
*label_chunk
;
2343 uint32_t label
= NO_LABEL
;
2345 while (current_label_chunk
) {
2346 label_chunk
= listgetdata(current_label_chunk
);
2350 /* try to get next free label in currently used label chunk */
2351 size
= label_chunk
->end
- label_chunk
->start
+ 1;
2352 for (i
= 0, pos
= 1; i
< size
; i
++, pos
<<= 1) {
2353 if (!(pos
& label_chunk
->used_mask
)) {
2354 label_chunk
->used_mask
|= pos
;
2355 label
= label_chunk
->start
+ i
;
2359 current_label_chunk
= listnextnode(current_label_chunk
);
2363 /* we moved till the last chunk, or were not able to find a label,
2364 so let's ask for another one */
2365 if (!current_label_chunk
||
2366 current_label_chunk
== listtail(label_chunk_list
) ||
2367 label
== NO_LABEL
) {
2368 if (lde_get_label_chunk() != 0)
2369 log_warn("%s: Error getting label chunk!", __func__
);
2377 lde_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
2378 const char *filter_name
)
2380 if (strcmp(af_conf
->acl_label_allocate_for
, filter_name
) == 0)
2381 lde_change_allocate_filter(af
);
2382 if ((strcmp(af_conf
->acl_label_advertise_to
, filter_name
) == 0)
2383 || (strcmp(af_conf
->acl_label_advertise_for
, filter_name
) == 0))
2384 lde_change_advertise_filter(af
);
2385 if ((strcmp(af_conf
->acl_label_accept_for
, filter_name
) == 0)
2386 || (strcmp(af_conf
->acl_label_accept_from
, filter_name
) == 0))
2387 lde_change_accept_filter(af
);
2388 if (strcmp(af_conf
->acl_label_expnull_for
, filter_name
) == 0)
2389 lde_change_expnull_for_filter(af
);
2392 void lde_route_update(struct iface
*iface
, int af
)
2395 struct fec_node
*fn
;
2399 /* update label of non-connected routes */
2400 log_debug("update labels for interface %s", iface
->name
);
2401 RB_FOREACH(f
, fec_tree
, &ft
) {
2402 fn
= (struct fec_node
*)f
;
2403 if (IS_MPLS_UNRESERVED_LABEL(fn
->local_label
))
2408 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2412 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2416 /* unspecified so process both address families */
2420 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2422 * If connected leave existing label. If LDP
2423 * configured on interface or a static route
2424 * may need new label. If no LDP configured
2425 * treat fec as a connected route
2427 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2430 if (fnh
->ifindex
!= iface
->ifindex
)
2433 fnh
->flags
&= ~F_FEC_NH_NO_LDP
;
2434 if (IS_MPLS_RESERVED_LABEL(fn
->local_label
)) {
2435 fn
->local_label
= NO_LABEL
;
2436 fn
->local_label
= lde_update_label(fn
);
2437 if (fn
->local_label
!= NO_LABEL
)
2438 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2439 lde_send_labelmapping(
2445 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2446 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2450 void lde_route_update_release(struct iface
*iface
, int af
)
2454 struct fec_node
*fn
;
2457 /* update label of interfaces no longer running LDP */
2458 log_debug("release all labels for interface %s af %s", iface
->name
,
2459 af
== AF_INET
? "ipv4" : "ipv6");
2460 RB_FOREACH(f
, fec_tree
, &ft
) {
2461 fn
= (struct fec_node
*)f
;
2465 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2469 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2473 fatalx("lde_route_update_release: unknown af");
2476 if (fn
->local_label
== NO_LABEL
)
2479 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2481 * If connected leave existing label. If LDP
2482 * removed from interface may need new label
2483 * and would be treated as a connected route
2485 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2488 if (fnh
->ifindex
!= iface
->ifindex
)
2491 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2492 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2493 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2494 lde_free_label(fn
->local_label
);
2495 fn
->local_label
= NO_LABEL
;
2496 fn
->local_label
= lde_update_label(fn
);
2497 if (fn
->local_label
!= NO_LABEL
)
2498 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2499 lde_send_labelmapping(ln
, fn
, 0);
2503 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2504 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2508 void lde_route_update_release_all(int af
)
2512 struct fec_node
*fn
;
2515 /* remove labels from all interfaces as LDP is no longer running for
2516 * this address family
2518 log_debug("release all labels for address family %s",
2519 af
== AF_INET
? "ipv4" : "ipv6");
2520 RB_FOREACH(f
, fec_tree
, &ft
) {
2521 fn
= (struct fec_node
*)f
;
2524 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2528 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2532 fatalx("lde_route_update_release: unknown af");
2535 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2536 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2538 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2539 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2540 lde_send_delete_klabel(fn
, fnh
);