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 void lde_dispatch_imsg(struct thread
*thread
);
45 static void lde_dispatch_parent(struct thread
*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
,
246 static void lde_dispatch_imsg(struct thread
*thread
)
248 struct imsgev
*iev
= THREAD_ARG(thread
);
249 struct imsgbuf
*ibuf
= &iev
->ibuf
;
253 struct lde_addr
*lde_addr
;
254 struct notify_msg
*nm
;
260 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
261 fatal("imsg_read error");
262 if (n
== 0) /* connection closed */
266 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
267 fatal("lde_dispatch_imsg: imsg_get error");
271 switch (imsg
.hdr
.type
) {
272 case IMSG_LABEL_MAPPING_FULL
:
273 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
275 log_debug("%s: cannot find lde neighbor",
282 case IMSG_LABEL_MAPPING
:
283 case IMSG_LABEL_REQUEST
:
284 case IMSG_LABEL_RELEASE
:
285 case IMSG_LABEL_WITHDRAW
:
286 case IMSG_LABEL_ABORT
:
287 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
289 fatalx("lde_dispatch_imsg: wrong imsg len");
292 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
294 log_debug("%s: cannot find lde neighbor",
299 switch (imsg
.hdr
.type
) {
300 case IMSG_LABEL_MAPPING
:
301 lde_check_mapping(map
, ln
, 1);
303 case IMSG_LABEL_REQUEST
:
304 lde_check_request(map
, ln
);
306 case IMSG_LABEL_RELEASE
:
307 lde_check_release(map
, ln
);
309 case IMSG_LABEL_WITHDRAW
:
310 lde_check_withdraw(map
, ln
);
312 case IMSG_LABEL_ABORT
:
317 case IMSG_ADDRESS_ADD
:
318 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
319 sizeof(struct lde_addr
))
320 fatalx("lde_dispatch_imsg: wrong imsg len");
321 lde_addr
= imsg
.data
;
323 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
325 log_debug("%s: cannot find lde neighbor",
329 if (lde_address_add(ln
, lde_addr
) < 0) {
330 log_debug("%s: cannot add address %s, it already exists", __func__
,
331 log_addr(lde_addr
->af
, &lde_addr
->addr
));
334 case IMSG_ADDRESS_DEL
:
335 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
336 sizeof(struct lde_addr
))
337 fatalx("lde_dispatch_imsg: wrong imsg len");
338 lde_addr
= imsg
.data
;
340 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
342 log_debug("%s: cannot find lde neighbor",
346 if (lde_address_del(ln
, lde_addr
) < 0) {
347 log_debug("%s: cannot delete address %s, it does not exist", __func__
,
348 log_addr(lde_addr
->af
, &lde_addr
->addr
));
351 case IMSG_NOTIFICATION
:
352 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
353 sizeof(struct notify_msg
))
354 fatalx("lde_dispatch_imsg: wrong imsg len");
357 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
359 log_debug("%s: cannot find lde neighbor",
364 switch (nm
->status_code
) {
366 l2vpn_recv_pw_status(ln
, nm
);
370 * Do nothing for now. Should be useful in
371 * the future when we implement LDP-IGP
372 * Synchronization (RFC 5443) and Graceful
373 * Restart (RFC 3478).
379 case IMSG_NEIGHBOR_UP
:
380 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
381 sizeof(struct lde_nbr
))
382 fatalx("lde_dispatch_imsg: wrong imsg len");
384 if (lde_nbr_find(imsg
.hdr
.peerid
))
385 fatalx("lde_dispatch_imsg: neighbor already exists");
386 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
388 case IMSG_NEIGHBOR_DOWN
:
389 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
391 case IMSG_CTL_SHOW_LIB
:
392 rt_dump(imsg
.hdr
.pid
);
394 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
395 imsg
.hdr
.pid
, NULL
, 0);
397 case IMSG_CTL_SHOW_L2VPN_PW
:
398 l2vpn_pw_ctl(imsg
.hdr
.pid
);
400 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
401 imsg
.hdr
.pid
, NULL
, 0);
403 case IMSG_CTL_SHOW_L2VPN_BINDING
:
404 l2vpn_binding_ctl(imsg
.hdr
.pid
);
406 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
407 imsg
.hdr
.pid
, NULL
, 0);
410 log_debug("%s: unexpected imsg %d", __func__
,
419 /* this pipe is dead, so remove the event handlers and exit */
420 thread_cancel(&iev
->ev_read
);
421 thread_cancel(&iev
->ev_write
);
427 static void lde_dispatch_parent(struct thread
*thread
)
429 static struct ldpd_conf
*nconf
;
430 struct iface
*iface
, *niface
;
432 struct nbr_params
*nnbrp
;
433 static struct l2vpn
*l2vpn
, *nl2vpn
;
434 struct l2vpn_if
*lif
, *nlif
;
435 struct l2vpn_pw
*pw
, *npw
;
440 struct imsgev
*iev
= THREAD_ARG(thread
);
441 struct imsgbuf
*ibuf
= &iev
->ibuf
;
445 struct ldp_access
*laccess
;
446 struct ldp_rlfa_node
*rnode
, *rntmp
;
447 struct ldp_rlfa_client
*rclient
;
448 struct zapi_rlfa_request
*rlfa_req
;
449 struct zapi_rlfa_igp
*rlfa_igp
;
453 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
454 fatal("imsg_read error");
455 if (n
== 0) /* connection closed */
459 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
460 fatal("lde_dispatch_parent: imsg_get error");
464 switch (imsg
.hdr
.type
) {
466 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
468 fatalx("IFSTATUS imsg with wrong len");
471 iface
= if_lookup_name(ldeconf
, kif
->ifname
);
473 if_update_info(iface
, kif
);
475 /* if up see if any labels need to be updated */
477 lde_route_update(iface
, AF_UNSPEC
);
481 RB_FOREACH(l2vpn
, l2vpn_head
, &ldeconf
->l2vpn_tree
) {
482 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
484 l2vpn_if_update_info(lif
, kif
);
487 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
489 l2vpn_pw_update_info(pw
, kif
);
495 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
496 sizeof(struct zapi_pw_status
))
497 fatalx("PW_UPDATE imsg with wrong len");
499 if (l2vpn_pw_status_update(imsg
.data
) != 0)
500 log_warnx("%s: error updating PW status",
503 case IMSG_NETWORK_ADD
:
504 case IMSG_NETWORK_UPDATE
:
505 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
506 sizeof(struct kroute
)) {
507 log_warnx("%s: wrong imsg len", __func__
);
514 fec
.type
= FEC_TYPE_IPV4
;
515 fec
.u
.ipv4
.prefix
= kr
->prefix
.v4
;
516 fec
.u
.ipv4
.prefixlen
= kr
->prefixlen
;
519 fec
.type
= FEC_TYPE_IPV6
;
520 fec
.u
.ipv6
.prefix
= kr
->prefix
.v6
;
521 fec
.u
.ipv6
.prefixlen
= kr
->prefixlen
;
524 fatalx("lde_dispatch_parent: unknown af");
527 switch (imsg
.hdr
.type
) {
528 case IMSG_NETWORK_ADD
:
529 lde_kernel_insert(&fec
, kr
->af
, &kr
->nexthop
,
530 kr
->ifindex
, kr
->route_type
,
532 kr
->flags
& F_CONNECTED
, NULL
);
534 case IMSG_NETWORK_UPDATE
:
535 lde_kernel_update(&fec
);
539 case IMSG_SOCKET_IPC
:
541 log_warnx("%s: received unexpected imsg fd to ldpe", __func__
);
544 if ((fd
= imsg
.fd
) == -1) {
545 log_warnx("%s: expected to receive imsg fd to ldpe but didn't receive any", __func__
);
549 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
551 imsg_init(&iev_ldpe
->ibuf
, fd
);
552 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
553 thread_add_read(master
, iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
,
555 iev_ldpe
->handler_write
= ldp_write_handler
;
556 iev_ldpe
->ev_write
= NULL
;
559 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
560 sizeof(struct ldpd_init
))
561 fatalx("INIT imsg with wrong len");
563 memcpy(&init
, imsg
.data
, sizeof(init
));
566 case IMSG_AGENTX_ENABLED
:
567 ldp_agentx_enabled();
569 case IMSG_RECONF_CONF
:
570 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
573 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
575 RB_INIT(iface_head
, &nconf
->iface_tree
);
576 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
577 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
578 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
580 case IMSG_RECONF_IFACE
:
581 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
583 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
585 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
587 case IMSG_RECONF_TNBR
:
588 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
590 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
592 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
594 case IMSG_RECONF_NBRP
:
595 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
597 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
599 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
601 case IMSG_RECONF_L2VPN
:
602 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
604 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
606 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
607 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
608 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
610 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
612 case IMSG_RECONF_L2VPN_IF
:
613 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
615 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
617 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
619 case IMSG_RECONF_L2VPN_PW
:
620 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
622 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
624 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
626 case IMSG_RECONF_L2VPN_IPW
:
627 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
629 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
631 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
633 case IMSG_RECONF_END
:
634 merge_config(ldeconf
, nconf
);
635 ldp_clear_config(nconf
);
638 case IMSG_DEBUG_UPDATE
:
639 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
641 log_warnx("%s: wrong imsg len", __func__
);
644 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
646 case IMSG_FILTER_UPDATE
:
647 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
648 sizeof(struct ldp_access
)) {
649 log_warnx("%s: wrong imsg len", __func__
);
653 lde_check_filter_af(AF_INET
, &ldeconf
->ipv4
,
655 lde_check_filter_af(AF_INET6
, &ldeconf
->ipv6
,
659 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
660 sizeof(struct zapi_rlfa_request
)) {
661 log_warnx("%s: wrong imsg len", __func__
);
664 rlfa_req
= imsg
.data
;
665 rnode
= rlfa_node_find(&rlfa_req
->destination
,
666 rlfa_req
->pq_address
);
668 rnode
= rlfa_node_new(&rlfa_req
->destination
,
669 rlfa_req
->pq_address
);
670 rclient
= rlfa_client_find(rnode
, &rlfa_req
->igp
);
672 /* RLFA already registered - do nothing */
674 rclient
= rlfa_client_new(rnode
, &rlfa_req
->igp
);
675 lde_rlfa_check(rclient
);
677 case IMSG_RLFA_UNREG_ALL
:
678 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
679 sizeof(struct zapi_rlfa_igp
)) {
680 log_warnx("%s: wrong imsg len", __func__
);
683 rlfa_igp
= imsg
.data
;
685 RB_FOREACH_SAFE (rnode
, ldp_rlfa_node_head
,
686 &rlfa_node_tree
, rntmp
) {
687 rclient
= rlfa_client_find(rnode
, rlfa_igp
);
691 rlfa_client_del(rclient
);
695 log_debug("%s: unexpected imsg %d", __func__
,
704 /* this pipe is dead, so remove the event handlers and exit */
705 thread_cancel(&iev
->ev_read
);
706 thread_cancel(&iev
->ev_write
);
712 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
714 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
717 static bool lde_fec_connected(const struct fec_node
*fn
)
721 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
722 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
728 static bool lde_fec_outside_mpls_network(const struct fec_node
*fn
)
732 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
733 if (!(fnh
->flags
& F_FEC_NH_NO_LDP
))
740 lde_update_label(struct fec_node
*fn
)
743 /* should we allocate a label for this fec? */
744 switch (fn
->fec
.type
) {
746 if ((ldeconf
->ipv4
.flags
& F_LDPD_AF_ALLOCHOSTONLY
)
747 && fn
->fec
.u
.ipv4
.prefixlen
!= IPV4_MAX_BITLEN
)
749 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
750 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
751 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
755 if ((ldeconf
->ipv6
.flags
& F_LDPD_AF_ALLOCHOSTONLY
)
756 && fn
->fec
.u
.ipv6
.prefixlen
!= IPV6_MAX_BITLEN
)
758 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
759 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
760 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
768 * If connected interface act as egress for fec.
769 * If LDP is not configured on an interface but there
770 * are other NHs with interfaces configured with LDP
771 * then don't act as an egress for the fec, otherwise
772 * act as an egress for the fec
774 if (lde_fec_connected(fn
) || lde_fec_outside_mpls_network(fn
)) {
775 /* choose implicit or explicit-null depending on configuration */
776 switch (fn
->fec
.type
) {
778 if (!(ldeconf
->ipv4
.flags
& F_LDPD_AF_EXPNULL
))
779 return (MPLS_LABEL_IMPLICIT_NULL
);
780 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
781 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
782 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
783 return (MPLS_LABEL_IMPLICIT_NULL
);
784 return MPLS_LABEL_IPV4_EXPLICIT_NULL
;
786 if (!(ldeconf
->ipv6
.flags
& F_LDPD_AF_EXPNULL
))
787 return (MPLS_LABEL_IMPLICIT_NULL
);
788 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
789 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
790 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
791 return (MPLS_LABEL_IMPLICIT_NULL
);
792 return MPLS_LABEL_IPV6_EXPLICIT_NULL
;
798 /* preserve current label if there's no need to update it */
799 if (fn
->local_label
!= NO_LABEL
&&
800 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
801 return (fn
->local_label
);
803 return (lde_get_next_label());
807 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
814 * Ordered Control: don't program label into HW until a
815 * labelmap msg has been received from upstream router
817 if (fnh
->flags
& F_FEC_NH_DEFER
)
820 switch (fn
->fec
.type
) {
822 memset(&kr
, 0, sizeof(kr
));
824 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
825 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
826 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
827 kr
.ifindex
= fnh
->ifindex
;
828 kr
.local_label
= fn
->local_label
;
829 kr
.remote_label
= fnh
->remote_label
;
830 kr
.route_type
= fnh
->route_type
;
831 kr
.route_instance
= fnh
->route_instance
;
832 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
836 memset(&kr
, 0, sizeof(kr
));
838 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
839 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
840 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
841 kr
.ifindex
= fnh
->ifindex
;
842 kr
.local_label
= fn
->local_label
;
843 kr
.remote_label
= fnh
->remote_label
;
844 kr
.route_type
= fnh
->route_type
;
845 kr
.route_instance
= fnh
->route_instance
;
847 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
851 pw
= (struct l2vpn_pw
*) fn
->data
;
852 if (!pw
|| fn
->local_label
== NO_LABEL
||
853 fnh
->remote_label
== NO_LABEL
)
858 zpw
.local_label
= fn
->local_label
;
859 zpw
.remote_label
= fnh
->remote_label
;
860 lde_imsg_compose_parent(IMSG_KPW_SET
, 0, &zpw
, sizeof(zpw
));
866 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
872 switch (fn
->fec
.type
) {
874 memset(&kr
, 0, sizeof(kr
));
876 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
877 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
878 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
879 kr
.ifindex
= fnh
->ifindex
;
880 kr
.local_label
= fn
->local_label
;
881 kr
.remote_label
= fnh
->remote_label
;
882 kr
.route_type
= fnh
->route_type
;
883 kr
.route_instance
= fnh
->route_instance
;
885 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
889 memset(&kr
, 0, sizeof(kr
));
891 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
892 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
893 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
894 kr
.ifindex
= fnh
->ifindex
;
895 kr
.local_label
= fn
->local_label
;
896 kr
.remote_label
= fnh
->remote_label
;
897 kr
.route_type
= fnh
->route_type
;
898 kr
.route_instance
= fnh
->route_instance
;
900 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
904 pw
= (struct l2vpn_pw
*) fn
->data
;
910 zpw
.local_label
= fn
->local_label
;
911 zpw
.remote_label
= fnh
->remote_label
;
912 lde_imsg_compose_parent(IMSG_KPW_UNSET
, 0, &zpw
, sizeof(zpw
));
918 lde_fec2prefix(const struct fec
*fec
, struct prefix
*prefix
)
920 memset(prefix
, 0, sizeof(*prefix
));
923 prefix
->family
= AF_INET
;
924 prefix
->u
.prefix4
= fec
->u
.ipv4
.prefix
;
925 prefix
->prefixlen
= fec
->u
.ipv4
.prefixlen
;
928 prefix
->family
= AF_INET6
;
929 prefix
->u
.prefix6
= fec
->u
.ipv6
.prefix
;
930 prefix
->prefixlen
= fec
->u
.ipv6
.prefixlen
;
933 prefix
->family
= AF_UNSPEC
;
939 lde_prefix2fec(const struct prefix
*prefix
, struct fec
*fec
)
941 memset(fec
, 0, sizeof(*fec
));
942 switch (prefix
->family
) {
944 fec
->type
= FEC_TYPE_IPV4
;
945 fec
->u
.ipv4
.prefix
= prefix
->u
.prefix4
;
946 fec
->u
.ipv4
.prefixlen
= prefix
->prefixlen
;
949 fec
->type
= FEC_TYPE_IPV6
;
950 fec
->u
.ipv6
.prefix
= prefix
->u
.prefix6
;
951 fec
->u
.ipv6
.prefixlen
= prefix
->prefixlen
;
954 fatalx("lde_prefix2fec: unknown af");
960 lde_fec2map(struct fec
*fec
, struct map
*map
)
962 memset(map
, 0, sizeof(*map
));
966 map
->type
= MAP_TYPE_PREFIX
;
967 map
->fec
.prefix
.af
= AF_INET
;
968 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
969 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
972 map
->type
= MAP_TYPE_PREFIX
;
973 map
->fec
.prefix
.af
= AF_INET6
;
974 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
975 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
978 map
->type
= MAP_TYPE_PWID
;
979 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
980 map
->fec
.pwid
.group_id
= 0;
981 map
->flags
|= F_MAP_PW_ID
;
982 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
988 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
990 memset(fec
, 0, sizeof(*fec
));
993 case MAP_TYPE_PREFIX
:
994 switch (map
->fec
.prefix
.af
) {
996 fec
->type
= FEC_TYPE_IPV4
;
997 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
998 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
1001 fec
->type
= FEC_TYPE_IPV6
;
1002 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
1003 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
1006 fatalx("lde_map2fec: unknown af");
1011 fec
->type
= FEC_TYPE_PWID
;
1012 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
1013 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
1014 fec
->u
.pwid
.lsr_id
= lsr_id
;
1020 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
1022 struct lde_wdraw
*lw
;
1024 struct lde_req
*lre
;
1026 struct l2vpn_pw
*pw
;
1031 * Ordered Control: do not send a labelmap msg until
1032 * a labelmap message is received from downstream router
1033 * and don't send labelmap back to downstream router
1035 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
1036 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1037 if (fnh
->flags
& F_FEC_NH_DEFER
)
1040 if (lde_address_find(ln
, fnh
->af
, &fnh
->nexthop
))
1050 * We shouldn't send a new label mapping if we have a pending
1051 * label release to receive. In this case, schedule to send a
1052 * label mapping as soon as a label release is received.
1054 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1056 if (!fec_find(&ln
->sent_map_pending
, &fn
->fec
)) {
1057 debug_evt("%s: FEC %s: scheduling to send label mapping later (waiting for pending label release)",
1058 __func__
, log_fec(&fn
->fec
));
1059 lde_map_pending_add(ln
, fn
);
1065 * This function skips SL.1 - 3 and SL.9 - 14 because the label
1066 * allocation is done way earlier (because of the merging nature of
1070 lde_fec2map(&fn
->fec
, &map
);
1071 switch (fn
->fec
.type
) {
1073 if (!ln
->v4_enabled
)
1075 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
1076 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1078 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
1079 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
1080 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
1084 if (!ln
->v6_enabled
)
1086 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
1087 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1089 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
1090 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
1091 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
1095 pw
= (struct l2vpn_pw
*) fn
->data
;
1096 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1097 /* not the remote end of the pseudowire */
1100 map
.flags
|= F_MAP_PW_IFMTU
;
1101 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
1102 if (pw
->flags
& F_PW_CWORD
)
1103 map
.flags
|= F_MAP_PW_CWORD
;
1104 if (pw
->flags
& F_PW_STATUSTLV
) {
1105 map
.flags
|= F_MAP_PW_STATUS
;
1106 map
.pw_status
= pw
->local_status
;
1110 map
.label
= fn
->local_label
;
1112 /* SL.6: is there a pending request for this mapping? */
1113 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
1115 /* set label request msg id in the mapping response. */
1116 map
.requestid
= lre
->msg_id
;
1117 map
.flags
= F_MAP_REQ_ID
;
1119 /* SL.7: delete record of pending request */
1120 lde_req_del(ln
, lre
, 0);
1123 /* SL.4: send label mapping */
1124 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
1127 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1130 /* SL.5: record sent label mapping */
1131 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1133 me
= lde_map_add(ln
, fn
, 1);
1138 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
,
1139 struct map
*wcard
, struct status_tlv
*st
)
1141 struct lde_wdraw
*lw
;
1144 struct l2vpn_pw
*pw
;
1147 lde_fec2map(&fn
->fec
, &map
);
1148 switch (fn
->fec
.type
) {
1150 if (!ln
->v4_enabled
)
1154 if (!ln
->v6_enabled
)
1158 pw
= (struct l2vpn_pw
*) fn
->data
;
1159 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1160 /* not the remote end of the pseudowire */
1163 if (pw
->flags
& F_PW_CWORD
)
1164 map
.flags
|= F_MAP_PW_CWORD
;
1167 map
.label
= fn
->local_label
;
1169 memcpy(&map
, wcard
, sizeof(map
));
1172 map
.st
.status_code
= st
->status_code
;
1173 map
.st
.msg_id
= st
->msg_id
;
1174 map
.st
.msg_type
= st
->msg_type
;
1175 map
.flags
|= F_MAP_STATUS
;
1178 /* SWd.1: send label withdraw. */
1179 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
1181 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1183 /* SWd.2: record label withdraw. */
1185 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1187 lw
= lde_wdraw_add(ln
, fn
);
1188 lw
->label
= map
.label
;
1192 RB_FOREACH(f
, fec_tree
, &ft
) {
1193 fn
= (struct fec_node
*)f
;
1194 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1195 if (lde_wildcard_apply(wcard
, &fn
->fec
, me
) == 0)
1198 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
1201 lw
= lde_wdraw_add(ln
, fn
);
1202 lw
->label
= map
.label
;
1208 lde_send_labelwithdraw_wcard(struct lde_nbr
*ln
, uint32_t label
)
1212 memset(&wcard
, 0, sizeof(wcard
));
1213 wcard
.type
= MAP_TYPE_WILDCARD
;
1214 wcard
.label
= label
;
1215 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1219 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr
*ln
, uint16_t af
,
1224 memset(&wcard
, 0, sizeof(wcard
));
1225 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1226 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1227 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1228 wcard
.label
= label
;
1229 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1233 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr
*ln
, uint16_t pw_type
,
1238 memset(&wcard
, 0, sizeof(wcard
));
1239 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1240 wcard
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1241 wcard
.fec
.twcard
.u
.pw_type
= pw_type
;
1242 wcard
.label
= label
;
1243 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1247 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr
*ln
, uint16_t pw_type
,
1252 memset(&wcard
, 0, sizeof(wcard
));
1253 wcard
.type
= MAP_TYPE_PWID
;
1254 wcard
.fec
.pwid
.type
= pw_type
;
1255 wcard
.fec
.pwid
.group_id
= group_id
;
1256 /* we can not append a Label TLV when using PWid group wildcards. */
1257 wcard
.label
= NO_LABEL
;
1258 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1262 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
,
1263 struct map
*wcard
, uint32_t label
)
1266 struct l2vpn_pw
*pw
;
1269 lde_fec2map(&fn
->fec
, &map
);
1270 switch (fn
->fec
.type
) {
1272 if (!ln
->v4_enabled
)
1276 if (!ln
->v6_enabled
)
1280 pw
= (struct l2vpn_pw
*) fn
->data
;
1281 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1282 /* not the remote end of the pseudowire */
1285 if (pw
->flags
& F_PW_CWORD
)
1286 map
.flags
|= F_MAP_PW_CWORD
;
1290 memcpy(&map
, wcard
, sizeof(map
));
1293 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1295 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1299 lde_send_labelrequest(struct lde_nbr
*ln
, struct fec_node
*fn
,
1300 struct map
*wcard
, int single
)
1304 struct lde_req
*lre
;
1307 lde_fec2map(&fn
->fec
, &map
);
1308 switch (fn
->fec
.type
) {
1310 if (!ln
->v4_enabled
)
1314 if (!ln
->v6_enabled
)
1318 fatalx("lde_send_labelrequest: unknown af");
1321 memcpy(&map
, wcard
, sizeof(map
));
1323 map
.label
= NO_LABEL
;
1326 /* SLR1.1: has label request for FEC been previously sent
1327 * and still outstanding just return,
1329 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1331 /* SLRq.3: send label request */
1332 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
, ln
->peerid
, 0,
1335 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1336 ln
->peerid
, 0, NULL
, 0);
1338 /* SLRq.4: record sent request */
1339 lde_req_add(ln
, &fn
->fec
, 1);
1342 /* if Wilcard just send label request */
1343 /* SLRq.3: send label request */
1344 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
,
1345 ln
->peerid
, 0, &map
, sizeof(map
));
1347 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1348 ln
->peerid
, 0, NULL
, 0);
1350 /* SLRq.4: record sent request */
1351 RB_FOREACH(f
, fec_tree
, &ft
) {
1352 fn
= (struct fec_node
*)f
;
1353 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1354 if (lde_wildcard_apply(wcard
, &fn
->fec
, NULL
) == 0)
1357 lde_req_add(ln
, f
, 1);
1363 lde_send_labelrequest_wcard(struct lde_nbr
*ln
, uint16_t af
)
1367 memset(&wcard
, 0, sizeof(wcard
));
1368 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1369 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1370 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1371 lde_send_labelrequest(ln
, NULL
, &wcard
, 1);
1375 lde_send_notification(struct lde_nbr
*ln
, uint32_t status_code
, uint32_t msg_id
,
1378 struct notify_msg nm
;
1380 memset(&nm
, 0, sizeof(nm
));
1381 nm
.status_code
= status_code
;
1382 /* 'msg_id' and 'msg_type' should be in network byte order */
1384 nm
.msg_type
= msg_type
;
1386 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1391 lde_send_notification_eol_prefix(struct lde_nbr
*ln
, int af
)
1393 struct notify_msg nm
;
1395 memset(&nm
, 0, sizeof(nm
));
1396 nm
.status_code
= S_ENDOFLIB
;
1397 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1398 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1399 nm
.fec
.fec
.twcard
.u
.prefix_af
= af
;
1400 nm
.flags
|= F_NOTIF_FEC
;
1402 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1407 lde_send_notification_eol_pwid(struct lde_nbr
*ln
, uint16_t pw_type
)
1409 struct notify_msg nm
;
1411 memset(&nm
, 0, sizeof(nm
));
1412 nm
.status_code
= S_ENDOFLIB
;
1413 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1414 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1415 nm
.fec
.fec
.twcard
.u
.pw_type
= pw_type
;
1416 nm
.flags
|= F_NOTIF_FEC
;
1418 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1423 lde_nbr_compare(const struct lde_nbr
*a
, const struct lde_nbr
*b
)
1425 return (a
->peerid
- b
->peerid
);
1428 static struct lde_nbr
*
1429 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1433 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1437 ln
->v4_enabled
= new->v4_enabled
;
1438 ln
->v6_enabled
= new->v6_enabled
;
1439 ln
->flags
= new->flags
;
1440 ln
->peerid
= peerid
;
1441 fec_init(&ln
->recv_map
);
1442 fec_init(&ln
->sent_map
);
1443 fec_init(&ln
->sent_map_pending
);
1444 fec_init(&ln
->recv_req
);
1445 fec_init(&ln
->sent_req
);
1446 fec_init(&ln
->sent_wdraw
);
1448 TAILQ_INIT(&ln
->addr_list
);
1450 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1451 fatalx("lde_nbr_new: RB_INSERT failed");
1457 lde_nbr_del(struct lde_nbr
*ln
)
1460 struct fec_node
*fn
;
1462 struct l2vpn_pw
*pw
;
1463 struct lde_nbr
*lnbr
;
1468 /* uninstall received mappings */
1469 RB_FOREACH(f
, fec_tree
, &ft
) {
1470 fn
= (struct fec_node
*)f
;
1472 /* Update RLFA clients. */
1473 lde_rlfa_update_clients(f
, ln
, MPLS_INVALID_LABEL
);
1475 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1479 if (!lde_address_find(ln
, fnh
->af
,
1484 * Ordered Control: must mark any non-connected
1485 * NH to wait until we receive a labelmap msg
1486 * before installing in kernel and sending to
1487 * peer, must do this as NHs are not removed
1488 * when lsps go down. Also send label withdraw
1489 * to other neighbors for all fecs from neighbor
1492 if (ldeconf
->flags
& F_LDPD_ORDERED_CONTROL
) {
1493 fnh
->flags
|= F_FEC_NH_DEFER
;
1495 RB_FOREACH(lnbr
, nbr_tree
, &lde_nbrs
) {
1496 if (ln
->peerid
== lnbr
->peerid
)
1498 lde_send_labelwithdraw(lnbr
, fn
, NULL
, NULL
);
1503 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1505 pw
= (struct l2vpn_pw
*) fn
->data
;
1507 pw
->reason
= F_PW_NO_REMOTE_LABEL
;
1515 lde_send_delete_klabel(fn
, fnh
);
1516 fnh
->remote_label
= NO_LABEL
;
1520 lde_address_list_free(ln
);
1522 fec_clear(&ln
->recv_map
, lde_map_free
);
1523 fec_clear(&ln
->sent_map
, lde_map_free
);
1524 fec_clear(&ln
->sent_map_pending
, free
);
1525 fec_clear(&ln
->recv_req
, free
);
1526 fec_clear(&ln
->sent_req
, free
);
1527 fec_clear(&ln
->sent_wdraw
, free
);
1529 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1534 static struct lde_nbr
*
1535 lde_nbr_find(uint32_t peerid
)
1541 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1545 lde_nbr_find_by_lsrid(struct in_addr addr
)
1549 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1550 if (ln
->id
.s_addr
== addr
.s_addr
)
1557 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1561 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1562 if (lde_address_find(ln
, af
, addr
) != NULL
)
1573 while (!RB_EMPTY(nbr_tree
, &lde_nbrs
)) {
1574 ln
= RB_ROOT(nbr_tree
, &lde_nbrs
);
1581 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1584 struct fec_node
*fn
;
1588 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1589 switch (fec
->type
) {
1591 if (lde_addr
->af
!= AF_INET
)
1595 if (lde_addr
->af
!= AF_INET6
)
1602 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1604 /* shouldn't happen */
1607 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1608 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1613 lde_send_delete_klabel(fn
, fnh
);
1614 fnh
->remote_label
= NO_LABEL
;
1616 me
= (struct lde_map
*)fec
;
1617 fnh
->remote_label
= me
->map
.label
;
1618 lde_send_change_klabel(fn
, fnh
);
1626 lde_allow_broken_lsp_update(int new_config
)
1628 struct fec_node
*fn
;
1632 RB_FOREACH(f
, fec_tree
, &ft
) {
1633 fn
= (struct fec_node
*)f
;
1635 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1636 /* allow-broken-lsp config is changing so
1637 * we need to reprogram labeled routes to
1638 * have proper top-level label
1640 if (!(new_config
& F_LDPD_ALLOW_BROKEN_LSP
))
1641 lde_send_delete_klabel(fn
, fnh
);
1643 if (fn
->local_label
!= NO_LABEL
)
1644 lde_send_change_klabel(fn
, fnh
);
1650 lde_map_compare(const struct lde_map
*a
, const struct lde_map
*b
)
1652 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1653 (union ldpd_addr
*)&b
->nexthop
->id
));
1657 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1661 me
= calloc(1, sizeof(*me
));
1669 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1670 me
->head
= &fn
->upstream
;
1671 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1672 log_warnx("failed to add %s to sent map",
1674 /* XXX on failure more cleanup is needed */
1676 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1677 me
->head
= &fn
->downstream
;
1678 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1679 log_warnx("failed to add %s to recv map",
1687 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1690 fec_remove(&ln
->sent_map
, &me
->fec
);
1692 fec_remove(&ln
->recv_map
, &me
->fec
);
1698 lde_map_free(void *ptr
)
1700 struct lde_map
*map
= ptr
;
1702 RB_REMOVE(lde_map_head
, map
->head
, map
);
1707 lde_map_pending_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1711 map
= calloc(1, sizeof(*map
));
1716 if (fec_insert(&ln
->sent_map_pending
, map
))
1717 log_warnx("failed to add %s to sent map (pending)",
1724 lde_map_pending_del(struct lde_nbr
*ln
, struct fec
*map
)
1726 fec_remove(&ln
->sent_map_pending
, map
);
1731 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1734 struct lde_req
*lre
;
1736 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1738 lre
= calloc(1, sizeof(*lre
));
1742 if (fec_insert(t
, &lre
->fec
)) {
1743 log_warnx("failed to add %s to %s req",
1744 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1754 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1757 fec_remove(&ln
->sent_req
, &lre
->fec
);
1759 fec_remove(&ln
->recv_req
, &lre
->fec
);
1765 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1767 struct lde_wdraw
*lw
;
1769 lw
= calloc(1, sizeof(*lw
));
1775 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1776 log_warnx("failed to add %s to sent wdraw",
1783 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1785 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1790 lde_change_egress_label(int af
)
1794 struct fec_node
*fn
;
1796 /* explicitly withdraw all null labels */
1797 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1798 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IMPLICIT_NULL
);
1800 lde_send_labelwithdraw_wcard(
1802 MPLS_LABEL_IPV4_EXPLICIT_NULL
);
1804 lde_send_labelwithdraw_wcard(
1806 MPLS_LABEL_IPV6_EXPLICIT_NULL
);
1809 /* update label of connected routes */
1810 RB_FOREACH(f
, fec_tree
, &ft
) {
1811 fn
= (struct fec_node
*)f
;
1812 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1817 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1821 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1825 fatalx("lde_change_egress_label: unknown af");
1828 fn
->local_label
= lde_update_label(fn
);
1829 if (fn
->local_label
!= NO_LABEL
)
1830 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1831 lde_send_labelmapping(ln
, fn
, 0);
1833 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1834 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1839 lde_change_allocate_filter(int af
)
1843 struct fec_node
*fn
;
1846 /* reallocate labels for fecs that match this filter */
1847 RB_FOREACH(f
, fec_tree
, &ft
) {
1848 fn
= (struct fec_node
*)f
;
1852 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1856 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1860 fatalx("lde_change_allocate_filter: unknown af");
1864 * If the local label has changed to NO_LABEL, send a label
1865 * withdraw to all peers.
1866 * If the local label has changed and it's different from
1867 * NO_LABEL, send a label mapping to all peers advertising
1869 * If the local label hasn't changed, do nothing
1871 new_label
= lde_update_label(fn
);
1872 if (fn
->local_label
!= new_label
) {
1873 if (new_label
== NO_LABEL
)
1874 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1875 lde_send_labelwithdraw(ln
, fn
,
1878 fn
->local_label
= new_label
;
1879 if (fn
->local_label
!= NO_LABEL
)
1880 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1881 lde_send_labelmapping(ln
, fn
, 0);
1884 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1885 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1890 lde_change_advertise_filter(int af
)
1894 struct fec_node
*fn
;
1895 char *acl_to_filter
;
1896 char *acl_for_filter
;
1897 union ldpd_addr
*prefix
;
1901 /* advertise label for fecs to neighbors if matches advertise filters */
1904 acl_to_filter
= ldeconf
->ipv4
.acl_label_advertise_to
;
1905 acl_for_filter
= ldeconf
->ipv4
.acl_label_advertise_for
;
1908 acl_to_filter
= ldeconf
->ipv6
.acl_label_advertise_to
;
1909 acl_for_filter
= ldeconf
->ipv6
.acl_label_advertise_for
;
1912 fatalx("lde_change_advertise_filter: unknown af");
1915 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1916 if (lde_acl_check(acl_to_filter
, af
, (union ldpd_addr
*)&ln
->id
,
1917 IPV4_MAX_BITLEN
) != FILTER_PERMIT
)
1918 lde_send_labelwithdraw_wcard(ln
, NO_LABEL
);
1920 /* This neighbor is allowed in to_filter, so
1921 * send labels if fec also matches for_filter
1923 RB_FOREACH(f
, fec_tree
, &ft
) {
1924 fn
= (struct fec_node
*)f
;
1927 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1929 prefix
= (union ldpd_addr
*)
1930 &fn
->fec
.u
.ipv4
.prefix
;
1931 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1934 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1936 prefix
= (union ldpd_addr
*)
1937 &fn
->fec
.u
.ipv6
.prefix
;
1938 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1943 if (lde_acl_check(acl_for_filter
, af
,
1944 prefix
, plen
) != FILTER_PERMIT
) {
1945 me
= (struct lde_map
*)fec_find(
1946 &ln
->sent_map
, &fn
->fec
);
1948 /* fec filtered withdraw */
1949 lde_send_labelwithdraw(ln
, fn
,
1952 /* fec allowed send map */
1953 lde_send_labelmapping(ln
, fn
, 0);
1955 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
,
1956 ln
->peerid
, 0, NULL
, 0);
1963 lde_change_accept_filter(int af
)
1967 struct fec_node
*fn
;
1968 char *acl_for_filter
;
1969 char *acl_from_filter
;
1970 union ldpd_addr
*prefix
;
1975 /* accept labels from neighbors specified in the from_filter and for
1976 * fecs defined in the for_filter
1980 acl_for_filter
= ldeconf
->ipv4
.acl_label_accept_for
;
1981 acl_from_filter
= ldeconf
->ipv4
.acl_label_accept_from
;
1982 type
= FEC_TYPE_IPV4
;
1985 acl_for_filter
= ldeconf
->ipv6
.acl_label_accept_for
;
1986 acl_from_filter
= ldeconf
->ipv6
.acl_label_accept_from
;
1987 type
= FEC_TYPE_IPV6
;
1990 fatalx("lde_change_accept_filter: unknown af");
1993 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1994 if (lde_acl_check(acl_from_filter
, AF_INET
, (union ldpd_addr
*)
1995 &ln
->id
, IPV4_MAX_BITLEN
) != FILTER_PERMIT
) {
1996 /* This neighbor is now filtered so remove fecs from
1999 RB_FOREACH(f
, fec_tree
, &ft
) {
2000 fn
= (struct fec_node
*)f
;
2001 if (fn
->fec
.type
== type
) {
2002 me
= (struct lde_map
*)fec_find(
2003 &ln
->recv_map
, &fn
->fec
);
2005 lde_map_del(ln
, me
, 0);
2008 } else if (ln
->flags
& F_NBR_CAP_TWCARD
) {
2009 /* This neighbor is allowed and supports type
2010 * wildcard so send a labelrequest
2011 * to get any new labels from neighbor
2012 * and make sure any fecs we currently have
2015 RB_FOREACH(f
, fec_tree
, &ft
) {
2016 fn
= (struct fec_node
*)f
;
2019 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2021 prefix
= (union ldpd_addr
*)
2022 &fn
->fec
.u
.ipv4
.prefix
;
2023 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
2026 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2028 prefix
= (union ldpd_addr
*)
2029 &fn
->fec
.u
.ipv6
.prefix
;
2030 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
2035 if (lde_acl_check(acl_for_filter
, af
,
2036 prefix
, plen
) != FILTER_PERMIT
) {
2037 me
= (struct lde_map
*)fec_find(
2038 &ln
->recv_map
, &fn
->fec
);
2040 lde_map_del(ln
, me
, 0);
2043 lde_send_labelrequest_wcard(ln
, af
);
2045 /* Type Wildcard is not supported so restart session */
2046 lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN
, ln
->peerid
, 0,
2052 lde_change_expnull_for_filter(int af
)
2056 struct fec_node
*fn
;
2059 union ldpd_addr
*prefix
;
2062 /* Configure explicit-null advertisement for all fecs in this filter */
2063 RB_FOREACH(f
, fec_tree
, &ft
) {
2064 fn
= (struct fec_node
*)f
;
2068 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2070 acl_name
= ldeconf
->ipv4
.acl_label_expnull_for
;
2071 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
2072 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
2073 exp_label
= MPLS_LABEL_IPV4_EXPLICIT_NULL
;
2076 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2078 acl_name
= ldeconf
->ipv6
.acl_label_expnull_for
;
2079 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
2080 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
2081 exp_label
= MPLS_LABEL_IPV6_EXPLICIT_NULL
;
2084 fatalx("lde_change_expnull_for_filter: unknown af");
2087 if (lde_acl_check(acl_name
, af
, prefix
, plen
) == FILTER_PERMIT
) {
2088 /* for this fec change any imp-null to exp-null */
2089 if (fn
->local_label
== MPLS_LABEL_IMPLICIT_NULL
) {
2090 fn
->local_label
= lde_update_label(fn
);
2091 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2092 lde_send_labelmapping(ln
, fn
, 0);
2095 /* for this fec change any exp-null back to imp-null */
2096 if (fn
->local_label
== exp_label
) {
2097 fn
->local_label
= lde_update_label(fn
);
2098 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2099 lde_send_labelmapping(ln
, fn
, 0);
2103 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2104 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
2109 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2111 struct lde_addr
*new;
2113 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
2116 if ((new = calloc(1, sizeof(*new))) == NULL
)
2119 new->af
= lde_addr
->af
;
2120 new->addr
= lde_addr
->addr
;
2121 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
2123 /* reevaluate the previously received mappings from this neighbor */
2124 lde_nbr_addr_update(ln
, lde_addr
, 0);
2130 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2132 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
2133 if (lde_addr
== NULL
)
2136 /* reevaluate the previously received mappings from this neighbor */
2137 lde_nbr_addr_update(ln
, lde_addr
, 1);
2139 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
2146 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
2148 struct lde_addr
*lde_addr
;
2150 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
2151 if (lde_addr
->af
== af
&&
2152 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
2159 lde_address_list_free(struct lde_nbr
*ln
)
2161 struct lde_addr
*lde_addr
;
2163 while ((lde_addr
= TAILQ_POP_FIRST(&ln
->addr_list
, entry
)) != NULL
)
2168 * Event callback used to retry the label-manager sync zapi session.
2170 static void zclient_sync_retry(struct thread
*thread
)
2172 zclient_sync_init();
2176 * Initialize and open a synchronous zapi session. This is used by label chunk
2177 * management code, which acquires and releases blocks of labels from the
2178 * zebra label-manager module.
2180 static void zclient_sync_init(void)
2182 struct zclient_options options
= zclient_options_default
;
2184 options
.synchronous
= true;
2186 /* Initialize special zclient for synchronous message exchanges. */
2187 zclient_sync
= zclient_new(master
, &options
, NULL
, 0);
2188 zclient_sync
->sock
= -1;
2189 zclient_sync
->redist_default
= ZEBRA_ROUTE_LDP
;
2190 zclient_sync
->session_id
= 1; /* Distinguish from main session */
2191 zclient_sync
->privs
= &lde_privs
;
2193 if (zclient_socket_connect(zclient_sync
) < 0) {
2194 log_warnx("Error connecting synchronous zclient!");
2197 /* make socket non-blocking */
2198 sock_set_nonblock(zclient_sync
->sock
);
2200 /* Send hello to notify zebra this is a synchronous client */
2201 if (zclient_send_hello(zclient_sync
) == ZCLIENT_SEND_FAILURE
) {
2202 log_warnx("Error sending hello for synchronous zclient!");
2206 /* Connect to label manager */
2207 if (lm_label_manager_connect(zclient_sync
, 0) != 0) {
2208 log_warnx("Error connecting to label manager!");
2212 /* Finish label-manager init once the LM session is running */
2213 lde_label_list_init();
2219 /* Discard failed zclient object */
2220 zclient_stop(zclient_sync
);
2221 zclient_free(zclient_sync
);
2222 zclient_sync
= NULL
;
2224 /* Retry using a timer */
2225 thread_add_timer(master
, zclient_sync_retry
, NULL
, 1, NULL
);
2229 lde_del_label_chunk(void *val
)
2235 lde_release_label_chunk(uint32_t start
, uint32_t end
)
2239 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
2241 log_warnx("Error releasing label chunk!");
2248 lde_get_label_chunk(void)
2251 uint32_t start
, end
;
2253 debug_labels("getting label chunk (size %u)", CHUNK_SIZE
);
2254 ret
= lm_get_label_chunk(zclient_sync
, 0, MPLS_LABEL_BASE_ANY
,
2255 CHUNK_SIZE
, &start
, &end
);
2257 log_warnx("Error getting label chunk!");
2261 on_get_label_chunk_response(start
, end
);
2267 lde_label_list_init(void)
2269 label_chunk_list
= list_new();
2270 label_chunk_list
->del
= lde_del_label_chunk
;
2272 /* get first chunk */
2273 while (lde_get_label_chunk () != 0) {
2274 log_warnx("Error getting first label chunk!");
2280 on_get_label_chunk_response(uint32_t start
, uint32_t end
)
2282 struct label_chunk
*new_label_chunk
;
2284 debug_labels("label chunk assign: %u - %u", start
, end
);
2286 new_label_chunk
= calloc(1, sizeof(struct label_chunk
));
2287 if (!new_label_chunk
) {
2288 log_warn("Error trying to allocate label chunk %u - %u", start
, end
);
2292 new_label_chunk
->start
= start
;
2293 new_label_chunk
->end
= end
;
2294 new_label_chunk
->used_mask
= 0;
2296 listnode_add(label_chunk_list
, (void *)new_label_chunk
);
2298 /* let's update current if needed */
2299 if (!current_label_chunk
)
2300 current_label_chunk
= listtail(label_chunk_list
);
2304 lde_free_label(uint32_t label
)
2306 struct listnode
*node
;
2307 struct label_chunk
*label_chunk
;
2310 for (ALL_LIST_ELEMENTS_RO(label_chunk_list
, node
, label_chunk
)) {
2311 if (label
<= label_chunk
->end
&& label
>= label_chunk
->start
) {
2312 pos
= 1ULL << (label
- label_chunk
->start
);
2313 label_chunk
->used_mask
&= ~pos
;
2314 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
2315 if (!label_chunk
->used_mask
&& (current_label_chunk
!= node
)) {
2316 if (lde_release_label_chunk(label_chunk
->start
, label_chunk
->end
) != 0)
2317 log_warnx("%s: Error releasing label chunk!", __func__
);
2319 listnode_delete(label_chunk_list
, label_chunk
);
2320 lde_del_label_chunk(label_chunk
);
2330 lde_get_next_label(void)
2332 struct label_chunk
*label_chunk
;
2335 uint32_t label
= NO_LABEL
;
2337 while (current_label_chunk
) {
2338 label_chunk
= listgetdata(current_label_chunk
);
2342 /* try to get next free label in currently used label chunk */
2343 size
= label_chunk
->end
- label_chunk
->start
+ 1;
2344 for (i
= 0, pos
= 1; i
< size
; i
++, pos
<<= 1) {
2345 if (!(pos
& label_chunk
->used_mask
)) {
2346 label_chunk
->used_mask
|= pos
;
2347 label
= label_chunk
->start
+ i
;
2351 current_label_chunk
= listnextnode(current_label_chunk
);
2355 /* we moved till the last chunk, or were not able to find a label,
2356 so let's ask for another one */
2357 if (!current_label_chunk
||
2358 current_label_chunk
== listtail(label_chunk_list
) ||
2359 label
== NO_LABEL
) {
2360 if (lde_get_label_chunk() != 0)
2361 log_warn("%s: Error getting label chunk!", __func__
);
2369 lde_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
2370 const char *filter_name
)
2372 if (strcmp(af_conf
->acl_label_allocate_for
, filter_name
) == 0)
2373 lde_change_allocate_filter(af
);
2374 if ((strcmp(af_conf
->acl_label_advertise_to
, filter_name
) == 0)
2375 || (strcmp(af_conf
->acl_label_advertise_for
, filter_name
) == 0))
2376 lde_change_advertise_filter(af
);
2377 if ((strcmp(af_conf
->acl_label_accept_for
, filter_name
) == 0)
2378 || (strcmp(af_conf
->acl_label_accept_from
, filter_name
) == 0))
2379 lde_change_accept_filter(af
);
2380 if (strcmp(af_conf
->acl_label_expnull_for
, filter_name
) == 0)
2381 lde_change_expnull_for_filter(af
);
2384 void lde_route_update(struct iface
*iface
, int af
)
2387 struct fec_node
*fn
;
2391 /* update label of non-connected routes */
2392 log_debug("update labels for interface %s", iface
->name
);
2393 RB_FOREACH(f
, fec_tree
, &ft
) {
2394 fn
= (struct fec_node
*)f
;
2395 if (IS_MPLS_UNRESERVED_LABEL(fn
->local_label
))
2400 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2404 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2408 /* unspecified so process both address families */
2412 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2414 * If connected leave existing label. If LDP
2415 * configured on interface or a static route
2416 * may need new label. If no LDP configured
2417 * treat fec as a connected route
2419 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2422 if (fnh
->ifindex
!= iface
->ifindex
)
2425 fnh
->flags
&= ~F_FEC_NH_NO_LDP
;
2426 if (IS_MPLS_RESERVED_LABEL(fn
->local_label
)) {
2427 fn
->local_label
= NO_LABEL
;
2428 fn
->local_label
= lde_update_label(fn
);
2429 if (fn
->local_label
!= NO_LABEL
)
2430 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2431 lde_send_labelmapping(
2437 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2438 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2442 void lde_route_update_release(struct iface
*iface
, int af
)
2446 struct fec_node
*fn
;
2449 /* update label of interfaces no longer running LDP */
2450 log_debug("release all labels for interface %s af %s", iface
->name
,
2451 af
== AF_INET
? "ipv4" : "ipv6");
2452 RB_FOREACH(f
, fec_tree
, &ft
) {
2453 fn
= (struct fec_node
*)f
;
2457 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2461 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2465 fatalx("lde_route_update_release: unknown af");
2468 if (fn
->local_label
== NO_LABEL
)
2471 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2473 * If connected leave existing label. If LDP
2474 * removed from interface may need new label
2475 * and would be treated as a connected route
2477 if (fnh
->flags
& F_FEC_NH_CONNECTED
)
2480 if (fnh
->ifindex
!= iface
->ifindex
)
2483 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2484 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2485 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2486 lde_free_label(fn
->local_label
);
2487 fn
->local_label
= NO_LABEL
;
2488 fn
->local_label
= lde_update_label(fn
);
2489 if (fn
->local_label
!= NO_LABEL
)
2490 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2491 lde_send_labelmapping(ln
, fn
, 0);
2495 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2496 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2500 void lde_route_update_release_all(int af
)
2504 struct fec_node
*fn
;
2507 /* remove labels from all interfaces as LDP is no longer running for
2508 * this address family
2510 log_debug("release all labels for address family %s",
2511 af
== AF_INET
? "ipv4" : "ipv6");
2512 RB_FOREACH(f
, fec_tree
, &ft
) {
2513 fn
= (struct fec_node
*)f
;
2516 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2520 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2524 fatalx("lde_route_update_release: unknown af");
2527 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2528 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2530 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2531 fnh
->flags
|= F_FEC_NH_NO_LDP
;
2532 lde_send_delete_klabel(fn
, fnh
);