4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 #include "ldp_debug.h"
37 static void lde_shutdown(void);
38 static int lde_dispatch_imsg(struct thread
*);
39 static int lde_dispatch_parent(struct thread
*);
40 static __inline
int lde_nbr_compare(struct lde_nbr
*,
42 static struct lde_nbr
*lde_nbr_new(uint32_t, struct lde_nbr
*);
43 static void lde_nbr_del(struct lde_nbr
*);
44 static struct lde_nbr
*lde_nbr_find(uint32_t);
45 static void lde_nbr_clear(void);
46 static void lde_nbr_addr_update(struct lde_nbr
*,
47 struct lde_addr
*, int);
48 static __inline
int lde_map_compare(struct lde_map
*, struct lde_map
*);
49 static void lde_map_free(void *);
50 static int lde_address_add(struct lde_nbr
*, struct lde_addr
*);
51 static int lde_address_del(struct lde_nbr
*, struct lde_addr
*);
52 static void lde_address_list_free(struct lde_nbr
*);
54 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
55 RB_GENERATE(lde_map_head
, lde_map
, entry
, lde_map_compare
)
57 struct ldpd_conf
*ldeconf
;
58 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
60 static struct imsgev
*iev_ldpe
;
61 static struct imsgev
*iev_main
, *iev_main_sync
;
63 /* Master of threads. */
64 struct thread_master
*master
;
67 static zebra_capabilities_t _caps_p
[] =
72 static struct zebra_privs_t lde_privs
=
74 #if defined(FRR_USER) && defined(FRR_GROUP)
78 #if defined(VTY_GROUP)
79 .vty_group
= VTY_GROUP
,
82 .cap_num_p
= array_size(_caps_p
),
86 /* SIGINT / SIGTERM handler. */
93 static struct quagga_signal_t lde_signals
[] =
105 /* label decision engine */
107 lde(const char *user
, const char *group
)
109 struct thread thread
;
112 ldeconf
= config_new_empty();
114 #ifdef HAVE_SETPROCTITLE
115 setproctitle("label decision engine");
117 ldpd_process
= PROC_LDE_ENGINE
;
119 /* drop privileges */
121 lde_privs
.user
= user
;
123 lde_privs
.group
= group
;
124 zprivs_init(&lde_privs
);
127 if (pledge("stdio recvfd", NULL
) == -1)
131 master
= thread_master_create();
133 /* setup signal handler */
134 signal_init(master
, array_size(lde_signals
), lde_signals
);
136 /* setup pipes and event handlers to the parent process */
137 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
139 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
140 iev_main
->handler_read
= lde_dispatch_parent
;
141 iev_main
->ev_read
= thread_add_read(master
, iev_main
->handler_read
,
142 iev_main
, iev_main
->ibuf
.fd
);
143 iev_main
->handler_write
= ldp_write_handler
;
145 if ((iev_main_sync
= calloc(1, sizeof(struct imsgev
))) == NULL
)
147 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
149 /* start the LIB garbage collector */
150 lde_gc_start_timer();
152 gettimeofday(&now
, NULL
);
153 global
.uptime
= now
.tv_sec
;
155 /* Fetch next active thread. */
156 while (thread_fetch(master
, &thread
))
157 thread_call(&thread
);
164 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
165 close(iev_ldpe
->ibuf
.fd
);
166 msgbuf_clear(&iev_main
->ibuf
.w
);
167 close(iev_main
->ibuf
.fd
);
168 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
169 close(iev_main_sync
->ibuf
.fd
);
175 config_clear(ldeconf
);
181 log_info("label decision engine exiting");
187 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
189 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
193 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
196 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
202 lde_dispatch_imsg(struct thread
*thread
)
204 struct imsgev
*iev
= THREAD_ARG(thread
);
205 struct imsgbuf
*ibuf
= &iev
->ibuf
;
209 struct lde_addr lde_addr
;
210 struct notify_msg nm
;
216 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
217 fatal("imsg_read error");
218 if (n
== 0) /* connection closed */
222 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
223 fatal("lde_dispatch_imsg: imsg_get error");
227 switch (imsg
.hdr
.type
) {
228 case IMSG_LABEL_MAPPING_FULL
:
229 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
231 log_debug("%s: cannot find lde neighbor",
238 case IMSG_LABEL_MAPPING
:
239 case IMSG_LABEL_REQUEST
:
240 case IMSG_LABEL_RELEASE
:
241 case IMSG_LABEL_WITHDRAW
:
242 case IMSG_LABEL_ABORT
:
243 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(map
))
244 fatalx("lde_dispatch_imsg: wrong imsg len");
245 memcpy(&map
, imsg
.data
, sizeof(map
));
247 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
249 log_debug("%s: cannot find lde neighbor",
254 switch (imsg
.hdr
.type
) {
255 case IMSG_LABEL_MAPPING
:
256 lde_check_mapping(&map
, ln
);
258 case IMSG_LABEL_REQUEST
:
259 lde_check_request(&map
, ln
);
261 case IMSG_LABEL_RELEASE
:
262 if (map
.type
== MAP_TYPE_WILDCARD
)
263 lde_check_release_wcard(&map
, ln
);
265 lde_check_release(&map
, ln
);
267 case IMSG_LABEL_WITHDRAW
:
268 if (map
.type
== MAP_TYPE_WILDCARD
)
269 lde_check_withdraw_wcard(&map
, ln
);
271 lde_check_withdraw(&map
, ln
);
273 case IMSG_LABEL_ABORT
:
278 case IMSG_ADDRESS_ADD
:
279 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
280 fatalx("lde_dispatch_imsg: wrong imsg len");
281 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
283 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
285 log_debug("%s: cannot find lde neighbor",
289 if (lde_address_add(ln
, &lde_addr
) < 0) {
290 log_debug("%s: cannot add address %s, it "
291 "already exists", __func__
,
292 log_addr(lde_addr
.af
, &lde_addr
.addr
));
295 case IMSG_ADDRESS_DEL
:
296 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
297 fatalx("lde_dispatch_imsg: wrong imsg len");
298 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
300 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
302 log_debug("%s: cannot find lde neighbor",
306 if (lde_address_del(ln
, &lde_addr
) < 0) {
307 log_debug("%s: cannot delete address %s, it "
308 "does not exist", __func__
,
309 log_addr(lde_addr
.af
, &lde_addr
.addr
));
312 case IMSG_NOTIFICATION
:
313 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(nm
))
314 fatalx("lde_dispatch_imsg: wrong imsg len");
315 memcpy(&nm
, imsg
.data
, sizeof(nm
));
317 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
319 log_debug("%s: cannot find lde neighbor",
324 switch (nm
.status_code
) {
326 l2vpn_recv_pw_status(ln
, &nm
);
332 case IMSG_NEIGHBOR_UP
:
333 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
334 sizeof(struct lde_nbr
))
335 fatalx("lde_dispatch_imsg: wrong imsg len");
337 if (lde_nbr_find(imsg
.hdr
.peerid
))
338 fatalx("lde_dispatch_imsg: "
339 "neighbor already exists");
340 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
342 case IMSG_NEIGHBOR_DOWN
:
343 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
345 case IMSG_CTL_SHOW_LIB
:
346 rt_dump(imsg
.hdr
.pid
);
348 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
349 imsg
.hdr
.pid
, NULL
, 0);
351 case IMSG_CTL_SHOW_L2VPN_PW
:
352 l2vpn_pw_ctl(imsg
.hdr
.pid
);
354 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
355 imsg
.hdr
.pid
, NULL
, 0);
357 case IMSG_CTL_SHOW_L2VPN_BINDING
:
358 l2vpn_binding_ctl(imsg
.hdr
.pid
);
360 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
361 imsg
.hdr
.pid
, NULL
, 0);
364 log_debug("%s: unexpected imsg %d", __func__
,
373 /* this pipe is dead, so remove the event handlers and exit */
374 THREAD_READ_OFF(iev
->ev_read
);
375 THREAD_WRITE_OFF(iev
->ev_write
);
384 lde_dispatch_parent(struct thread
*thread
)
386 static struct ldpd_conf
*nconf
;
387 struct iface
*niface
;
389 struct nbr_params
*nnbrp
;
390 static struct l2vpn
*nl2vpn
;
391 struct l2vpn_if
*nlif
;
392 struct l2vpn_pw
*npw
;
395 int fd
= THREAD_FD(thread
);
396 struct imsgev
*iev
= THREAD_ARG(thread
);
397 struct imsgbuf
*ibuf
= &iev
->ibuf
;
404 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
405 fatal("imsg_read error");
406 if (n
== 0) /* connection closed */
410 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
411 fatal("lde_dispatch_parent: imsg_get error");
415 switch (imsg
.hdr
.type
) {
416 case IMSG_NETWORK_ADD
:
417 case IMSG_NETWORK_UPDATE
:
418 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(kr
)) {
419 log_warnx("%s: wrong imsg len", __func__
);
422 memcpy(&kr
, imsg
.data
, sizeof(kr
));
426 fec
.type
= FEC_TYPE_IPV4
;
427 fec
.u
.ipv4
.prefix
= kr
.prefix
.v4
;
428 fec
.u
.ipv4
.prefixlen
= kr
.prefixlen
;
431 fec
.type
= FEC_TYPE_IPV6
;
432 fec
.u
.ipv6
.prefix
= kr
.prefix
.v6
;
433 fec
.u
.ipv6
.prefixlen
= kr
.prefixlen
;
436 fatalx("lde_dispatch_parent: unknown af");
439 switch (imsg
.hdr
.type
) {
440 case IMSG_NETWORK_ADD
:
441 lde_kernel_insert(&fec
, kr
.af
, &kr
.nexthop
,
442 kr
.ifindex
, kr
.priority
,
443 kr
.flags
& F_CONNECTED
, NULL
);
445 case IMSG_NETWORK_UPDATE
:
446 lde_kernel_update(&fec
);
450 case IMSG_SOCKET_IPC
:
452 log_warnx("%s: received unexpected imsg fd "
453 "to ldpe", __func__
);
456 if ((fd
= imsg
.fd
) == -1) {
457 log_warnx("%s: expected to receive imsg fd to "
458 "ldpe but didn't receive any", __func__
);
462 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
464 imsg_init(&iev_ldpe
->ibuf
, fd
);
465 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
466 iev_ldpe
->ev_read
= thread_add_read(master
,
467 iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
);
468 iev_ldpe
->handler_write
= ldp_write_handler
;
469 iev_ldpe
->ev_write
= NULL
;
471 case IMSG_RECONF_CONF
:
472 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
475 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
477 RB_INIT(&nconf
->iface_tree
);
478 RB_INIT(&nconf
->tnbr_tree
);
479 RB_INIT(&nconf
->nbrp_tree
);
480 RB_INIT(&nconf
->l2vpn_tree
);
482 case IMSG_RECONF_IFACE
:
483 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
485 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
487 LIST_INIT(&niface
->addr_list
);
488 RB_INIT(&niface
->ipv4
.adj_tree
);
489 RB_INIT(&niface
->ipv6
.adj_tree
);
490 niface
->ipv4
.iface
= niface
;
491 niface
->ipv6
.iface
= niface
;
493 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
495 case IMSG_RECONF_TNBR
:
496 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
498 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
500 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
502 case IMSG_RECONF_NBRP
:
503 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
505 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
507 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
509 case IMSG_RECONF_L2VPN
:
510 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
512 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
514 RB_INIT(&nl2vpn
->if_tree
);
515 RB_INIT(&nl2vpn
->pw_tree
);
516 RB_INIT(&nl2vpn
->pw_inactive_tree
);
518 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
520 case IMSG_RECONF_L2VPN_IF
:
521 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
523 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
525 nlif
->l2vpn
= nl2vpn
;
526 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
528 case IMSG_RECONF_L2VPN_PW
:
529 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
531 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
534 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
536 case IMSG_RECONF_L2VPN_IPW
:
537 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
539 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
542 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
544 case IMSG_RECONF_END
:
545 merge_config(ldeconf
, nconf
);
548 case IMSG_DEBUG_UPDATE
:
549 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
551 log_warnx("%s: wrong imsg len", __func__
);
554 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
557 log_debug("%s: unexpected imsg %d", __func__
,
566 /* this pipe is dead, so remove the event handlers and exit */
567 THREAD_READ_OFF(iev
->ev_read
);
568 THREAD_WRITE_OFF(iev
->ev_write
);
576 lde_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
578 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
582 lde_update_label(struct fec_node
*fn
)
584 static uint32_t label
= MPLS_LABEL_RESERVED_MAX
;
588 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
589 if (fnh
->flags
& F_FEC_NH_CONNECTED
) {
595 /* should we allocate a label for this fec? */
596 switch (fn
->fec
.type
) {
598 if ((ldeconf
->ipv4
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
599 fn
->fec
.u
.ipv4
.prefixlen
!= 32)
601 if (lde_acl_check(ldeconf
->ipv4
.acl_label_allocate_for
,
602 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
603 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
607 if ((ldeconf
->ipv6
.flags
& F_LDPD_AF_ALLOCHOSTONLY
) &&
608 fn
->fec
.u
.ipv6
.prefixlen
!= 128)
610 if (lde_acl_check(ldeconf
->ipv6
.acl_label_allocate_for
,
611 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
612 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
620 /* choose implicit or explicit-null depending on configuration */
621 switch (fn
->fec
.type
) {
623 if (!(ldeconf
->ipv4
.flags
& F_LDPD_AF_EXPNULL
))
624 return (MPLS_LABEL_IMPLNULL
);
625 if (lde_acl_check(ldeconf
->ipv4
.acl_label_expnull_for
,
626 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
627 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
628 return (MPLS_LABEL_IMPLNULL
);
629 return (MPLS_LABEL_IPV4NULL
);
631 if (!(ldeconf
->ipv6
.flags
& F_LDPD_AF_EXPNULL
))
632 return (MPLS_LABEL_IMPLNULL
);
633 if (lde_acl_check(ldeconf
->ipv6
.acl_label_expnull_for
,
634 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
635 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
636 return (MPLS_LABEL_IMPLNULL
);
637 return (MPLS_LABEL_IPV6NULL
);
639 fatalx("lde_update_label: unexpected fec type");
644 /* preserve current label if there's no need to update it */
645 if (fn
->local_label
!= NO_LABEL
&&
646 fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
647 return (fn
->local_label
);
650 * TODO: request label to zebra or define a range of labels for ldpd.
658 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
664 switch (fn
->fec
.type
) {
666 memset(&kr
, 0, sizeof(kr
));
668 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
669 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
670 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
671 kr
.ifindex
= fnh
->ifindex
;
672 kr
.local_label
= fn
->local_label
;
673 kr
.remote_label
= fnh
->remote_label
;
674 kr
.priority
= fnh
->priority
;
676 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
679 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
680 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
681 &fn
->fec
.u
.ipv4
.prefix
);
684 memset(&kr
, 0, sizeof(kr
));
686 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
687 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
688 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
689 kr
.ifindex
= fnh
->ifindex
;
690 kr
.local_label
= fn
->local_label
;
691 kr
.remote_label
= fnh
->remote_label
;
692 kr
.priority
= fnh
->priority
;
694 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
697 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
698 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
699 &fn
->fec
.u
.ipv6
.prefix
);
702 if (fn
->local_label
== NO_LABEL
||
703 fnh
->remote_label
== NO_LABEL
)
706 pw
= (struct l2vpn_pw
*) fn
->data
;
707 pw
->flags
|= F_PW_STATUS_UP
;
709 memset(&kpw
, 0, sizeof(kpw
));
710 kpw
.ifindex
= pw
->ifindex
;
711 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
713 kpw
.nexthop
= pw
->addr
;
714 kpw
.local_label
= fn
->local_label
;
715 kpw
.remote_label
= fnh
->remote_label
;
716 kpw
.flags
= pw
->flags
;
718 lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE
, 0, &kpw
,
725 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
731 switch (fn
->fec
.type
) {
733 memset(&kr
, 0, sizeof(kr
));
735 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
736 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
737 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
738 kr
.ifindex
= fnh
->ifindex
;
739 kr
.local_label
= fn
->local_label
;
740 kr
.remote_label
= fnh
->remote_label
;
741 kr
.priority
= fnh
->priority
;
743 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
746 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
747 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
748 &fn
->fec
.u
.ipv4
.prefix
);
751 memset(&kr
, 0, sizeof(kr
));
753 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
754 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
755 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
756 kr
.ifindex
= fnh
->ifindex
;
757 kr
.local_label
= fn
->local_label
;
758 kr
.remote_label
= fnh
->remote_label
;
759 kr
.priority
= fnh
->priority
;
761 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
764 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
765 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
766 &fn
->fec
.u
.ipv6
.prefix
);
769 pw
= (struct l2vpn_pw
*) fn
->data
;
770 if (!(pw
->flags
& F_PW_STATUS_UP
))
772 pw
->flags
&= ~F_PW_STATUS_UP
;
774 memset(&kpw
, 0, sizeof(kpw
));
775 kpw
.ifindex
= pw
->ifindex
;
776 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
778 kpw
.nexthop
= pw
->addr
;
779 kpw
.local_label
= fn
->local_label
;
780 kpw
.remote_label
= fnh
->remote_label
;
781 kpw
.flags
= pw
->flags
;
783 lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE
, 0, &kpw
,
790 lde_fec2map(struct fec
*fec
, struct map
*map
)
792 memset(map
, 0, sizeof(*map
));
796 map
->type
= MAP_TYPE_PREFIX
;
797 map
->fec
.prefix
.af
= AF_INET
;
798 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
799 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
802 map
->type
= MAP_TYPE_PREFIX
;
803 map
->fec
.prefix
.af
= AF_INET6
;
804 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
805 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
808 map
->type
= MAP_TYPE_PWID
;
809 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
810 map
->fec
.pwid
.group_id
= 0;
811 map
->flags
|= F_MAP_PW_ID
;
812 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
818 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
820 memset(fec
, 0, sizeof(*fec
));
823 case MAP_TYPE_PREFIX
:
824 switch (map
->fec
.prefix
.af
) {
826 fec
->type
= FEC_TYPE_IPV4
;
827 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
828 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
831 fec
->type
= FEC_TYPE_IPV6
;
832 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
833 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
836 fatalx("lde_map2fec: unknown af");
841 fec
->type
= FEC_TYPE_PWID
;
842 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
843 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
844 fec
->u
.pwid
.lsr_id
= lsr_id
;
850 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
858 * This function skips SL.1 - 3 and SL.9 - 14 because the label
859 * allocation is done way earlier (because of the merging nature of
863 lde_fec2map(&fn
->fec
, &map
);
864 switch (fn
->fec
.type
) {
868 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_to
,
869 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
871 if (lde_acl_check(ldeconf
->ipv4
.acl_label_advertise_for
,
872 AF_INET
, (union ldpd_addr
*)&fn
->fec
.u
.ipv4
.prefix
,
873 fn
->fec
.u
.ipv4
.prefixlen
) != FILTER_PERMIT
)
879 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_to
,
880 AF_INET
, (union ldpd_addr
*)&ln
->id
, 32) != FILTER_PERMIT
)
882 if (lde_acl_check(ldeconf
->ipv6
.acl_label_advertise_for
,
883 AF_INET6
, (union ldpd_addr
*)&fn
->fec
.u
.ipv6
.prefix
,
884 fn
->fec
.u
.ipv6
.prefixlen
) != FILTER_PERMIT
)
888 pw
= (struct l2vpn_pw
*) fn
->data
;
889 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
890 /* not the remote end of the pseudowire */
893 map
.flags
|= F_MAP_PW_IFMTU
;
894 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
895 if (pw
->flags
& F_PW_CWORD
)
896 map
.flags
|= F_MAP_PW_CWORD
;
897 if (pw
->flags
& F_PW_STATUSTLV
) {
898 map
.flags
|= F_MAP_PW_STATUS
;
899 /* VPLS are always up */
900 map
.pw_status
= PW_FORWARDING
;
904 map
.label
= fn
->local_label
;
906 /* SL.6: is there a pending request for this mapping? */
907 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
909 /* set label request msg id in the mapping response. */
910 map
.requestid
= lre
->msg_id
;
911 map
.flags
= F_MAP_REQ_ID
;
913 /* SL.7: delete record of pending request */
914 lde_req_del(ln
, lre
, 0);
917 /* SL.4: send label mapping */
918 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
921 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
924 /* SL.5: record sent label mapping */
925 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
927 me
= lde_map_add(ln
, fn
, 1);
932 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
,
933 struct status_tlv
*st
)
935 struct lde_wdraw
*lw
;
941 lde_fec2map(&fn
->fec
, &map
);
942 switch (fn
->fec
.type
) {
952 pw
= (struct l2vpn_pw
*) fn
->data
;
953 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
954 /* not the remote end of the pseudowire */
957 if (pw
->flags
& F_PW_CWORD
)
958 map
.flags
|= F_MAP_PW_CWORD
;
961 map
.label
= fn
->local_label
;
963 memset(&map
, 0, sizeof(map
));
964 map
.type
= MAP_TYPE_WILDCARD
;
969 map
.st
.status_code
= st
->status_code
;
970 map
.st
.msg_id
= st
->msg_id
;
971 map
.st
.msg_type
= st
->msg_type
;
972 map
.flags
|= F_MAP_STATUS
;
975 /* SWd.1: send label withdraw. */
976 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
978 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
980 /* SWd.2: record label withdraw. */
982 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
984 lw
= lde_wdraw_add(ln
, fn
);
985 lw
->label
= map
.label
;
987 RB_FOREACH(f
, fec_tree
, &ft
) {
988 fn
= (struct fec_node
*)f
;
990 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
993 lw
= lde_wdraw_add(ln
, fn
);
994 lw
->label
= map
.label
;
1000 lde_send_labelwithdraw_all(struct fec_node
*fn
, uint32_t label
)
1004 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1005 lde_send_labelwithdraw(ln
, fn
, label
, NULL
);
1009 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
)
1012 struct l2vpn_pw
*pw
;
1015 lde_fec2map(&fn
->fec
, &map
);
1016 switch (fn
->fec
.type
) {
1018 if (!ln
->v4_enabled
)
1022 if (!ln
->v6_enabled
)
1026 pw
= (struct l2vpn_pw
*) fn
->data
;
1027 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
1028 /* not the remote end of the pseudowire */
1031 if (pw
->flags
& F_PW_CWORD
)
1032 map
.flags
|= F_MAP_PW_CWORD
;
1036 memset(&map
, 0, sizeof(map
));
1037 map
.type
= MAP_TYPE_WILDCARD
;
1041 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
1043 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
1047 lde_send_notification(uint32_t peerid
, uint32_t status_code
, uint32_t msg_id
,
1050 struct notify_msg nm
;
1052 memset(&nm
, 0, sizeof(nm
));
1053 nm
.status_code
= status_code
;
1054 /* 'msg_id' and 'msg_type' should be in network byte order */
1056 nm
.msg_type
= msg_type
;
1058 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, peerid
, 0,
1063 lde_nbr_compare(struct lde_nbr
*a
, struct lde_nbr
*b
)
1065 return (a
->peerid
- b
->peerid
);
1068 static struct lde_nbr
*
1069 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
1073 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
1077 ln
->v4_enabled
= new->v4_enabled
;
1078 ln
->v6_enabled
= new->v6_enabled
;
1079 ln
->peerid
= peerid
;
1080 fec_init(&ln
->recv_map
);
1081 fec_init(&ln
->sent_map
);
1082 fec_init(&ln
->recv_req
);
1083 fec_init(&ln
->sent_req
);
1084 fec_init(&ln
->sent_wdraw
);
1086 TAILQ_INIT(&ln
->addr_list
);
1088 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1089 fatalx("lde_nbr_new: RB_INSERT failed");
1095 lde_nbr_del(struct lde_nbr
*ln
)
1098 struct fec_node
*fn
;
1100 struct l2vpn_pw
*pw
;
1105 /* uninstall received mappings */
1106 RB_FOREACH(f
, fec_tree
, &ft
) {
1107 fn
= (struct fec_node
*)f
;
1109 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1113 if (!lde_address_find(ln
, fnh
->af
,
1118 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1120 pw
= (struct l2vpn_pw
*) fn
->data
;
1128 lde_send_delete_klabel(fn
, fnh
);
1129 fnh
->remote_label
= NO_LABEL
;
1133 lde_address_list_free(ln
);
1135 fec_clear(&ln
->recv_map
, lde_map_free
);
1136 fec_clear(&ln
->sent_map
, lde_map_free
);
1137 fec_clear(&ln
->recv_req
, free
);
1138 fec_clear(&ln
->sent_req
, free
);
1139 fec_clear(&ln
->sent_wdraw
, free
);
1141 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1146 static struct lde_nbr
*
1147 lde_nbr_find(uint32_t peerid
)
1153 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1157 lde_nbr_find_by_lsrid(struct in_addr addr
)
1161 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1162 if (ln
->id
.s_addr
== addr
.s_addr
)
1169 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1173 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1174 if (lde_address_find(ln
, af
, addr
) != NULL
)
1185 while ((ln
= RB_ROOT(&lde_nbrs
)) != NULL
)
1190 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1193 struct fec_node
*fn
;
1197 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1198 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1199 switch (fec
->type
) {
1201 if (lde_addr
->af
!= AF_INET
)
1205 if (lde_addr
->af
!= AF_INET6
)
1212 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1213 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1218 lde_send_delete_klabel(fn
, fnh
);
1219 fnh
->remote_label
= NO_LABEL
;
1221 me
= (struct lde_map
*)fec
;
1222 fnh
->remote_label
= me
->map
.label
;
1223 lde_send_change_klabel(fn
, fnh
);
1231 lde_map_compare(struct lde_map
*a
, struct lde_map
*b
)
1233 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1234 (union ldpd_addr
*)&b
->nexthop
->id
));
1238 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1242 me
= calloc(1, sizeof(*me
));
1250 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1251 me
->head
= &fn
->upstream
;
1252 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1253 log_warnx("failed to add %s to sent map",
1255 /* XXX on failure more cleanup is needed */
1257 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1258 me
->head
= &fn
->downstream
;
1259 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1260 log_warnx("failed to add %s to recv map",
1268 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1271 fec_remove(&ln
->sent_map
, &me
->fec
);
1273 fec_remove(&ln
->recv_map
, &me
->fec
);
1279 lde_map_free(void *ptr
)
1281 struct lde_map
*map
= ptr
;
1283 RB_REMOVE(lde_map_head
, map
->head
, map
);
1288 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1291 struct lde_req
*lre
;
1293 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1295 lre
= calloc(1, sizeof(*lre
));
1299 if (fec_insert(t
, &lre
->fec
)) {
1300 log_warnx("failed to add %s to %s req",
1301 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1311 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1314 fec_remove(&ln
->sent_req
, &lre
->fec
);
1316 fec_remove(&ln
->recv_req
, &lre
->fec
);
1322 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1324 struct lde_wdraw
*lw
;
1326 lw
= calloc(1, sizeof(*lw
));
1332 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1333 log_warnx("failed to add %s to sent wdraw",
1340 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1342 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1347 lde_change_egress_label(int af
)
1351 struct fec_node
*fn
;
1353 /* explicitly withdraw all null labels */
1354 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1355 lde_send_labelwithdraw(ln
, NULL
, MPLS_LABEL_IMPLNULL
, NULL
);
1357 lde_send_labelwithdraw(ln
, NULL
, MPLS_LABEL_IPV4NULL
,
1360 lde_send_labelwithdraw(ln
, NULL
, MPLS_LABEL_IPV6NULL
,
1364 /* update label of connected routes */
1365 RB_FOREACH(f
, fec_tree
, &ft
) {
1366 fn
= (struct fec_node
*)f
;
1367 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1372 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1376 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1380 fatalx("lde_change_egress_label: unknown af");
1383 fn
->local_label
= lde_update_label(fn
);
1384 if (fn
->local_label
!= NO_LABEL
)
1385 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1386 lde_send_labelmapping(ln
, fn
, 0);
1388 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1389 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1394 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1396 struct lde_addr
*new;
1398 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
1401 if ((new = calloc(1, sizeof(*new))) == NULL
)
1404 new->af
= lde_addr
->af
;
1405 new->addr
= lde_addr
->addr
;
1406 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
1408 /* reevaluate the previously received mappings from this neighbor */
1409 lde_nbr_addr_update(ln
, lde_addr
, 0);
1415 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1417 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
1418 if (lde_addr
== NULL
)
1421 /* reevaluate the previously received mappings from this neighbor */
1422 lde_nbr_addr_update(ln
, lde_addr
, 1);
1424 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
1431 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
1433 struct lde_addr
*lde_addr
;
1435 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
1436 if (lde_addr
->af
== af
&&
1437 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
1444 lde_address_list_free(struct lde_nbr
*ln
)
1446 struct lde_addr
*lde_addr
;
1448 while ((lde_addr
= TAILQ_FIRST(&ln
->addr_list
)) != NULL
) {
1449 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);