1 // SPDX-License-Identifier: ISC
5 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
6 * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
7 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
8 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
18 #include "ldp_debug.h"
26 #include <lib/linklist.h>
32 static void lde_shutdown(void);
33 static void lde_dispatch_imsg(struct event
*thread
);
34 static void lde_dispatch_parent(struct event
*thread
);
35 static __inline
int lde_nbr_compare(const struct lde_nbr
*,
36 const struct lde_nbr
*);
37 static struct lde_nbr
*lde_nbr_new(uint32_t, struct lde_nbr
*);
38 static void lde_nbr_del(struct lde_nbr
*);
39 static struct lde_nbr
*lde_nbr_find(uint32_t);
40 static void lde_nbr_clear(void);
41 static void lde_nbr_addr_update(struct lde_nbr
*,
42 struct lde_addr
*, int);
43 static __inline
int lde_map_compare(const struct lde_map
*,
44 const struct lde_map
*);
45 static void lde_map_free(void *);
46 static int lde_address_add(struct lde_nbr
*, struct lde_addr
*);
47 static int lde_address_del(struct lde_nbr
*, struct lde_addr
*);
48 static void lde_address_list_free(struct lde_nbr
*);
49 static void zclient_sync_init(void);
50 static void lde_label_list_init(void);
51 static int lde_get_label_chunk(void);
52 static void on_get_label_chunk_response(uint32_t start
, uint32_t end
);
53 static uint32_t lde_get_next_label(void);
54 static bool lde_fec_connected(const struct fec_node
*);
55 static bool lde_fec_outside_mpls_network(const struct fec_node
*);
56 static void lde_check_filter_af(int, struct ldpd_af_conf
*,
59 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
60 RB_GENERATE(lde_map_head
, lde_map
, entry
, lde_map_compare
)
62 struct ldpd_conf
*ldeconf
;
63 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
65 static struct imsgev
*iev_ldpe
;
66 static struct imsgev iev_main_sync_data
;
67 static struct imsgev
*iev_main
, *iev_main_sync
;
70 static zebra_capabilities_t _caps_p
[] =
75 static struct zebra_privs_t lde_privs
=
77 #if defined(VTY_GROUP)
78 .vty_group
= VTY_GROUP
,
81 .cap_num_p
= array_size(_caps_p
),
85 /* List of chunks of labels externally assigned by Zebra */
86 static struct list
*label_chunk_list
;
87 static struct listnode
*current_label_chunk
;
89 /* Synchronous zclient to request labels */
90 static struct zclient
*zclient_sync
;
92 /* SIGINT / SIGTERM handler. */
99 static struct frr_signal_t lde_signals
[] =
115 /* label decision engine */
119 #ifdef HAVE_SETPROCTITLE
120 setproctitle("label decision engine");
122 ldpd_process
= PROC_LDE_ENGINE
;
123 log_procname
= log_procnames
[PROC_LDE_ENGINE
];
126 /* no frr_config_fork() here, allow frr_pthread to create threads */
127 frr_is_after_fork
= true;
129 /* setup signal handler */
130 signal_init(master
, array_size(lde_signals
), lde_signals
);
132 /* setup pipes and event handlers to the parent process */
133 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
135 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
136 iev_main
->handler_read
= lde_dispatch_parent
;
137 event_add_read(master
, iev_main
->handler_read
, iev_main
,
138 iev_main
->ibuf
.fd
, &iev_main
->ev_read
);
139 iev_main
->handler_write
= ldp_write_handler
;
141 memset(&iev_main_sync_data
, 0, sizeof(iev_main_sync_data
));
142 iev_main_sync
= &iev_main_sync_data
;
143 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
145 /* create base configuration */
146 ldeconf
= config_new_empty();
149 while (event_fetch(master
, &thread
))
157 lde_init(struct ldpd_init
*init
)
159 /* drop privileges */
160 lde_privs
.user
= init
->user
;
161 lde_privs
.group
= init
->group
;
162 zprivs_preinit(&lde_privs
);
163 zprivs_init(&lde_privs
);
165 /* start the LIB garbage collector */
166 lde_gc_start_timer();
168 /* Init synchronous zclient and label list */
169 frr_zclient_addr(&zclient_addr
, &zclient_addr_len
,
170 init
->zclient_serv_path
);
179 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
180 close(iev_ldpe
->ibuf
.fd
);
181 iev_ldpe
->ibuf
.fd
= -1;
183 msgbuf_clear(&iev_main
->ibuf
.w
);
184 close(iev_main
->ibuf
.fd
);
185 iev_main
->ibuf
.fd
= -1;
186 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
187 close(iev_main_sync
->ibuf
.fd
);
188 iev_main_sync
->ibuf
.fd
= -1;
194 config_clear(ldeconf
);
200 log_info("label decision engine exiting");
208 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
210 if (iev_main
->ibuf
.fd
== -1)
212 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
216 lde_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
218 if (iev_main_sync
->ibuf
.fd
== -1)
220 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
221 imsg_flush(&iev_main_sync
->ibuf
);
225 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
228 if (iev_ldpe
->ibuf
.fd
== -1)
230 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
235 static void lde_dispatch_imsg(struct event
*thread
)
237 struct imsgev
*iev
= EVENT_ARG(thread
);
238 struct imsgbuf
*ibuf
= &iev
->ibuf
;
242 struct lde_addr
*lde_addr
;
243 struct notify_msg
*nm
;
249 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
250 fatal("imsg_read error");
251 if (n
== 0) /* connection closed */
255 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
256 fatal("lde_dispatch_imsg: imsg_get error");
260 switch (imsg
.hdr
.type
) {
261 case IMSG_LABEL_MAPPING_FULL
:
262 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
264 log_debug("%s: cannot find lde neighbor", __func__
);
270 case IMSG_LABEL_MAPPING
:
271 case IMSG_LABEL_REQUEST
:
272 case IMSG_LABEL_RELEASE
:
273 case IMSG_LABEL_WITHDRAW
:
274 case IMSG_LABEL_ABORT
:
275 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct map
))
276 fatalx("lde_dispatch_imsg: wrong imsg len");
279 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
281 log_debug("%s: cannot find lde neighbor", __func__
);
285 switch (imsg
.hdr
.type
) {
286 case IMSG_LABEL_MAPPING
:
287 lde_check_mapping(map
, ln
, 1);
289 case IMSG_LABEL_REQUEST
:
290 lde_check_request(map
, ln
);
292 case IMSG_LABEL_RELEASE
:
293 lde_check_release(map
, ln
);
295 case IMSG_LABEL_WITHDRAW
:
296 lde_check_withdraw(map
, ln
);
298 case IMSG_LABEL_ABORT
:
303 case IMSG_ADDRESS_ADD
:
304 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct lde_addr
))
305 fatalx("lde_dispatch_imsg: wrong imsg len");
306 lde_addr
= imsg
.data
;
308 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
310 log_debug("%s: cannot find lde neighbor", __func__
);
314 if (lde_address_add(ln
, lde_addr
) < 0) {
315 log_debug("%s: cannot add address %s, it already exists", __func__
,
316 log_addr(lde_addr
->af
, &lde_addr
->addr
));
319 case IMSG_ADDRESS_DEL
:
320 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= 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", __func__
);
330 if (lde_address_del(ln
, lde_addr
) < 0) {
331 log_debug("%s: cannot delete address %s, it does not exist", __func__
,
332 log_addr(lde_addr
->af
, &lde_addr
->addr
));
335 case IMSG_NOTIFICATION
:
336 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct notify_msg
))
337 fatalx("lde_dispatch_imsg: wrong imsg len");
340 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
342 log_debug("%s: cannot find lde neighbor", __func__
);
346 switch (nm
->status_code
) {
348 l2vpn_recv_pw_status(ln
, nm
);
352 * Do nothing for now. Should be useful in
353 * the future when we implement LDP-IGP
354 * Synchronization (RFC 5443) and Graceful
355 * Restart (RFC 3478).
361 case IMSG_NEIGHBOR_UP
:
362 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct lde_nbr
))
363 fatalx("lde_dispatch_imsg: wrong imsg len");
365 if (lde_nbr_find(imsg
.hdr
.peerid
))
366 fatalx("lde_dispatch_imsg: neighbor already exists");
367 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
369 case IMSG_NEIGHBOR_DOWN
:
370 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
372 case IMSG_CTL_SHOW_LIB
:
373 rt_dump(imsg
.hdr
.pid
);
375 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
376 imsg
.hdr
.pid
, NULL
, 0);
378 case IMSG_CTL_SHOW_L2VPN_PW
:
379 l2vpn_pw_ctl(imsg
.hdr
.pid
);
381 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0, imsg
.hdr
.pid
, NULL
, 0);
383 case IMSG_CTL_SHOW_L2VPN_BINDING
:
384 l2vpn_binding_ctl(imsg
.hdr
.pid
);
386 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0, imsg
.hdr
.pid
, NULL
, 0);
389 log_debug("%s: unexpected imsg %d", __func__
, imsg
.hdr
.type
);
397 /* this pipe is dead, so remove the event handlers and exit */
398 EVENT_OFF(iev
->ev_read
);
399 EVENT_OFF(iev
->ev_write
);
405 static void lde_dispatch_parent(struct event
*thread
)
407 static struct ldpd_conf
*nconf
;
408 struct iface
*iface
, *niface
;
410 struct nbr_params
*nnbrp
;
411 static struct l2vpn
*l2vpn
, *nl2vpn
;
412 struct l2vpn_if
*lif
, *nlif
;
413 struct l2vpn_pw
*pw
, *npw
;
418 struct imsgev
*iev
= EVENT_ARG(thread
);
419 struct imsgbuf
*ibuf
= &iev
->ibuf
;
423 struct ldp_access
*laccess
;
424 struct ldp_rlfa_node
*rnode
, *rntmp
;
425 struct ldp_rlfa_client
*rclient
;
426 struct zapi_rlfa_request
*rlfa_req
;
427 struct zapi_rlfa_igp
*rlfa_igp
;
431 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
432 fatal("imsg_read error");
433 if (n
== 0) /* connection closed */
437 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
438 fatal("lde_dispatch_parent: imsg_get error");
442 switch (imsg
.hdr
.type
) {
444 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct kif
))
445 fatalx("IFSTATUS imsg with wrong len");
448 iface
= if_lookup_name(ldeconf
, kif
->ifname
);
450 if_update_info(iface
, kif
);
452 /* if up see if any labels need to be updated */
454 lde_route_update(iface
, AF_UNSPEC
);
458 RB_FOREACH(l2vpn
, l2vpn_head
, &ldeconf
->l2vpn_tree
) {
459 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
461 l2vpn_if_update_info(lif
, kif
);
464 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
466 l2vpn_pw_update_info(pw
, kif
);
472 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct zapi_pw_status
))
473 fatalx("PW_UPDATE imsg with wrong len");
475 if (l2vpn_pw_status_update(imsg
.data
) != 0)
476 log_warnx("%s: error updating PW status", __func__
);
478 case IMSG_NETWORK_ADD
:
479 case IMSG_NETWORK_UPDATE
:
480 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct kroute
)) {
481 log_warnx("%s: wrong imsg len", __func__
);
488 fec
.type
= FEC_TYPE_IPV4
;
489 fec
.u
.ipv4
.prefix
= kr
->prefix
.v4
;
490 fec
.u
.ipv4
.prefixlen
= kr
->prefixlen
;
493 fec
.type
= FEC_TYPE_IPV6
;
494 fec
.u
.ipv6
.prefix
= kr
->prefix
.v6
;
495 fec
.u
.ipv6
.prefixlen
= kr
->prefixlen
;
498 fatalx("lde_dispatch_parent: unknown af");
501 switch (imsg
.hdr
.type
) {
502 case IMSG_NETWORK_ADD
:
503 lde_kernel_insert(&fec
, kr
->af
, &kr
->nexthop
,
504 kr
->ifindex
, kr
->route_type
, kr
->route_instance
,
505 CHECK_FLAG(kr
->flags
, F_CONNECTED
), NULL
);
507 case IMSG_NETWORK_UPDATE
:
508 lde_kernel_update(&fec
);
512 case IMSG_SOCKET_IPC
:
514 log_warnx("%s: received unexpected imsg fd to ldpe", __func__
);
517 if ((fd
= imsg
.fd
) == -1) {
518 log_warnx("%s: expected to receive imsg fd to ldpe but didn't receive any", __func__
);
522 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
524 imsg_init(&iev_ldpe
->ibuf
, fd
);
525 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
526 event_add_read(master
, iev_ldpe
->handler_read
, iev_ldpe
,
527 iev_ldpe
->ibuf
.fd
, &iev_ldpe
->ev_read
);
528 iev_ldpe
->handler_write
= ldp_write_handler
;
529 iev_ldpe
->ev_write
= NULL
;
532 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
533 sizeof(struct ldpd_init
))
534 fatalx("INIT imsg with wrong len");
536 memcpy(&init
, imsg
.data
, sizeof(init
));
539 case IMSG_AGENTX_ENABLED
:
540 ldp_agentx_enabled();
542 case IMSG_RECONF_CONF
:
543 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) == NULL
)
545 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
547 RB_INIT(iface_head
, &nconf
->iface_tree
);
548 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
549 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
550 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
552 case IMSG_RECONF_IFACE
:
553 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
555 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
557 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
559 case IMSG_RECONF_TNBR
:
560 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
562 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
564 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
566 case IMSG_RECONF_NBRP
:
567 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
569 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
571 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
573 case IMSG_RECONF_L2VPN
:
574 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
576 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
578 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
579 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
580 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
582 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
584 case IMSG_RECONF_L2VPN_IF
:
585 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
587 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
589 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
591 case IMSG_RECONF_L2VPN_PW
:
592 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
594 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
596 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
598 case IMSG_RECONF_L2VPN_IPW
:
599 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
601 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
603 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
605 case IMSG_RECONF_END
:
606 merge_config(ldeconf
, nconf
);
607 ldp_clear_config(nconf
);
610 case IMSG_DEBUG_UPDATE
:
611 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
613 log_warnx("%s: wrong imsg len", __func__
);
616 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
618 case IMSG_FILTER_UPDATE
:
619 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
620 sizeof(struct ldp_access
)) {
621 log_warnx("%s: wrong imsg len", __func__
);
625 lde_check_filter_af(AF_INET
, &ldeconf
->ipv4
,
627 lde_check_filter_af(AF_INET6
, &ldeconf
->ipv6
,
631 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
632 sizeof(struct zapi_rlfa_request
)) {
633 log_warnx("%s: wrong imsg len", __func__
);
636 rlfa_req
= imsg
.data
;
637 rnode
= rlfa_node_find(&rlfa_req
->destination
,
638 rlfa_req
->pq_address
);
640 rnode
= rlfa_node_new(&rlfa_req
->destination
,
641 rlfa_req
->pq_address
);
642 rclient
= rlfa_client_find(rnode
, &rlfa_req
->igp
);
644 /* RLFA already registered - do nothing */
646 rclient
= rlfa_client_new(rnode
, &rlfa_req
->igp
);
647 lde_rlfa_check(rclient
);
649 case IMSG_RLFA_UNREG_ALL
:
650 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
651 sizeof(struct zapi_rlfa_igp
)) {
652 log_warnx("%s: wrong imsg len", __func__
);
655 rlfa_igp
= imsg
.data
;
657 RB_FOREACH_SAFE (rnode
, ldp_rlfa_node_head
,
658 &rlfa_node_tree
, rntmp
) {
659 rclient
= rlfa_client_find(rnode
, rlfa_igp
);
663 rlfa_client_del(rclient
);
667 log_debug("%s: unexpected imsg %d", __func__
, imsg
.hdr
.type
);
675 /* this pipe is dead, so remove the event handlers and exit */
676 EVENT_OFF(iev
->ev_read
);
677 EVENT_OFF(iev
->ev_write
);
683 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
685 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
688 static bool lde_fec_connected(const struct fec_node
*fn
)
692 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
693 if (CHECK_FLAG(fnh
->flags
, F_FEC_NH_CONNECTED
))
699 static bool lde_fec_outside_mpls_network(const struct fec_node
*fn
)
703 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
)
704 if (!CHECK_FLAG(fnh
->flags
, F_FEC_NH_NO_LDP
))
711 lde_update_label(struct fec_node
*fn
)
714 /* should we allocate a label for this fec? */
715 switch (fn
->fec
.type
) {
717 if (CHECK_FLAG(ldeconf
->ipv4
.flags
, F_LDPD_AF_ALLOCHOSTONLY
)
718 && fn
->fec
.u
.ipv4
.prefixlen
!= IPV4_MAX_BITLEN
)
721 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
722 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
723 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
727 if (CHECK_FLAG(ldeconf
->ipv6
.flags
, F_LDPD_AF_ALLOCHOSTONLY
)
728 && fn
->fec
.u
.ipv6
.prefixlen
!= IPV6_MAX_BITLEN
)
731 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
732 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
733 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
741 * If connected interface act as egress for fec.
742 * If LDP is not configured on an interface but there
743 * are other NHs with interfaces configured with LDP
744 * then don't act as an egress for the fec, otherwise
745 * act as an egress for the fec
747 if (lde_fec_connected(fn
) || lde_fec_outside_mpls_network(fn
)) {
748 /* choose implicit or explicit-null depending on configuration */
749 switch (fn
->fec
.type
) {
751 if (!CHECK_FLAG(ldeconf
->ipv4
.flags
, F_LDPD_AF_EXPNULL
))
752 return (MPLS_LABEL_IMPLICIT_NULL
);
754 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
755 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
756 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
757 return (MPLS_LABEL_IMPLICIT_NULL
);
758 return MPLS_LABEL_IPV4_EXPLICIT_NULL
;
760 if (!CHECK_FLAG(ldeconf
->ipv6
.flags
, F_LDPD_AF_EXPNULL
))
761 return (MPLS_LABEL_IMPLICIT_NULL
);
763 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
764 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
765 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
766 return (MPLS_LABEL_IMPLICIT_NULL
);
767 return MPLS_LABEL_IPV6_EXPLICIT_NULL
;
773 /* preserve current label if there's no need to update it */
774 if (fn
->local_label
!= NO_LABEL
&&
775 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
776 return (fn
->local_label
);
778 return (lde_get_next_label());
782 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
789 * Ordered Control: don't program label into HW until a
790 * labelmap msg has been received from upstream router
792 if (CHECK_FLAG(fnh
->flags
, F_FEC_NH_DEFER
))
795 switch (fn
->fec
.type
) {
797 memset(&kr
, 0, sizeof(kr
));
799 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
800 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
801 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
802 kr
.ifindex
= fnh
->ifindex
;
803 kr
.local_label
= fn
->local_label
;
804 kr
.remote_label
= fnh
->remote_label
;
805 kr
.route_type
= fnh
->route_type
;
806 kr
.route_instance
= fnh
->route_instance
;
807 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
, sizeof(kr
));
810 memset(&kr
, 0, sizeof(kr
));
812 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
813 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
814 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
815 kr
.ifindex
= fnh
->ifindex
;
816 kr
.local_label
= fn
->local_label
;
817 kr
.remote_label
= fnh
->remote_label
;
818 kr
.route_type
= fnh
->route_type
;
819 kr
.route_instance
= fnh
->route_instance
;
821 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
, sizeof(kr
));
824 pw
= (struct l2vpn_pw
*) fn
->data
;
825 if (!pw
|| fn
->local_label
== NO_LABEL
||
826 fnh
->remote_label
== NO_LABEL
)
831 zpw
.local_label
= fn
->local_label
;
832 zpw
.remote_label
= fnh
->remote_label
;
833 lde_imsg_compose_parent(IMSG_KPW_SET
, 0, &zpw
, sizeof(zpw
));
839 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
845 switch (fn
->fec
.type
) {
847 memset(&kr
, 0, sizeof(kr
));
849 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
850 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
851 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
852 kr
.ifindex
= fnh
->ifindex
;
853 kr
.local_label
= fn
->local_label
;
854 kr
.remote_label
= fnh
->remote_label
;
855 kr
.route_type
= fnh
->route_type
;
856 kr
.route_instance
= fnh
->route_instance
;
858 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
, sizeof(kr
));
861 memset(&kr
, 0, sizeof(kr
));
863 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
864 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
865 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
866 kr
.ifindex
= fnh
->ifindex
;
867 kr
.local_label
= fn
->local_label
;
868 kr
.remote_label
= fnh
->remote_label
;
869 kr
.route_type
= fnh
->route_type
;
870 kr
.route_instance
= fnh
->route_instance
;
872 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
, sizeof(kr
));
875 pw
= (struct l2vpn_pw
*) fn
->data
;
881 zpw
.local_label
= fn
->local_label
;
882 zpw
.remote_label
= fnh
->remote_label
;
883 lde_imsg_compose_parent(IMSG_KPW_UNSET
, 0, &zpw
, sizeof(zpw
));
889 lde_fec2prefix(const struct fec
*fec
, struct prefix
*prefix
)
891 memset(prefix
, 0, sizeof(*prefix
));
894 prefix
->family
= AF_INET
;
895 prefix
->u
.prefix4
= fec
->u
.ipv4
.prefix
;
896 prefix
->prefixlen
= fec
->u
.ipv4
.prefixlen
;
899 prefix
->family
= AF_INET6
;
900 prefix
->u
.prefix6
= fec
->u
.ipv6
.prefix
;
901 prefix
->prefixlen
= fec
->u
.ipv6
.prefixlen
;
904 prefix
->family
= AF_UNSPEC
;
910 lde_prefix2fec(const struct prefix
*prefix
, struct fec
*fec
)
912 memset(fec
, 0, sizeof(*fec
));
913 switch (prefix
->family
) {
915 fec
->type
= FEC_TYPE_IPV4
;
916 fec
->u
.ipv4
.prefix
= prefix
->u
.prefix4
;
917 fec
->u
.ipv4
.prefixlen
= prefix
->prefixlen
;
920 fec
->type
= FEC_TYPE_IPV6
;
921 fec
->u
.ipv6
.prefix
= prefix
->u
.prefix6
;
922 fec
->u
.ipv6
.prefixlen
= prefix
->prefixlen
;
925 fatalx("lde_prefix2fec: unknown af");
931 lde_fec2map(struct fec
*fec
, struct map
*map
)
933 memset(map
, 0, sizeof(*map
));
937 map
->type
= MAP_TYPE_PREFIX
;
938 map
->fec
.prefix
.af
= AF_INET
;
939 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
940 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
943 map
->type
= MAP_TYPE_PREFIX
;
944 map
->fec
.prefix
.af
= AF_INET6
;
945 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
946 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
949 map
->type
= MAP_TYPE_PWID
;
950 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
951 map
->fec
.pwid
.group_id
= 0;
952 SET_FLAG(map
->flags
, F_MAP_PW_ID
);
953 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
959 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
961 memset(fec
, 0, sizeof(*fec
));
964 case MAP_TYPE_PREFIX
:
965 switch (map
->fec
.prefix
.af
) {
967 fec
->type
= FEC_TYPE_IPV4
;
968 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
969 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
972 fec
->type
= FEC_TYPE_IPV6
;
973 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
974 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
977 fatalx("lde_map2fec: unknown af");
982 fec
->type
= FEC_TYPE_PWID
;
983 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
984 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
985 fec
->u
.pwid
.lsr_id
= lsr_id
;
991 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
993 struct lde_wdraw
*lw
;
1002 * Ordered Control: do not send a labelmap msg until
1003 * a labelmap message is received from downstream router
1004 * and don't send labelmap back to downstream router
1006 if (CHECK_FLAG(ldeconf
->flags
, F_LDPD_ORDERED_CONTROL
)) {
1007 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1008 if (CHECK_FLAG(fnh
->flags
, F_FEC_NH_DEFER
))
1011 if (lde_address_find(ln
, fnh
->af
, &fnh
->nexthop
))
1021 * We shouldn't send a new label mapping if we have a pending
1022 * label release to receive. In this case, schedule to send a
1023 * label mapping as soon as a label release is received.
1025 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1027 if (!fec_find(&ln
->sent_map_pending
, &fn
->fec
)) {
1028 debug_evt("%s: FEC %s: scheduling to send label mapping later (waiting for pending label release)",
1029 __func__
, log_fec(&fn
->fec
));
1030 lde_map_pending_add(ln
, fn
);
1036 * This function skips SL.1 - 3 and SL.9 - 14 because the label
1037 * allocation is done way earlier (because of the merging nature of
1041 lde_fec2map(&fn
->fec
, &map
);
1042 switch (fn
->fec
.type
) {
1044 if (!ln
->v4_enabled
)
1047 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
1048 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1051 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
1052 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
1053 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
1057 if (!ln
->v6_enabled
)
1060 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
1061 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
1064 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
1065 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
1066 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
1070 pw
= (struct l2vpn_pw
*) fn
->data
;
1071 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1072 /* not the remote end of the pseudowire */
1075 SET_FLAG(map
.flags
, F_MAP_PW_IFMTU
);
1076 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
1078 if (CHECK_FLAG(pw
->flags
, F_PW_CWORD
))
1079 SET_FLAG(map
.flags
, F_MAP_PW_CWORD
);
1081 if (CHECK_FLAG(pw
->flags
, F_PW_STATUSTLV
)) {
1082 SET_FLAG(map
.flags
, F_MAP_PW_STATUS
);
1083 map
.pw_status
= pw
->local_status
;
1087 map
.label
= fn
->local_label
;
1089 /* SL.6: is there a pending request for this mapping? */
1090 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
1092 /* set label request msg id in the mapping response. */
1093 map
.requestid
= lre
->msg_id
;
1094 map
.flags
= F_MAP_REQ_ID
;
1096 /* SL.7: delete record of pending request */
1097 lde_req_del(ln
, lre
, 0);
1100 /* SL.4: send label mapping */
1101 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
1104 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1107 /* SL.5: record sent label mapping */
1108 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1110 me
= lde_map_add(ln
, fn
, 1);
1115 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
,
1116 struct map
*wcard
, struct status_tlv
*st
)
1118 struct lde_wdraw
*lw
;
1121 struct l2vpn_pw
*pw
;
1124 lde_fec2map(&fn
->fec
, &map
);
1125 switch (fn
->fec
.type
) {
1127 if (!ln
->v4_enabled
)
1131 if (!ln
->v6_enabled
)
1135 pw
= (struct l2vpn_pw
*) fn
->data
;
1136 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1137 /* not the remote end of the pseudowire */
1140 if (CHECK_FLAG(pw
->flags
, F_PW_CWORD
))
1141 SET_FLAG(map
.flags
, F_MAP_PW_CWORD
);
1144 map
.label
= fn
->local_label
;
1146 memcpy(&map
, wcard
, sizeof(map
));
1149 map
.st
.status_code
= st
->status_code
;
1150 map
.st
.msg_id
= st
->msg_id
;
1151 map
.st
.msg_type
= st
->msg_type
;
1152 SET_FLAG(map
.flags
, F_MAP_STATUS
);
1155 /* SWd.1: send label withdraw. */
1156 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
1158 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1160 /* SWd.2: record label withdraw. */
1162 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1164 lw
= lde_wdraw_add(ln
, fn
);
1165 lw
->label
= map
.label
;
1169 RB_FOREACH(f
, fec_tree
, &ft
) {
1170 fn
= (struct fec_node
*)f
;
1171 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1172 if (lde_wildcard_apply(wcard
, &fn
->fec
, me
) == 0)
1175 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1177 lw
= lde_wdraw_add(ln
, fn
);
1179 lw
->label
= map
.label
;
1185 lde_send_labelwithdraw_wcard(struct lde_nbr
*ln
, uint32_t label
)
1189 memset(&wcard
, 0, sizeof(wcard
));
1190 wcard
.type
= MAP_TYPE_WILDCARD
;
1191 wcard
.label
= label
;
1192 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1196 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr
*ln
, uint16_t af
,
1201 memset(&wcard
, 0, sizeof(wcard
));
1202 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1203 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1204 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1205 wcard
.label
= label
;
1206 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1210 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr
*ln
, uint16_t pw_type
,
1215 memset(&wcard
, 0, sizeof(wcard
));
1216 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1217 wcard
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1218 wcard
.fec
.twcard
.u
.pw_type
= pw_type
;
1219 wcard
.label
= label
;
1220 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1224 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr
*ln
, uint16_t pw_type
,
1229 memset(&wcard
, 0, sizeof(wcard
));
1230 wcard
.type
= MAP_TYPE_PWID
;
1231 wcard
.fec
.pwid
.type
= pw_type
;
1232 wcard
.fec
.pwid
.group_id
= group_id
;
1233 /* we can not append a Label TLV when using PWid group wildcards. */
1234 wcard
.label
= NO_LABEL
;
1235 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1239 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
,
1240 struct map
*wcard
, uint32_t label
)
1243 struct l2vpn_pw
*pw
;
1246 lde_fec2map(&fn
->fec
, &map
);
1247 switch (fn
->fec
.type
) {
1249 if (!ln
->v4_enabled
)
1253 if (!ln
->v6_enabled
)
1257 pw
= (struct l2vpn_pw
*) fn
->data
;
1258 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1259 /* not the remote end of the pseudowire */
1262 if (CHECK_FLAG(pw
->flags
, F_PW_CWORD
))
1263 SET_FLAG(map
.flags
, F_MAP_PW_CWORD
);
1267 memcpy(&map
, wcard
, sizeof(map
));
1270 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1272 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1276 lde_send_labelrequest(struct lde_nbr
*ln
, struct fec_node
*fn
,
1277 struct map
*wcard
, int single
)
1281 struct lde_req
*lre
;
1284 lde_fec2map(&fn
->fec
, &map
);
1285 switch (fn
->fec
.type
) {
1287 if (!ln
->v4_enabled
)
1291 if (!ln
->v6_enabled
)
1295 fatalx("lde_send_labelrequest: unknown af");
1298 memcpy(&map
, wcard
, sizeof(map
));
1300 map
.label
= NO_LABEL
;
1303 /* SLR1.1: has label request for FEC been previously sent
1304 * and still outstanding just return,
1306 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1308 /* SLRq.3: send label request */
1309 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
, ln
->peerid
, 0,
1312 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
,
1313 ln
->peerid
, 0, NULL
, 0);
1315 /* SLRq.4: record sent request */
1316 lde_req_add(ln
, &fn
->fec
, 1);
1319 /* if Wilcard just send label request */
1320 /* SLRq.3: send label request */
1321 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD
,
1322 ln
->peerid
, 0, &map
, sizeof(map
));
1324 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1326 /* SLRq.4: record sent request */
1327 RB_FOREACH(f
, fec_tree
, &ft
) {
1328 fn
= (struct fec_node
*)f
;
1329 lre
= (struct lde_req
*)fec_find(&ln
->sent_req
, &fn
->fec
);
1330 if (lde_wildcard_apply(wcard
, &fn
->fec
, NULL
) == 0)
1333 lde_req_add(ln
, f
, 1);
1339 lde_send_labelrequest_wcard(struct lde_nbr
*ln
, uint16_t af
)
1343 memset(&wcard
, 0, sizeof(wcard
));
1344 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1345 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1346 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1347 lde_send_labelrequest(ln
, NULL
, &wcard
, 1);
1351 lde_send_notification(struct lde_nbr
*ln
, uint32_t status_code
, uint32_t msg_id
,
1354 struct notify_msg nm
;
1356 memset(&nm
, 0, sizeof(nm
));
1357 nm
.status_code
= status_code
;
1358 /* 'msg_id' and 'msg_type' should be in network byte order */
1360 nm
.msg_type
= msg_type
;
1362 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1367 lde_send_notification_eol_prefix(struct lde_nbr
*ln
, int af
)
1369 struct notify_msg nm
;
1371 memset(&nm
, 0, sizeof(nm
));
1372 nm
.status_code
= S_ENDOFLIB
;
1373 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1374 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1375 nm
.fec
.fec
.twcard
.u
.prefix_af
= af
;
1376 SET_FLAG(nm
.flags
, F_NOTIF_FEC
);
1378 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1383 lde_send_notification_eol_pwid(struct lde_nbr
*ln
, uint16_t pw_type
)
1385 struct notify_msg nm
;
1387 memset(&nm
, 0, sizeof(nm
));
1388 nm
.status_code
= S_ENDOFLIB
;
1389 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1390 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1391 nm
.fec
.fec
.twcard
.u
.pw_type
= pw_type
;
1392 SET_FLAG(nm
.flags
, F_NOTIF_FEC
);
1394 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1399 lde_nbr_compare(const struct lde_nbr
*a
, const struct lde_nbr
*b
)
1401 return (a
->peerid
- b
->peerid
);
1404 static struct lde_nbr
*
1405 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1409 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1413 ln
->v4_enabled
= new->v4_enabled
;
1414 ln
->v6_enabled
= new->v6_enabled
;
1415 ln
->flags
= new->flags
;
1416 ln
->peerid
= peerid
;
1417 fec_init(&ln
->recv_map
);
1418 fec_init(&ln
->sent_map
);
1419 fec_init(&ln
->sent_map_pending
);
1420 fec_init(&ln
->recv_req
);
1421 fec_init(&ln
->sent_req
);
1422 fec_init(&ln
->sent_wdraw
);
1424 TAILQ_INIT(&ln
->addr_list
);
1426 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1427 fatalx("lde_nbr_new: RB_INSERT failed");
1433 lde_nbr_del(struct lde_nbr
*ln
)
1436 struct fec_node
*fn
;
1438 struct l2vpn_pw
*pw
;
1439 struct lde_nbr
*lnbr
;
1444 /* uninstall received mappings */
1445 RB_FOREACH(f
, fec_tree
, &ft
) {
1446 fn
= (struct fec_node
*)f
;
1448 /* Update RLFA clients. */
1449 lde_rlfa_update_clients(f
, ln
, MPLS_INVALID_LABEL
);
1451 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1455 if (!lde_address_find(ln
, fnh
->af
, &fnh
->nexthop
))
1459 * Ordered Control: must mark any non-connected
1460 * NH to wait until we receive a labelmap msg
1461 * before installing in kernel and sending to
1462 * peer, must do this as NHs are not removed
1463 * when lsps go down. Also send label withdraw
1464 * to other neighbors for all fecs from neighbor
1467 if (CHECK_FLAG(ldeconf
->flags
, F_LDPD_ORDERED_CONTROL
)) {
1468 SET_FLAG(fnh
->flags
, F_FEC_NH_DEFER
);
1470 RB_FOREACH(lnbr
, nbr_tree
, &lde_nbrs
) {
1471 if (ln
->peerid
== lnbr
->peerid
)
1473 lde_send_labelwithdraw(lnbr
, fn
, NULL
, NULL
);
1478 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1480 pw
= (struct l2vpn_pw
*) fn
->data
;
1482 pw
->reason
= F_PW_NO_REMOTE_LABEL
;
1490 lde_send_delete_klabel(fn
, fnh
);
1491 fnh
->remote_label
= NO_LABEL
;
1495 lde_address_list_free(ln
);
1497 fec_clear(&ln
->recv_map
, lde_map_free
);
1498 fec_clear(&ln
->sent_map
, lde_map_free
);
1499 fec_clear(&ln
->sent_map_pending
, free
);
1500 fec_clear(&ln
->recv_req
, free
);
1501 fec_clear(&ln
->sent_req
, free
);
1502 fec_clear(&ln
->sent_wdraw
, free
);
1504 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1509 static struct lde_nbr
*
1510 lde_nbr_find(uint32_t peerid
)
1516 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1520 lde_nbr_find_by_lsrid(struct in_addr addr
)
1524 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1525 if (ln
->id
.s_addr
== addr
.s_addr
)
1532 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1536 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1537 if (lde_address_find(ln
, af
, addr
) != NULL
)
1548 while (!RB_EMPTY(nbr_tree
, &lde_nbrs
)) {
1549 ln
= RB_ROOT(nbr_tree
, &lde_nbrs
);
1556 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1559 struct fec_node
*fn
;
1563 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1564 switch (fec
->type
) {
1566 if (lde_addr
->af
!= AF_INET
)
1570 if (lde_addr
->af
!= AF_INET6
)
1577 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1579 /* shouldn't happen */
1582 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1583 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
, &lde_addr
->addr
))
1587 lde_send_delete_klabel(fn
, fnh
);
1588 fnh
->remote_label
= NO_LABEL
;
1590 me
= (struct lde_map
*)fec
;
1591 fnh
->remote_label
= me
->map
.label
;
1592 lde_send_change_klabel(fn
, fnh
);
1600 lde_allow_broken_lsp_update(int new_config
)
1602 struct fec_node
*fn
;
1606 RB_FOREACH(f
, fec_tree
, &ft
) {
1607 fn
= (struct fec_node
*)f
;
1609 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1610 /* allow-broken-lsp config is changing so
1611 * we need to reprogram labeled routes to
1612 * have proper top-level label
1614 if (!(new_config
& F_LDPD_ALLOW_BROKEN_LSP
))
1615 lde_send_delete_klabel(fn
, fnh
);
1617 if (fn
->local_label
!= NO_LABEL
)
1618 lde_send_change_klabel(fn
, fnh
);
1624 lde_map_compare(const struct lde_map
*a
, const struct lde_map
*b
)
1626 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1627 (union ldpd_addr
*)&b
->nexthop
->id
));
1631 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1635 me
= calloc(1, sizeof(*me
));
1643 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1644 me
->head
= &fn
->upstream
;
1645 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1646 log_warnx("failed to add %s to sent map", log_fec(&me
->fec
));
1647 /* XXX on failure more cleanup is needed */
1649 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1650 me
->head
= &fn
->downstream
;
1651 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1652 log_warnx("failed to add %s to recv map", log_fec(&me
->fec
));
1659 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1662 fec_remove(&ln
->sent_map
, &me
->fec
);
1664 fec_remove(&ln
->recv_map
, &me
->fec
);
1670 lde_map_free(void *ptr
)
1672 struct lde_map
*map
= ptr
;
1674 RB_REMOVE(lde_map_head
, map
->head
, map
);
1679 lde_map_pending_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1683 map
= calloc(1, sizeof(*map
));
1688 if (fec_insert(&ln
->sent_map_pending
, map
))
1689 log_warnx("failed to add %s to sent map (pending)", log_fec(map
));
1695 lde_map_pending_del(struct lde_nbr
*ln
, struct fec
*map
)
1697 fec_remove(&ln
->sent_map_pending
, map
);
1702 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1705 struct lde_req
*lre
;
1707 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1709 lre
= calloc(1, sizeof(*lre
));
1713 if (fec_insert(t
, &lre
->fec
)) {
1714 log_warnx("failed to add %s to %s req",
1715 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1725 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1728 fec_remove(&ln
->sent_req
, &lre
->fec
);
1730 fec_remove(&ln
->recv_req
, &lre
->fec
);
1736 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1738 struct lde_wdraw
*lw
;
1740 lw
= calloc(1, sizeof(*lw
));
1746 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1747 log_warnx("failed to add %s to sent wdraw", log_fec(&lw
->fec
));
1753 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1755 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1760 lde_change_egress_label(int af
)
1764 struct fec_node
*fn
;
1766 /* explicitly withdraw all null labels */
1767 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1768 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IMPLICIT_NULL
);
1770 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IPV4_EXPLICIT_NULL
);
1772 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IPV6_EXPLICIT_NULL
);
1775 /* update label of connected routes */
1776 RB_FOREACH(f
, fec_tree
, &ft
) {
1777 fn
= (struct fec_node
*)f
;
1778 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1783 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1787 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1791 fatalx("lde_change_egress_label: unknown af");
1794 fn
->local_label
= lde_update_label(fn
);
1795 if (fn
->local_label
!= NO_LABEL
)
1796 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1797 lde_send_labelmapping(ln
, fn
, 0);
1799 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1800 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1804 lde_change_allocate_filter(int af
)
1808 struct fec_node
*fn
;
1811 /* reallocate labels for fecs that match this filter */
1812 RB_FOREACH(f
, fec_tree
, &ft
) {
1813 fn
= (struct fec_node
*)f
;
1817 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1821 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1825 fatalx("lde_change_allocate_filter: unknown af");
1829 * If the local label has changed to NO_LABEL, send a label
1830 * withdraw to all peers.
1831 * If the local label has changed and it's different from
1832 * NO_LABEL, send a label mapping to all peers advertising
1834 * If the local label hasn't changed, do nothing
1836 new_label
= lde_update_label(fn
);
1837 if (fn
->local_label
!= new_label
) {
1838 if (new_label
== NO_LABEL
)
1839 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1840 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
1842 fn
->local_label
= new_label
;
1843 if (fn
->local_label
!= NO_LABEL
)
1844 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1845 lde_send_labelmapping(ln
, fn
, 0);
1849 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1850 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1855 lde_change_advertise_filter(int af
)
1859 struct fec_node
*fn
;
1860 char *acl_to_filter
;
1861 char *acl_for_filter
;
1862 union ldpd_addr
*prefix
;
1866 /* advertise label for fecs to neighbors if matches advertise filters */
1869 acl_to_filter
= ldeconf
->ipv4
.acl_label_advertise_to
;
1870 acl_for_filter
= ldeconf
->ipv4
.acl_label_advertise_for
;
1873 acl_to_filter
= ldeconf
->ipv6
.acl_label_advertise_to
;
1874 acl_for_filter
= ldeconf
->ipv6
.acl_label_advertise_for
;
1877 fatalx("lde_change_advertise_filter: unknown af");
1880 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1881 if (lde_acl_check(acl_to_filter
, af
, (union ldpd_addr
*)&ln
->id
,
1882 IPV4_MAX_BITLEN
) != FILTER_PERMIT
)
1883 lde_send_labelwithdraw_wcard(ln
, NO_LABEL
);
1885 /* This neighbor is allowed in to_filter, so
1886 * send labels if fec also matches for_filter
1888 RB_FOREACH(f
, fec_tree
, &ft
) {
1889 fn
= (struct fec_node
*)f
;
1892 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1894 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
1895 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1898 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1900 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
1901 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1907 if (lde_acl_check(acl_for_filter
, af
,
1908 prefix
, plen
) != FILTER_PERMIT
) {
1909 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1911 /* fec filtered withdraw */
1912 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
1914 /* fec allowed send map */
1915 lde_send_labelmapping(ln
, fn
, 0);
1917 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1924 lde_change_accept_filter(int af
)
1928 struct fec_node
*fn
;
1929 char *acl_for_filter
;
1930 char *acl_from_filter
;
1931 union ldpd_addr
*prefix
;
1936 /* accept labels from neighbors specified in the from_filter and for
1937 * fecs defined in the for_filter
1941 acl_for_filter
= ldeconf
->ipv4
.acl_label_accept_for
;
1942 acl_from_filter
= ldeconf
->ipv4
.acl_label_accept_from
;
1943 type
= FEC_TYPE_IPV4
;
1946 acl_for_filter
= ldeconf
->ipv6
.acl_label_accept_for
;
1947 acl_from_filter
= ldeconf
->ipv6
.acl_label_accept_from
;
1948 type
= FEC_TYPE_IPV6
;
1951 fatalx("lde_change_accept_filter: unknown af");
1954 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1955 if (lde_acl_check(acl_from_filter
, AF_INET
, (union ldpd_addr
*)
1956 &ln
->id
, IPV4_MAX_BITLEN
) != FILTER_PERMIT
) {
1957 /* This neighbor is now filtered so remove fecs from
1960 RB_FOREACH(f
, fec_tree
, &ft
) {
1961 fn
= (struct fec_node
*)f
;
1962 if (fn
->fec
.type
== type
) {
1963 me
= (struct lde_map
*)fec_find(&ln
->recv_map
, &fn
->fec
);
1965 lde_map_del(ln
, me
, 0);
1968 } else if (CHECK_FLAG(ln
->flags
, F_NBR_CAP_TWCARD
)) {
1969 /* This neighbor is allowed and supports type
1970 * wildcard so send a labelrequest
1971 * to get any new labels from neighbor
1972 * and make sure any fecs we currently have
1975 RB_FOREACH(f
, fec_tree
, &ft
) {
1976 fn
= (struct fec_node
*)f
;
1979 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1981 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
1982 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
1985 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1987 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
1988 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
1993 if (lde_acl_check(acl_for_filter
, af
,
1994 prefix
, plen
) != FILTER_PERMIT
) {
1995 me
= (struct lde_map
*)fec_find(&ln
->recv_map
, &fn
->fec
);
1997 lde_map_del(ln
, me
, 0);
2000 lde_send_labelrequest_wcard(ln
, af
);
2002 /* Type Wildcard is not supported so restart session */
2003 lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN
, ln
->peerid
, 0, NULL
, 0);
2008 lde_change_expnull_for_filter(int af
)
2012 struct fec_node
*fn
;
2015 union ldpd_addr
*prefix
;
2018 /* Configure explicit-null advertisement for all fecs in this filter */
2019 RB_FOREACH(f
, fec_tree
, &ft
) {
2020 fn
= (struct fec_node
*)f
;
2024 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2026 acl_name
= ldeconf
->ipv4
.acl_label_expnull_for
;
2027 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
;
2028 plen
= fn
->fec
.u
.ipv4
.prefixlen
;
2029 exp_label
= MPLS_LABEL_IPV4_EXPLICIT_NULL
;
2032 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2034 acl_name
= ldeconf
->ipv6
.acl_label_expnull_for
;
2035 prefix
= (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
;
2036 plen
= fn
->fec
.u
.ipv6
.prefixlen
;
2037 exp_label
= MPLS_LABEL_IPV6_EXPLICIT_NULL
;
2040 fatalx("lde_change_expnull_for_filter: unknown af");
2043 if (lde_acl_check(acl_name
, af
, prefix
, plen
) == FILTER_PERMIT
) {
2044 /* for this fec change any imp-null to exp-null */
2045 if (fn
->local_label
== MPLS_LABEL_IMPLICIT_NULL
) {
2046 fn
->local_label
= lde_update_label(fn
);
2047 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2048 lde_send_labelmapping(ln
, fn
, 0);
2051 /* for this fec change any exp-null back to imp-null */
2052 if (fn
->local_label
== exp_label
) {
2053 fn
->local_label
= lde_update_label(fn
);
2054 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2055 lde_send_labelmapping(ln
, fn
, 0);
2059 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2060 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
2065 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2067 struct lde_addr
*new;
2069 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
2072 if ((new = calloc(1, sizeof(*new))) == NULL
)
2075 new->af
= lde_addr
->af
;
2076 new->addr
= lde_addr
->addr
;
2077 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
2079 /* reevaluate the previously received mappings from this neighbor */
2080 lde_nbr_addr_update(ln
, lde_addr
, 0);
2086 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
2088 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
2089 if (lde_addr
== NULL
)
2092 /* reevaluate the previously received mappings from this neighbor */
2093 lde_nbr_addr_update(ln
, lde_addr
, 1);
2095 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
2102 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
2104 struct lde_addr
*lde_addr
;
2106 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
2107 if (lde_addr
->af
== af
&&
2108 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
2115 lde_address_list_free(struct lde_nbr
*ln
)
2117 struct lde_addr
*lde_addr
;
2119 while ((lde_addr
= TAILQ_POP_FIRST(&ln
->addr_list
, entry
)) != NULL
)
2124 * Event callback used to retry the label-manager sync zapi session.
2126 static void zclient_sync_retry(struct event
*thread
)
2128 zclient_sync_init();
2132 * Initialize and open a synchronous zapi session. This is used by label chunk
2133 * management code, which acquires and releases blocks of labels from the
2134 * zebra label-manager module.
2136 static void zclient_sync_init(void)
2138 struct zclient_options options
= zclient_options_default
;
2140 options
.synchronous
= true;
2142 /* Initialize special zclient for synchronous message exchanges. */
2143 zclient_sync
= zclient_new(master
, &options
, NULL
, 0);
2144 zclient_sync
->sock
= -1;
2145 zclient_sync
->redist_default
= ZEBRA_ROUTE_LDP
;
2146 zclient_sync
->session_id
= 1; /* Distinguish from main session */
2147 zclient_sync
->privs
= &lde_privs
;
2149 if (zclient_socket_connect(zclient_sync
) < 0) {
2150 log_warnx("Error connecting synchronous zclient!");
2153 /* make socket non-blocking */
2154 sock_set_nonblock(zclient_sync
->sock
);
2156 /* Send hello to notify zebra this is a synchronous client */
2157 if (zclient_send_hello(zclient_sync
) == ZCLIENT_SEND_FAILURE
) {
2158 log_warnx("Error sending hello for synchronous zclient!");
2162 /* Connect to label manager */
2163 if (lm_label_manager_connect(zclient_sync
, 0) != 0) {
2164 log_warnx("Error connecting to label manager!");
2168 /* Finish label-manager init once the LM session is running */
2169 lde_label_list_init();
2175 /* Discard failed zclient object */
2176 zclient_stop(zclient_sync
);
2177 zclient_free(zclient_sync
);
2178 zclient_sync
= NULL
;
2180 /* Retry using a timer */
2181 event_add_timer(master
, zclient_sync_retry
, NULL
, 1, NULL
);
2185 lde_del_label_chunk(void *val
)
2191 lde_release_label_chunk(uint32_t start
, uint32_t end
)
2195 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
2197 log_warnx("Error releasing label chunk!");
2204 lde_get_label_chunk(void)
2207 uint32_t start
, end
;
2209 debug_labels("getting label chunk (size %u)", CHUNK_SIZE
);
2210 ret
= lm_get_label_chunk(zclient_sync
, 0, MPLS_LABEL_BASE_ANY
,
2211 CHUNK_SIZE
, &start
, &end
);
2213 log_warnx("Error getting label chunk!");
2217 on_get_label_chunk_response(start
, end
);
2223 lde_label_list_init(void)
2225 label_chunk_list
= list_new();
2226 label_chunk_list
->del
= lde_del_label_chunk
;
2228 /* get first chunk */
2229 while (lde_get_label_chunk () != 0) {
2230 log_warnx("Error getting first label chunk!");
2236 on_get_label_chunk_response(uint32_t start
, uint32_t end
)
2238 struct label_chunk
*new_label_chunk
;
2240 debug_labels("label chunk assign: %u - %u", start
, end
);
2242 new_label_chunk
= calloc(1, sizeof(struct label_chunk
));
2243 if (!new_label_chunk
) {
2244 log_warn("Error trying to allocate label chunk %u - %u", start
, end
);
2248 new_label_chunk
->start
= start
;
2249 new_label_chunk
->end
= end
;
2250 new_label_chunk
->used_mask
= 0;
2252 listnode_add(label_chunk_list
, (void *)new_label_chunk
);
2254 /* let's update current if needed */
2255 if (!current_label_chunk
)
2256 current_label_chunk
= listtail(label_chunk_list
);
2260 lde_free_label(uint32_t label
)
2262 struct listnode
*node
;
2263 struct label_chunk
*label_chunk
;
2266 for (ALL_LIST_ELEMENTS_RO(label_chunk_list
, node
, label_chunk
)) {
2267 if (label
<= label_chunk
->end
&& label
>= label_chunk
->start
) {
2268 pos
= 1ULL << (label
- label_chunk
->start
);
2269 UNSET_FLAG(label_chunk
->used_mask
, pos
);
2270 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
2271 if (!label_chunk
->used_mask
&& (current_label_chunk
!= node
)) {
2272 if (lde_release_label_chunk(label_chunk
->start
, label_chunk
->end
) != 0)
2273 log_warnx("%s: Error releasing label chunk!", __func__
);
2275 listnode_delete(label_chunk_list
, label_chunk
);
2276 lde_del_label_chunk(label_chunk
);
2287 lde_get_next_label(void)
2289 struct label_chunk
*label_chunk
;
2292 uint32_t label
= NO_LABEL
;
2294 while (current_label_chunk
) {
2295 label_chunk
= listgetdata(current_label_chunk
);
2299 /* try to get next free label in currently used label chunk */
2300 size
= label_chunk
->end
- label_chunk
->start
+ 1;
2301 for (i
= 0, pos
= 1; i
< size
; i
++, pos
<<= 1) {
2302 if (!(pos
& label_chunk
->used_mask
)) {
2303 SET_FLAG(label_chunk
->used_mask
, pos
);
2304 label
= label_chunk
->start
+ i
;
2308 current_label_chunk
= listnextnode(current_label_chunk
);
2312 /* we moved till the last chunk, or were not able to find a label,
2313 so let's ask for another one */
2314 if (!current_label_chunk
||
2315 current_label_chunk
== listtail(label_chunk_list
) ||
2316 label
== NO_LABEL
) {
2317 if (lde_get_label_chunk() != 0)
2318 log_warn("%s: Error getting label chunk!", __func__
);
2326 lde_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
2327 const char *filter_name
)
2329 if (strcmp(af_conf
->acl_label_allocate_for
, filter_name
) == 0)
2330 lde_change_allocate_filter(af
);
2332 if ((strcmp(af_conf
->acl_label_advertise_to
, filter_name
) == 0)
2333 || (strcmp(af_conf
->acl_label_advertise_for
, filter_name
) == 0))
2334 lde_change_advertise_filter(af
);
2336 if ((strcmp(af_conf
->acl_label_accept_for
, filter_name
) == 0)
2337 || (strcmp(af_conf
->acl_label_accept_from
, filter_name
) == 0))
2338 lde_change_accept_filter(af
);
2340 if (strcmp(af_conf
->acl_label_expnull_for
, filter_name
) == 0)
2341 lde_change_expnull_for_filter(af
);
2344 void lde_route_update(struct iface
*iface
, int af
)
2347 struct fec_node
*fn
;
2351 /* update label of non-connected routes */
2352 log_debug("update labels for interface %s", iface
->name
);
2354 RB_FOREACH(f
, fec_tree
, &ft
) {
2355 fn
= (struct fec_node
*)f
;
2356 if (IS_MPLS_UNRESERVED_LABEL(fn
->local_label
))
2361 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2365 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2369 /* unspecified so process both address families */
2373 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2375 * If connected leave existing label. If LDP
2376 * configured on interface or a static route
2377 * may need new label. If no LDP configured
2378 * treat fec as a connected route
2380 if (CHECK_FLAG(fnh
->flags
, F_FEC_NH_CONNECTED
))
2383 if (fnh
->ifindex
!= iface
->ifindex
)
2386 UNSET_FLAG(fnh
->flags
, F_FEC_NH_NO_LDP
);
2387 if (IS_MPLS_RESERVED_LABEL(fn
->local_label
)) {
2388 fn
->local_label
= NO_LABEL
;
2389 fn
->local_label
= lde_update_label(fn
);
2390 if (fn
->local_label
!= NO_LABEL
)
2391 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2392 lde_send_labelmapping(
2399 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2400 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2404 void lde_route_update_release(struct iface
*iface
, int af
)
2408 struct fec_node
*fn
;
2411 /* update label of interfaces no longer running LDP */
2412 log_debug("release all labels for interface %s af %s", iface
->name
,
2413 af
== AF_INET
? "ipv4" : "ipv6");
2415 RB_FOREACH(f
, fec_tree
, &ft
) {
2416 fn
= (struct fec_node
*)f
;
2420 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2424 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2428 fatalx("lde_route_update_release: unknown af");
2431 if (fn
->local_label
== NO_LABEL
)
2434 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2436 * If connected leave existing label. If LDP
2437 * removed from interface may need new label
2438 * and would be treated as a connected route
2440 if (CHECK_FLAG(fnh
->flags
, F_FEC_NH_CONNECTED
))
2443 if (fnh
->ifindex
!= iface
->ifindex
)
2446 SET_FLAG(fnh
->flags
, F_FEC_NH_NO_LDP
);
2447 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2448 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2449 lde_free_label(fn
->local_label
);
2450 fn
->local_label
= NO_LABEL
;
2451 fn
->local_label
= lde_update_label(fn
);
2452 if (fn
->local_label
!= NO_LABEL
)
2453 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2454 lde_send_labelmapping(ln
, fn
, 0);
2459 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2460 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
,
2464 void lde_route_update_release_all(int af
)
2468 struct fec_node
*fn
;
2471 /* remove labels from all interfaces as LDP is no longer running for
2472 * this address family
2474 log_debug("release all labels for address family %s",
2475 af
== AF_INET
? "ipv4" : "ipv6");
2477 RB_FOREACH(f
, fec_tree
, &ft
) {
2478 fn
= (struct fec_node
*)f
;
2481 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
2485 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
2489 fatalx("lde_route_update_release: unknown af");
2492 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
2493 lde_send_labelwithdraw(ln
, fn
, NULL
, NULL
);
2495 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
2496 SET_FLAG(fnh
->flags
, F_FEC_NH_NO_LDP
);
2497 lde_send_delete_klabel(fn
, fnh
);