4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 #include "ldp_debug.h"
36 #include <lib/linklist.h>
42 static void lde_shutdown(void);
43 static int lde_dispatch_imsg(struct thread
*);
44 static int lde_dispatch_parent(struct thread
*);
45 static __inline
int lde_nbr_compare(const struct lde_nbr
*,
46 const struct lde_nbr
*);
47 static struct lde_nbr
*lde_nbr_new(uint32_t, struct lde_nbr
*);
48 static void lde_nbr_del(struct lde_nbr
*);
49 static struct lde_nbr
*lde_nbr_find(uint32_t);
50 static void lde_nbr_clear(void);
51 static void lde_nbr_addr_update(struct lde_nbr
*,
52 struct lde_addr
*, int);
53 static __inline
int lde_map_compare(const struct lde_map
*,
54 const struct lde_map
*);
55 static void lde_map_free(void *);
56 static int lde_address_add(struct lde_nbr
*, struct lde_addr
*);
57 static int lde_address_del(struct lde_nbr
*, struct lde_addr
*);
58 static void lde_address_list_free(struct lde_nbr
*);
59 static void zclient_sync_init(unsigned short instance
);
60 static void lde_label_list_init(void);
61 static int lde_get_label_chunk(void);
62 static void on_get_label_chunk_response(uint32_t start
, uint32_t end
);
63 static uint32_t lde_get_next_label(void);
65 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
66 RB_GENERATE(lde_map_head
, lde_map
, entry
, lde_map_compare
)
68 struct ldpd_conf
*ldeconf
;
69 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
71 static struct imsgev
*iev_ldpe
;
72 static struct imsgev
*iev_main
, *iev_main_sync
;
74 /* Master of threads. */
75 struct thread_master
*master
;
78 static zebra_capabilities_t _caps_p
[] =
83 static struct zebra_privs_t lde_privs
=
85 #if defined(VTY_GROUP)
86 .vty_group
= VTY_GROUP
,
89 .cap_num_p
= array_size(_caps_p
),
93 /* List of chunks of labels externally assigned by Zebra */
94 static struct list
*label_chunk_list
;
95 static struct listnode
*current_label_chunk
;
97 /* Synchronous zclient to request labels */
98 static struct zclient
*zclient_sync
;
100 /* SIGINT / SIGTERM handler. */
107 static struct quagga_signal_t lde_signals
[] =
123 /* label decision engine */
127 struct thread thread
;
129 #ifdef HAVE_SETPROCTITLE
130 setproctitle("label decision engine");
132 ldpd_process
= PROC_LDE_ENGINE
;
133 log_procname
= log_procnames
[PROC_LDE_ENGINE
];
135 master
= thread_master_create(NULL
);
137 /* setup signal handler */
138 signal_init(master
, array_size(lde_signals
), lde_signals
);
140 /* setup pipes and event handlers to the parent process */
141 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
143 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
144 iev_main
->handler_read
= lde_dispatch_parent
;
145 iev_main
->ev_read
= NULL
;
146 thread_add_read(master
, iev_main
->handler_read
, iev_main
, iev_main
->ibuf
.fd
,
148 iev_main
->handler_write
= ldp_write_handler
;
150 if ((iev_main_sync
= calloc(1, sizeof(struct imsgev
))) == NULL
)
152 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
154 /* create base configuration */
155 ldeconf
= config_new_empty();
157 /* Fetch next active thread. */
158 while (thread_fetch(master
, &thread
))
159 thread_call(&thread
);
163 lde_init(struct ldpd_init
*init
)
165 /* drop privileges */
166 lde_privs
.user
= init
->user
;
167 lde_privs
.group
= init
->group
;
168 zprivs_preinit(&lde_privs
);
169 zprivs_init(&lde_privs
);
171 /* start the LIB garbage collector */
172 lde_gc_start_timer();
174 /* Init synchronous zclient and label list */
175 frr_zclient_addr(&zclient_addr
, &zclient_addr_len
,
176 init
->zclient_serv_path
);
177 zclient_sync_init(init
->instance
);
178 lde_label_list_init();
186 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
187 close(iev_ldpe
->ibuf
.fd
);
188 iev_ldpe
->ibuf
.fd
= -1;
190 msgbuf_clear(&iev_main
->ibuf
.w
);
191 close(iev_main
->ibuf
.fd
);
192 iev_main
->ibuf
.fd
= -1;
193 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
194 close(iev_main_sync
->ibuf
.fd
);
195 iev_main_sync
->ibuf
.fd
= -1;
201 config_clear(ldeconf
);
208 log_info("label decision engine exiting");
214 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
216 if (iev_main
->ibuf
.fd
== -1)
218 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
222 lde_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
224 if (iev_main_sync
->ibuf
.fd
== -1)
226 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
227 imsg_flush(&iev_main_sync
->ibuf
);
231 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
234 if (iev_ldpe
->ibuf
.fd
== -1)
236 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
242 lde_dispatch_imsg(struct thread
*thread
)
244 struct imsgev
*iev
= THREAD_ARG(thread
);
245 struct imsgbuf
*ibuf
= &iev
->ibuf
;
249 struct lde_addr
*lde_addr
;
250 struct notify_msg
*nm
;
256 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
257 fatal("imsg_read error");
258 if (n
== 0) /* connection closed */
262 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
263 fatal("lde_dispatch_imsg: imsg_get error");
267 switch (imsg
.hdr
.type
) {
268 case IMSG_LABEL_MAPPING_FULL
:
269 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
271 log_debug("%s: cannot find lde neighbor",
278 case IMSG_LABEL_MAPPING
:
279 case IMSG_LABEL_REQUEST
:
280 case IMSG_LABEL_RELEASE
:
281 case IMSG_LABEL_WITHDRAW
:
282 case IMSG_LABEL_ABORT
:
283 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
285 fatalx("lde_dispatch_imsg: wrong imsg len");
288 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
290 log_debug("%s: cannot find lde neighbor",
295 switch (imsg
.hdr
.type
) {
296 case IMSG_LABEL_MAPPING
:
297 lde_check_mapping(map
, ln
);
299 case IMSG_LABEL_REQUEST
:
300 lde_check_request(map
, ln
);
302 case IMSG_LABEL_RELEASE
:
303 lde_check_release(map
, ln
);
305 case IMSG_LABEL_WITHDRAW
:
306 lde_check_withdraw(map
, ln
);
308 case IMSG_LABEL_ABORT
:
313 case IMSG_ADDRESS_ADD
:
314 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
315 sizeof(struct lde_addr
))
316 fatalx("lde_dispatch_imsg: wrong imsg len");
317 lde_addr
= imsg
.data
;
319 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
321 log_debug("%s: cannot find lde neighbor",
325 if (lde_address_add(ln
, lde_addr
) < 0) {
326 log_debug("%s: cannot add address %s, it "
327 "already exists", __func__
,
328 log_addr(lde_addr
->af
, &lde_addr
->addr
));
331 case IMSG_ADDRESS_DEL
:
332 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
333 sizeof(struct lde_addr
))
334 fatalx("lde_dispatch_imsg: wrong imsg len");
335 lde_addr
= imsg
.data
;
337 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
339 log_debug("%s: cannot find lde neighbor",
343 if (lde_address_del(ln
, lde_addr
) < 0) {
344 log_debug("%s: cannot delete address %s, it "
345 "does not exist", __func__
,
346 log_addr(lde_addr
->af
, &lde_addr
->addr
));
349 case IMSG_NOTIFICATION
:
350 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
351 sizeof(struct notify_msg
))
352 fatalx("lde_dispatch_imsg: wrong imsg len");
355 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
357 log_debug("%s: cannot find lde neighbor",
362 switch (nm
->status_code
) {
364 l2vpn_recv_pw_status(ln
, nm
);
368 * Do nothing for now. Should be useful in
369 * the future when we implement LDP-IGP
370 * Synchronization (RFC 5443) and Graceful
371 * Restart (RFC 3478).
377 case IMSG_NEIGHBOR_UP
:
378 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
379 sizeof(struct lde_nbr
))
380 fatalx("lde_dispatch_imsg: wrong imsg len");
382 if (lde_nbr_find(imsg
.hdr
.peerid
))
383 fatalx("lde_dispatch_imsg: "
384 "neighbor already exists");
385 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
387 case IMSG_NEIGHBOR_DOWN
:
388 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
390 case IMSG_CTL_SHOW_LIB
:
391 rt_dump(imsg
.hdr
.pid
);
393 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
394 imsg
.hdr
.pid
, NULL
, 0);
396 case IMSG_CTL_SHOW_L2VPN_PW
:
397 l2vpn_pw_ctl(imsg
.hdr
.pid
);
399 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
400 imsg
.hdr
.pid
, NULL
, 0);
402 case IMSG_CTL_SHOW_L2VPN_BINDING
:
403 l2vpn_binding_ctl(imsg
.hdr
.pid
);
405 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
406 imsg
.hdr
.pid
, NULL
, 0);
409 log_debug("%s: unexpected imsg %d", __func__
,
418 /* this pipe is dead, so remove the event handlers and exit */
419 THREAD_READ_OFF(iev
->ev_read
);
420 THREAD_WRITE_OFF(iev
->ev_write
);
429 lde_dispatch_parent(struct thread
*thread
)
431 static struct ldpd_conf
*nconf
;
432 struct iface
*iface
, *niface
;
434 struct nbr_params
*nnbrp
;
435 static struct l2vpn
*l2vpn
, *nl2vpn
;
436 struct l2vpn_if
*lif
, *nlif
;
437 struct l2vpn_pw
*pw
, *npw
;
442 struct imsgev
*iev
= THREAD_ARG(thread
);
443 struct imsgbuf
*ibuf
= &iev
->ibuf
;
450 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
451 fatal("imsg_read error");
452 if (n
== 0) /* connection closed */
456 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
457 fatal("lde_dispatch_parent: imsg_get error");
461 switch (imsg
.hdr
.type
) {
463 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
465 fatalx("IFSTATUS imsg with wrong len");
468 iface
= if_lookup_name(ldeconf
, kif
->ifname
);
470 if_update_info(iface
, kif
);
474 RB_FOREACH(l2vpn
, l2vpn_head
, &ldeconf
->l2vpn_tree
) {
475 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
477 l2vpn_if_update_info(lif
, kif
);
480 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
482 l2vpn_pw_update_info(pw
, kif
);
488 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
489 sizeof(struct zapi_pw_status
))
490 fatalx("PW_UPDATE imsg with wrong len");
492 if (l2vpn_pw_status_update(imsg
.data
) != 0)
493 log_warnx("%s: error updating PW status",
496 case IMSG_NETWORK_ADD
:
497 case IMSG_NETWORK_UPDATE
:
498 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
499 sizeof(struct kroute
)) {
500 log_warnx("%s: wrong imsg len", __func__
);
507 fec
.type
= FEC_TYPE_IPV4
;
508 fec
.u
.ipv4
.prefix
= kr
->prefix
.v4
;
509 fec
.u
.ipv4
.prefixlen
= kr
->prefixlen
;
512 fec
.type
= FEC_TYPE_IPV6
;
513 fec
.u
.ipv6
.prefix
= kr
->prefix
.v6
;
514 fec
.u
.ipv6
.prefixlen
= kr
->prefixlen
;
517 fatalx("lde_dispatch_parent: unknown af");
520 switch (imsg
.hdr
.type
) {
521 case IMSG_NETWORK_ADD
:
522 lde_kernel_insert(&fec
, kr
->af
, &kr
->nexthop
,
523 kr
->ifindex
, kr
->route_type
,
525 kr
->flags
& F_CONNECTED
, NULL
);
527 case IMSG_NETWORK_UPDATE
:
528 lde_kernel_update(&fec
);
532 case IMSG_SOCKET_IPC
:
534 log_warnx("%s: received unexpected imsg fd "
535 "to ldpe", __func__
);
538 if ((fd
= imsg
.fd
) == -1) {
539 log_warnx("%s: expected to receive imsg fd to "
540 "ldpe but didn't receive any", __func__
);
544 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
546 imsg_init(&iev_ldpe
->ibuf
, fd
);
547 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
548 iev_ldpe
->ev_read
= NULL
;
549 thread_add_read(master
, iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
,
551 iev_ldpe
->handler_write
= ldp_write_handler
;
552 iev_ldpe
->ev_write
= NULL
;
555 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
556 sizeof(struct ldpd_init
))
557 fatalx("INIT imsg with wrong len");
559 memcpy(&init
, imsg
.data
, sizeof(init
));
562 case IMSG_RECONF_CONF
:
563 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
566 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
568 RB_INIT(iface_head
, &nconf
->iface_tree
);
569 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
570 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
571 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
573 case IMSG_RECONF_IFACE
:
574 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
576 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
578 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
580 case IMSG_RECONF_TNBR
:
581 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
583 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
585 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
587 case IMSG_RECONF_NBRP
:
588 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
590 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
592 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
594 case IMSG_RECONF_L2VPN
:
595 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
597 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
599 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
600 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
601 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
603 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
605 case IMSG_RECONF_L2VPN_IF
:
606 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
608 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
610 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
612 case IMSG_RECONF_L2VPN_PW
:
613 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
615 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
617 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
619 case IMSG_RECONF_L2VPN_IPW
:
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_inactive_tree
, npw
);
626 case IMSG_RECONF_END
:
627 merge_config(ldeconf
, nconf
);
628 ldp_clear_config(nconf
);
631 case IMSG_DEBUG_UPDATE
:
632 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
634 log_warnx("%s: wrong imsg len", __func__
);
637 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
640 log_debug("%s: unexpected imsg %d", __func__
,
649 /* this pipe is dead, so remove the event handlers and exit */
650 THREAD_READ_OFF(iev
->ev_read
);
651 THREAD_WRITE_OFF(iev
->ev_write
);
659 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
661 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
665 lde_update_label(struct fec_node
*fn
)
670 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
671 if (fnh
->flags
& F_FEC_NH_CONNECTED
) {
677 /* should we allocate a label for this fec? */
678 switch (fn
->fec
.type
) {
680 if ((ldeconf
->ipv4
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
681 fn
->fec
.u
.ipv4
.prefixlen
!= 32)
683 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
684 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
685 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
689 if ((ldeconf
->ipv6
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
690 fn
->fec
.u
.ipv6
.prefixlen
!= 128)
692 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
693 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
694 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
702 /* choose implicit or explicit-null depending on configuration */
703 switch (fn
->fec
.type
) {
705 if (!(ldeconf
->ipv4
.flags
& F_LDPD_AF_EXPNULL
))
706 return (MPLS_LABEL_IMPLICIT_NULL
);
707 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
708 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
709 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
710 return (MPLS_LABEL_IMPLICIT_NULL
);
711 return MPLS_LABEL_IPV4_EXPLICIT_NULL
;
713 if (!(ldeconf
->ipv6
.flags
& F_LDPD_AF_EXPNULL
))
714 return (MPLS_LABEL_IMPLICIT_NULL
);
715 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
716 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
717 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
718 return (MPLS_LABEL_IMPLICIT_NULL
);
719 return MPLS_LABEL_IPV6_EXPLICIT_NULL
;
721 fatalx("lde_update_label: unexpected fec type");
726 /* preserve current label if there's no need to update it */
727 if (fn
->local_label
!= NO_LABEL
&&
728 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
729 return (fn
->local_label
);
731 return (lde_get_next_label());
735 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
741 switch (fn
->fec
.type
) {
743 memset(&kr
, 0, sizeof(kr
));
745 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
746 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
747 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
748 kr
.ifindex
= fnh
->ifindex
;
749 kr
.local_label
= fn
->local_label
;
750 kr
.remote_label
= fnh
->remote_label
;
751 kr
.route_type
= fnh
->route_type
;
752 kr
.route_instance
= fnh
->route_instance
;
754 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
758 memset(&kr
, 0, sizeof(kr
));
760 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
761 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
762 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
763 kr
.ifindex
= fnh
->ifindex
;
764 kr
.local_label
= fn
->local_label
;
765 kr
.remote_label
= fnh
->remote_label
;
766 kr
.route_type
= fnh
->route_type
;
767 kr
.route_instance
= fnh
->route_instance
;
769 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
773 pw
= (struct l2vpn_pw
*) fn
->data
;
774 if (!pw
|| fn
->local_label
== NO_LABEL
||
775 fnh
->remote_label
== NO_LABEL
)
780 zpw
.local_label
= fn
->local_label
;
781 zpw
.remote_label
= fnh
->remote_label
;
782 lde_imsg_compose_parent(IMSG_KPW_SET
, 0, &zpw
, sizeof(zpw
));
788 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
794 switch (fn
->fec
.type
) {
796 memset(&kr
, 0, sizeof(kr
));
798 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
799 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
800 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
801 kr
.ifindex
= fnh
->ifindex
;
802 kr
.local_label
= fn
->local_label
;
803 kr
.remote_label
= fnh
->remote_label
;
804 kr
.route_type
= fnh
->route_type
;
805 kr
.route_instance
= fnh
->route_instance
;
807 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
811 memset(&kr
, 0, sizeof(kr
));
813 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
814 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
815 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
816 kr
.ifindex
= fnh
->ifindex
;
817 kr
.local_label
= fn
->local_label
;
818 kr
.remote_label
= fnh
->remote_label
;
819 kr
.route_type
= fnh
->route_type
;
820 kr
.route_instance
= fnh
->route_instance
;
822 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
826 pw
= (struct l2vpn_pw
*) fn
->data
;
832 zpw
.local_label
= fn
->local_label
;
833 zpw
.remote_label
= fnh
->remote_label
;
834 lde_imsg_compose_parent(IMSG_KPW_UNSET
, 0, &zpw
, sizeof(zpw
));
840 lde_fec2map(struct fec
*fec
, struct map
*map
)
842 memset(map
, 0, sizeof(*map
));
846 map
->type
= MAP_TYPE_PREFIX
;
847 map
->fec
.prefix
.af
= AF_INET
;
848 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
849 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
852 map
->type
= MAP_TYPE_PREFIX
;
853 map
->fec
.prefix
.af
= AF_INET6
;
854 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
855 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
858 map
->type
= MAP_TYPE_PWID
;
859 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
860 map
->fec
.pwid
.group_id
= 0;
861 map
->flags
|= F_MAP_PW_ID
;
862 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
868 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
870 memset(fec
, 0, sizeof(*fec
));
873 case MAP_TYPE_PREFIX
:
874 switch (map
->fec
.prefix
.af
) {
876 fec
->type
= FEC_TYPE_IPV4
;
877 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
878 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
881 fec
->type
= FEC_TYPE_IPV6
;
882 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
883 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
886 fatalx("lde_map2fec: unknown af");
891 fec
->type
= FEC_TYPE_PWID
;
892 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
893 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
894 fec
->u
.pwid
.lsr_id
= lsr_id
;
900 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
902 struct lde_wdraw
*lw
;
909 * We shouldn't send a new label mapping if we have a pending
910 * label release to receive. In this case, schedule to send a
911 * label mapping as soon as a label release is received.
913 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
915 if (!fec_find(&ln
->sent_map_pending
, &fn
->fec
)) {
916 debug_evt("%s: FEC %s: scheduling to send label "
917 "mapping later (waiting for pending label release)",
918 __func__
, log_fec(&fn
->fec
));
919 lde_map_pending_add(ln
, fn
);
925 * This function skips SL.1 - 3 and SL.9 - 14 because the label
926 * allocation is done way earlier (because of the merging nature of
930 lde_fec2map(&fn
->fec
, &map
);
931 switch (fn
->fec
.type
) {
935 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
936 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
938 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
939 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
940 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
946 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
947 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
949 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
950 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
951 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
955 pw
= (struct l2vpn_pw
*) fn
->data
;
956 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
957 /* not the remote end of the pseudowire */
960 map
.flags
|= F_MAP_PW_IFMTU
;
961 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
962 if (pw
->flags
& F_PW_CWORD
)
963 map
.flags
|= F_MAP_PW_CWORD
;
964 if (pw
->flags
& F_PW_STATUSTLV
) {
965 map
.flags
|= F_MAP_PW_STATUS
;
966 map
.pw_status
= pw
->local_status
;
970 map
.label
= fn
->local_label
;
972 /* SL.6: is there a pending request for this mapping? */
973 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
975 /* set label request msg id in the mapping response. */
976 map
.requestid
= lre
->msg_id
;
977 map
.flags
= F_MAP_REQ_ID
;
979 /* SL.7: delete record of pending request */
980 lde_req_del(ln
, lre
, 0);
983 /* SL.4: send label mapping */
984 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
987 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
990 /* SL.5: record sent label mapping */
991 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
993 me
= lde_map_add(ln
, fn
, 1);
998 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
,
999 struct map
*wcard
, struct status_tlv
*st
)
1001 struct lde_wdraw
*lw
;
1004 struct l2vpn_pw
*pw
;
1007 lde_fec2map(&fn
->fec
, &map
);
1008 switch (fn
->fec
.type
) {
1010 if (!ln
->v4_enabled
)
1014 if (!ln
->v6_enabled
)
1018 pw
= (struct l2vpn_pw
*) fn
->data
;
1019 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1020 /* not the remote end of the pseudowire */
1023 if (pw
->flags
& F_PW_CWORD
)
1024 map
.flags
|= F_MAP_PW_CWORD
;
1027 map
.label
= fn
->local_label
;
1029 memcpy(&map
, wcard
, sizeof(map
));
1032 map
.st
.status_code
= st
->status_code
;
1033 map
.st
.msg_id
= st
->msg_id
;
1034 map
.st
.msg_type
= st
->msg_type
;
1035 map
.flags
|= F_MAP_STATUS
;
1038 /* SWd.1: send label withdraw. */
1039 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
1041 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1043 /* SWd.2: record label withdraw. */
1045 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
1047 lw
= lde_wdraw_add(ln
, fn
);
1048 lw
->label
= map
.label
;
1052 RB_FOREACH(f
, fec_tree
, &ft
) {
1053 fn
= (struct fec_node
*)f
;
1054 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
1055 if (lde_wildcard_apply(wcard
, &fn
->fec
, me
) == 0)
1058 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
1061 lw
= lde_wdraw_add(ln
, fn
);
1062 lw
->label
= map
.label
;
1068 lde_send_labelwithdraw_wcard(struct lde_nbr
*ln
, uint32_t label
)
1072 memset(&wcard
, 0, sizeof(wcard
));
1073 wcard
.type
= MAP_TYPE_WILDCARD
;
1074 wcard
.label
= label
;
1075 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1079 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr
*ln
, uint16_t af
,
1084 memset(&wcard
, 0, sizeof(wcard
));
1085 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1086 wcard
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1087 wcard
.fec
.twcard
.u
.prefix_af
= af
;
1088 wcard
.label
= label
;
1089 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1093 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr
*ln
, uint16_t pw_type
,
1098 memset(&wcard
, 0, sizeof(wcard
));
1099 wcard
.type
= MAP_TYPE_TYPED_WCARD
;
1100 wcard
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1101 wcard
.fec
.twcard
.u
.pw_type
= pw_type
;
1102 wcard
.label
= label
;
1103 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1107 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr
*ln
, uint16_t pw_type
,
1112 memset(&wcard
, 0, sizeof(wcard
));
1113 wcard
.type
= MAP_TYPE_PWID
;
1114 wcard
.fec
.pwid
.type
= pw_type
;
1115 wcard
.fec
.pwid
.group_id
= group_id
;
1116 /* we can not append a Label TLV when using PWid group wildcards. */
1117 wcard
.label
= NO_LABEL
;
1118 lde_send_labelwithdraw(ln
, NULL
, &wcard
, NULL
);
1122 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
,
1123 struct map
*wcard
, uint32_t label
)
1126 struct l2vpn_pw
*pw
;
1129 lde_fec2map(&fn
->fec
, &map
);
1130 switch (fn
->fec
.type
) {
1132 if (!ln
->v4_enabled
)
1136 if (!ln
->v6_enabled
)
1140 pw
= (struct l2vpn_pw
*) fn
->data
;
1141 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1142 /* not the remote end of the pseudowire */
1145 if (pw
->flags
& F_PW_CWORD
)
1146 map
.flags
|= F_MAP_PW_CWORD
;
1150 memcpy(&map
, wcard
, sizeof(map
));
1153 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1155 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1159 lde_send_notification(struct lde_nbr
*ln
, uint32_t status_code
, uint32_t msg_id
,
1162 struct notify_msg nm
;
1164 memset(&nm
, 0, sizeof(nm
));
1165 nm
.status_code
= status_code
;
1166 /* 'msg_id' and 'msg_type' should be in network byte order */
1168 nm
.msg_type
= msg_type
;
1170 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1175 lde_send_notification_eol_prefix(struct lde_nbr
*ln
, int af
)
1177 struct notify_msg nm
;
1179 memset(&nm
, 0, sizeof(nm
));
1180 nm
.status_code
= S_ENDOFLIB
;
1181 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1182 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PREFIX
;
1183 nm
.fec
.fec
.twcard
.u
.prefix_af
= af
;
1184 nm
.flags
|= F_NOTIF_FEC
;
1186 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1191 lde_send_notification_eol_pwid(struct lde_nbr
*ln
, uint16_t pw_type
)
1193 struct notify_msg nm
;
1195 memset(&nm
, 0, sizeof(nm
));
1196 nm
.status_code
= S_ENDOFLIB
;
1197 nm
.fec
.type
= MAP_TYPE_TYPED_WCARD
;
1198 nm
.fec
.fec
.twcard
.type
= MAP_TYPE_PWID
;
1199 nm
.fec
.fec
.twcard
.u
.pw_type
= pw_type
;
1200 nm
.flags
|= F_NOTIF_FEC
;
1202 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, ln
->peerid
, 0,
1207 lde_nbr_compare(const struct lde_nbr
*a
, const struct lde_nbr
*b
)
1209 return (a
->peerid
- b
->peerid
);
1212 static struct lde_nbr
*
1213 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1217 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1221 ln
->v4_enabled
= new->v4_enabled
;
1222 ln
->v6_enabled
= new->v6_enabled
;
1223 ln
->flags
= new->flags
;
1224 ln
->peerid
= peerid
;
1225 fec_init(&ln
->recv_map
);
1226 fec_init(&ln
->sent_map
);
1227 fec_init(&ln
->sent_map_pending
);
1228 fec_init(&ln
->recv_req
);
1229 fec_init(&ln
->sent_req
);
1230 fec_init(&ln
->sent_wdraw
);
1232 TAILQ_INIT(&ln
->addr_list
);
1234 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1235 fatalx("lde_nbr_new: RB_INSERT failed");
1241 lde_nbr_del(struct lde_nbr
*ln
)
1244 struct fec_node
*fn
;
1246 struct l2vpn_pw
*pw
;
1251 /* uninstall received mappings */
1252 RB_FOREACH(f
, fec_tree
, &ft
) {
1253 fn
= (struct fec_node
*)f
;
1255 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1259 if (!lde_address_find(ln
, fnh
->af
,
1264 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1266 pw
= (struct l2vpn_pw
*) fn
->data
;
1274 lde_send_delete_klabel(fn
, fnh
);
1275 fnh
->remote_label
= NO_LABEL
;
1279 lde_address_list_free(ln
);
1281 fec_clear(&ln
->recv_map
, lde_map_free
);
1282 fec_clear(&ln
->sent_map
, lde_map_free
);
1283 fec_clear(&ln
->sent_map_pending
, free
);
1284 fec_clear(&ln
->recv_req
, free
);
1285 fec_clear(&ln
->sent_req
, free
);
1286 fec_clear(&ln
->sent_wdraw
, free
);
1288 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1293 static struct lde_nbr
*
1294 lde_nbr_find(uint32_t peerid
)
1300 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1304 lde_nbr_find_by_lsrid(struct in_addr addr
)
1308 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1309 if (ln
->id
.s_addr
== addr
.s_addr
)
1316 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1320 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1321 if (lde_address_find(ln
, af
, addr
) != NULL
)
1332 while (!RB_EMPTY(nbr_tree
, &lde_nbrs
)) {
1333 ln
= RB_ROOT(nbr_tree
, &lde_nbrs
);
1340 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1343 struct fec_node
*fn
;
1347 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1348 switch (fec
->type
) {
1350 if (lde_addr
->af
!= AF_INET
)
1354 if (lde_addr
->af
!= AF_INET6
)
1361 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1363 /* shouldn't happen */
1366 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1367 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1372 lde_send_delete_klabel(fn
, fnh
);
1373 fnh
->remote_label
= NO_LABEL
;
1375 me
= (struct lde_map
*)fec
;
1376 fnh
->remote_label
= me
->map
.label
;
1377 lde_send_change_klabel(fn
, fnh
);
1385 lde_map_compare(const struct lde_map
*a
, const struct lde_map
*b
)
1387 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1388 (union ldpd_addr
*)&b
->nexthop
->id
));
1392 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1396 me
= calloc(1, sizeof(*me
));
1404 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1405 me
->head
= &fn
->upstream
;
1406 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1407 log_warnx("failed to add %s to sent map",
1409 /* XXX on failure more cleanup is needed */
1411 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1412 me
->head
= &fn
->downstream
;
1413 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1414 log_warnx("failed to add %s to recv map",
1422 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1425 fec_remove(&ln
->sent_map
, &me
->fec
);
1427 fec_remove(&ln
->recv_map
, &me
->fec
);
1433 lde_map_free(void *ptr
)
1435 struct lde_map
*map
= ptr
;
1437 RB_REMOVE(lde_map_head
, map
->head
, map
);
1442 lde_map_pending_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1446 map
= calloc(1, sizeof(*map
));
1451 if (fec_insert(&ln
->sent_map_pending
, map
))
1452 log_warnx("failed to add %s to sent map (pending)",
1459 lde_map_pending_del(struct lde_nbr
*ln
, struct fec
*map
)
1461 fec_remove(&ln
->sent_map_pending
, map
);
1466 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1469 struct lde_req
*lre
;
1471 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1473 lre
= calloc(1, sizeof(*lre
));
1477 if (fec_insert(t
, &lre
->fec
)) {
1478 log_warnx("failed to add %s to %s req",
1479 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1489 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1492 fec_remove(&ln
->sent_req
, &lre
->fec
);
1494 fec_remove(&ln
->recv_req
, &lre
->fec
);
1500 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1502 struct lde_wdraw
*lw
;
1504 lw
= calloc(1, sizeof(*lw
));
1510 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1511 log_warnx("failed to add %s to sent wdraw",
1518 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1520 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1525 lde_change_egress_label(int af
)
1529 struct fec_node
*fn
;
1531 /* explicitly withdraw all null labels */
1532 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1533 lde_send_labelwithdraw_wcard(ln
, MPLS_LABEL_IMPLICIT_NULL
);
1535 lde_send_labelwithdraw_wcard(
1537 MPLS_LABEL_IPV4_EXPLICIT_NULL
);
1539 lde_send_labelwithdraw_wcard(
1541 MPLS_LABEL_IPV6_EXPLICIT_NULL
);
1544 /* update label of connected routes */
1545 RB_FOREACH(f
, fec_tree
, &ft
) {
1546 fn
= (struct fec_node
*)f
;
1547 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1552 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1556 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1560 fatalx("lde_change_egress_label: unknown af");
1563 fn
->local_label
= lde_update_label(fn
);
1564 if (fn
->local_label
!= NO_LABEL
)
1565 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1566 lde_send_labelmapping(ln
, fn
, 0);
1568 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1569 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1574 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1576 struct lde_addr
*new;
1578 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
1581 if ((new = calloc(1, sizeof(*new))) == NULL
)
1584 new->af
= lde_addr
->af
;
1585 new->addr
= lde_addr
->addr
;
1586 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
1588 /* reevaluate the previously received mappings from this neighbor */
1589 lde_nbr_addr_update(ln
, lde_addr
, 0);
1595 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1597 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
1598 if (lde_addr
== NULL
)
1601 /* reevaluate the previously received mappings from this neighbor */
1602 lde_nbr_addr_update(ln
, lde_addr
, 1);
1604 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
1611 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
1613 struct lde_addr
*lde_addr
;
1615 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
1616 if (lde_addr
->af
== af
&&
1617 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
1624 lde_address_list_free(struct lde_nbr
*ln
)
1626 struct lde_addr
*lde_addr
;
1628 while ((lde_addr
= TAILQ_POP_FIRST(&ln
->addr_list
, entry
)) != NULL
)
1632 static void zclient_sync_init(unsigned short instance
)
1634 /* Initialize special zclient for synchronous message exchanges. */
1635 zclient_sync
= zclient_new(master
, &zclient_options_default
);
1636 zclient_sync
->sock
= -1;
1637 zclient_sync
->redist_default
= ZEBRA_ROUTE_LDP
;
1638 zclient_sync
->instance
= instance
;
1639 zclient_sync
->privs
= &lde_privs
;
1641 while (zclient_socket_connect(zclient_sync
) < 0) {
1642 log_warnx("Error connecting synchronous zclient!");
1645 /* make socket non-blocking */
1646 sock_set_nonblock(zclient_sync
->sock
);
1648 /* Connect to label manager */
1649 while (lm_label_manager_connect(zclient_sync
, 0) != 0) {
1650 log_warnx("Error connecting to label manager!");
1656 lde_del_label_chunk(void *val
)
1662 lde_release_label_chunk(uint32_t start
, uint32_t end
)
1666 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
1668 log_warnx("Error releasing label chunk!");
1675 lde_get_label_chunk(void)
1678 uint32_t start
, end
;
1680 debug_labels("getting label chunk (size %u)", CHUNK_SIZE
);
1681 ret
= lm_get_label_chunk(zclient_sync
, 0, MPLS_LABEL_BASE_ANY
,
1682 CHUNK_SIZE
, &start
, &end
);
1684 log_warnx("Error getting label chunk!");
1688 on_get_label_chunk_response(start
, end
);
1694 lde_label_list_init(void)
1696 label_chunk_list
= list_new();
1697 label_chunk_list
->del
= lde_del_label_chunk
;
1699 /* get first chunk */
1700 while (lde_get_label_chunk () != 0) {
1701 log_warnx("Error getting first label chunk!");
1707 on_get_label_chunk_response(uint32_t start
, uint32_t end
)
1709 struct label_chunk
*new_label_chunk
;
1711 debug_labels("label chunk assign: %u - %u", start
, end
);
1713 new_label_chunk
= calloc(1, sizeof(struct label_chunk
));
1714 if (!new_label_chunk
) {
1715 log_warn("Error trying to allocate label chunk %u - %u", start
, end
);
1719 new_label_chunk
->start
= start
;
1720 new_label_chunk
->end
= end
;
1721 new_label_chunk
->used_mask
= 0;
1723 listnode_add(label_chunk_list
, (void *)new_label_chunk
);
1725 /* let's update current if needed */
1726 if (!current_label_chunk
)
1727 current_label_chunk
= listtail(label_chunk_list
);
1731 lde_free_label(uint32_t label
)
1733 struct listnode
*node
;
1734 struct label_chunk
*label_chunk
;
1737 for (ALL_LIST_ELEMENTS_RO(label_chunk_list
, node
, label_chunk
)) {
1738 if (label
<= label_chunk
->end
&& label
>= label_chunk
->start
) {
1739 pos
= 1ULL << (label
- label_chunk
->start
);
1740 label_chunk
->used_mask
&= ~pos
;
1741 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
1742 if (!label_chunk
->used_mask
&& (current_label_chunk
!= node
)) {
1743 if (lde_release_label_chunk(label_chunk
->start
, label_chunk
->end
) != 0)
1744 log_warnx("%s: Error releasing label chunk!", __func__
);
1746 listnode_delete(label_chunk_list
, label_chunk
);
1747 lde_del_label_chunk(label_chunk
);
1757 lde_get_next_label(void)
1759 struct label_chunk
*label_chunk
;
1762 uint32_t label
= NO_LABEL
;
1764 while (current_label_chunk
) {
1765 label_chunk
= listgetdata(current_label_chunk
);
1769 /* try to get next free label in currently used label chunk */
1770 size
= label_chunk
->end
- label_chunk
->start
+ 1;
1771 for (i
= 0, pos
= 1; i
< size
; i
++, pos
<<= 1) {
1772 if (!(pos
& label_chunk
->used_mask
)) {
1773 label_chunk
->used_mask
|= pos
;
1774 label
= label_chunk
->start
+ i
;
1778 current_label_chunk
= listnextnode(current_label_chunk
);
1782 /* we moved till the last chunk, or were not able to find a label,
1783 so let's ask for another one */
1784 if (!current_label_chunk
||
1785 current_label_chunk
== listtail(label_chunk_list
) ||
1786 label
== NO_LABEL
) {
1787 if (lde_get_label_chunk() != 0)
1788 log_warn("%s: Error getting label chunk!", __func__
);