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
;
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(QUAGGA_USER) && defined(QUAGGA_GROUP)
76 .group
= QUAGGA_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 pipe and event handler to the parent process */
137 if ((iev_main
= malloc(sizeof(struct imsgev
))) == NULL
)
139 imsg_init(&iev_main
->ibuf
, 3);
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
;
144 iev_main
->ev_write
= NULL
;
146 /* start the LIB garbage collector */
147 lde_gc_start_timer();
149 gettimeofday(&now
, NULL
);
150 global
.uptime
= now
.tv_sec
;
152 /* Fetch next active thread. */
153 while (thread_fetch(master
, &thread
))
154 thread_call(&thread
);
161 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
162 close(iev_ldpe
->ibuf
.fd
);
163 msgbuf_clear(&iev_main
->ibuf
.w
);
164 close(iev_main
->ibuf
.fd
);
170 config_clear(ldeconf
);
175 log_info("label decision engine exiting");
181 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
183 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
187 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
190 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
196 lde_dispatch_imsg(struct thread
*thread
)
198 struct imsgev
*iev
= THREAD_ARG(thread
);
199 struct imsgbuf
*ibuf
= &iev
->ibuf
;
203 struct lde_addr lde_addr
;
204 struct notify_msg nm
;
210 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
211 fatal("imsg_read error");
212 if (n
== 0) /* connection closed */
216 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
217 fatal("lde_dispatch_imsg: imsg_get error");
221 switch (imsg
.hdr
.type
) {
222 case IMSG_LABEL_MAPPING_FULL
:
223 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
225 log_debug("%s: cannot find lde neighbor",
232 case IMSG_LABEL_MAPPING
:
233 case IMSG_LABEL_REQUEST
:
234 case IMSG_LABEL_RELEASE
:
235 case IMSG_LABEL_WITHDRAW
:
236 case IMSG_LABEL_ABORT
:
237 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(map
))
238 fatalx("lde_dispatch_imsg: wrong imsg len");
239 memcpy(&map
, imsg
.data
, sizeof(map
));
241 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
243 log_debug("%s: cannot find lde neighbor",
248 switch (imsg
.hdr
.type
) {
249 case IMSG_LABEL_MAPPING
:
250 lde_check_mapping(&map
, ln
);
252 case IMSG_LABEL_REQUEST
:
253 lde_check_request(&map
, ln
);
255 case IMSG_LABEL_RELEASE
:
256 if (map
.type
== MAP_TYPE_WILDCARD
)
257 lde_check_release_wcard(&map
, ln
);
259 lde_check_release(&map
, ln
);
261 case IMSG_LABEL_WITHDRAW
:
262 if (map
.type
== MAP_TYPE_WILDCARD
)
263 lde_check_withdraw_wcard(&map
, ln
);
265 lde_check_withdraw(&map
, ln
);
267 case IMSG_LABEL_ABORT
:
272 case IMSG_ADDRESS_ADD
:
273 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
274 fatalx("lde_dispatch_imsg: wrong imsg len");
275 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
277 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
279 log_debug("%s: cannot find lde neighbor",
283 if (lde_address_add(ln
, &lde_addr
) < 0) {
284 log_debug("%s: cannot add address %s, it "
285 "already exists", __func__
,
286 log_addr(lde_addr
.af
, &lde_addr
.addr
));
289 case IMSG_ADDRESS_DEL
:
290 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
291 fatalx("lde_dispatch_imsg: wrong imsg len");
292 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
294 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
296 log_debug("%s: cannot find lde neighbor",
300 if (lde_address_del(ln
, &lde_addr
) < 0) {
301 log_debug("%s: cannot delete address %s, it "
302 "does not exist", __func__
,
303 log_addr(lde_addr
.af
, &lde_addr
.addr
));
306 case IMSG_NOTIFICATION
:
307 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(nm
))
308 fatalx("lde_dispatch_imsg: wrong imsg len");
309 memcpy(&nm
, imsg
.data
, sizeof(nm
));
311 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
313 log_debug("%s: cannot find lde neighbor",
318 switch (nm
.status_code
) {
320 l2vpn_recv_pw_status(ln
, &nm
);
326 case IMSG_NEIGHBOR_UP
:
327 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
328 sizeof(struct lde_nbr
))
329 fatalx("lde_dispatch_imsg: wrong imsg len");
331 if (lde_nbr_find(imsg
.hdr
.peerid
))
332 fatalx("lde_dispatch_imsg: "
333 "neighbor already exists");
334 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
336 case IMSG_NEIGHBOR_DOWN
:
337 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
339 case IMSG_CTL_SHOW_LIB
:
340 rt_dump(imsg
.hdr
.pid
);
342 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
343 imsg
.hdr
.pid
, NULL
, 0);
345 case IMSG_CTL_SHOW_L2VPN_PW
:
346 l2vpn_pw_ctl(imsg
.hdr
.pid
);
348 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
349 imsg
.hdr
.pid
, NULL
, 0);
351 case IMSG_CTL_SHOW_L2VPN_BINDING
:
352 l2vpn_binding_ctl(imsg
.hdr
.pid
);
354 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
355 imsg
.hdr
.pid
, NULL
, 0);
358 log_debug("%s: unexpected imsg %d", __func__
,
367 /* this pipe is dead, so remove the event handlers and exit */
368 THREAD_READ_OFF(iev
->ev_read
);
369 THREAD_WRITE_OFF(iev
->ev_write
);
378 lde_dispatch_parent(struct thread
*thread
)
380 static struct ldpd_conf
*nconf
;
381 struct iface
*niface
;
383 struct nbr_params
*nnbrp
;
384 static struct l2vpn
*nl2vpn
;
385 struct l2vpn_if
*nlif
;
386 struct l2vpn_pw
*npw
;
389 int fd
= THREAD_FD(thread
);
390 struct imsgev
*iev
= THREAD_ARG(thread
);
391 struct imsgbuf
*ibuf
= &iev
->ibuf
;
398 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
399 fatal("imsg_read error");
400 if (n
== 0) /* connection closed */
404 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
405 fatal("lde_dispatch_parent: imsg_get error");
409 switch (imsg
.hdr
.type
) {
410 case IMSG_NETWORK_ADD
:
411 case IMSG_NETWORK_ADD_END
:
412 case IMSG_NETWORK_DEL
:
413 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(kr
)) {
414 log_warnx("%s: wrong imsg len", __func__
);
417 memcpy(&kr
, imsg
.data
, sizeof(kr
));
421 fec
.type
= FEC_TYPE_IPV4
;
422 fec
.u
.ipv4
.prefix
= kr
.prefix
.v4
;
423 fec
.u
.ipv4
.prefixlen
= kr
.prefixlen
;
426 fec
.type
= FEC_TYPE_IPV6
;
427 fec
.u
.ipv6
.prefix
= kr
.prefix
.v6
;
428 fec
.u
.ipv6
.prefixlen
= kr
.prefixlen
;
431 fatalx("lde_dispatch_parent: unknown af");
434 switch (imsg
.hdr
.type
) {
435 case IMSG_NETWORK_ADD
:
436 lde_kernel_insert(&fec
, kr
.af
, &kr
.nexthop
,
437 kr
.ifindex
, kr
.priority
,
438 kr
.flags
& F_CONNECTED
, NULL
);
440 case IMSG_NETWORK_ADD_END
:
441 lde_kernel_reevaluate(&fec
);
443 case IMSG_NETWORK_DEL
:
444 lde_kernel_remove(&fec
, kr
.af
, &kr
.nexthop
,
445 kr
.ifindex
, kr
.priority
);
449 case IMSG_SOCKET_IPC
:
451 log_warnx("%s: received unexpected imsg fd "
452 "to ldpe", __func__
);
455 if ((fd
= imsg
.fd
) == -1) {
456 log_warnx("%s: expected to receive imsg fd to "
457 "ldpe but didn't receive any", __func__
);
461 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
463 imsg_init(&iev_ldpe
->ibuf
, fd
);
464 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
465 iev_ldpe
->ev_read
= thread_add_read(master
,
466 iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
);
467 iev_ldpe
->handler_write
= ldp_write_handler
;
468 iev_ldpe
->ev_write
= NULL
;
470 case IMSG_RECONF_CONF
:
471 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
474 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
476 RB_INIT(&nconf
->iface_tree
);
477 RB_INIT(&nconf
->tnbr_tree
);
478 RB_INIT(&nconf
->nbrp_tree
);
479 RB_INIT(&nconf
->l2vpn_tree
);
481 case IMSG_RECONF_IFACE
:
482 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
484 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
486 LIST_INIT(&niface
->addr_list
);
487 LIST_INIT(&niface
->ipv4
.adj_list
);
488 LIST_INIT(&niface
->ipv6
.adj_list
);
489 niface
->ipv4
.iface
= niface
;
490 niface
->ipv6
.iface
= niface
;
492 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
494 case IMSG_RECONF_TNBR
:
495 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
497 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
499 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
501 case IMSG_RECONF_NBRP
:
502 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
504 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
506 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
508 case IMSG_RECONF_L2VPN
:
509 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
511 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
513 RB_INIT(&nl2vpn
->if_tree
);
514 RB_INIT(&nl2vpn
->pw_tree
);
515 RB_INIT(&nl2vpn
->pw_inactive_tree
);
517 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
519 case IMSG_RECONF_L2VPN_IF
:
520 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
522 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
524 nlif
->l2vpn
= nl2vpn
;
525 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
527 case IMSG_RECONF_L2VPN_PW
:
528 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
530 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
533 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
535 case IMSG_RECONF_L2VPN_IPW
:
536 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
538 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
541 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
543 case IMSG_RECONF_END
:
544 merge_config(ldeconf
, nconf
);
547 case IMSG_DEBUG_UPDATE
:
548 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
550 log_warnx("%s: wrong imsg len", __func__
);
553 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
556 log_debug("%s: unexpected imsg %d", __func__
,
565 /* this pipe is dead, so remove the event handlers and exit */
566 THREAD_READ_OFF(iev
->ev_read
);
567 THREAD_WRITE_OFF(iev
->ev_write
);
575 lde_assign_label(void)
577 static uint32_t label
= MPLS_LABEL_RESERVED_MAX
;
580 * TODO: request label to zebra or define a range of labels for ldpd.
588 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
594 switch (fn
->fec
.type
) {
596 memset(&kr
, 0, sizeof(kr
));
598 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
599 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
600 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
601 kr
.ifindex
= fnh
->ifindex
;
602 kr
.local_label
= fn
->local_label
;
603 kr
.remote_label
= fnh
->remote_label
;
604 kr
.priority
= fnh
->priority
;
606 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
609 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
610 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
611 &fn
->fec
.u
.ipv4
.prefix
);
614 memset(&kr
, 0, sizeof(kr
));
616 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
617 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
618 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
619 kr
.ifindex
= fnh
->ifindex
;
620 kr
.local_label
= fn
->local_label
;
621 kr
.remote_label
= fnh
->remote_label
;
622 kr
.priority
= fnh
->priority
;
624 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
627 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
628 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
629 &fn
->fec
.u
.ipv6
.prefix
);
632 if (fn
->local_label
== NO_LABEL
||
633 fnh
->remote_label
== NO_LABEL
)
636 pw
= (struct l2vpn_pw
*) fn
->data
;
637 pw
->flags
|= F_PW_STATUS_UP
;
639 memset(&kpw
, 0, sizeof(kpw
));
640 kpw
.ifindex
= pw
->ifindex
;
641 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
643 kpw
.nexthop
= pw
->addr
;
644 kpw
.local_label
= fn
->local_label
;
645 kpw
.remote_label
= fnh
->remote_label
;
646 kpw
.flags
= pw
->flags
;
648 lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE
, 0, &kpw
,
655 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
661 switch (fn
->fec
.type
) {
663 memset(&kr
, 0, sizeof(kr
));
665 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
666 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
667 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
668 kr
.ifindex
= fnh
->ifindex
;
669 kr
.local_label
= fn
->local_label
;
670 kr
.remote_label
= fnh
->remote_label
;
671 kr
.priority
= fnh
->priority
;
673 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
676 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
677 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
678 &fn
->fec
.u
.ipv4
.prefix
);
681 memset(&kr
, 0, sizeof(kr
));
683 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
684 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
685 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
686 kr
.ifindex
= fnh
->ifindex
;
687 kr
.local_label
= fn
->local_label
;
688 kr
.remote_label
= fnh
->remote_label
;
689 kr
.priority
= fnh
->priority
;
691 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
694 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
695 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
696 &fn
->fec
.u
.ipv6
.prefix
);
699 pw
= (struct l2vpn_pw
*) fn
->data
;
700 if (!(pw
->flags
& F_PW_STATUS_UP
))
702 pw
->flags
&= ~F_PW_STATUS_UP
;
704 memset(&kpw
, 0, sizeof(kpw
));
705 kpw
.ifindex
= pw
->ifindex
;
706 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
708 kpw
.nexthop
= pw
->addr
;
709 kpw
.local_label
= fn
->local_label
;
710 kpw
.remote_label
= fnh
->remote_label
;
711 kpw
.flags
= pw
->flags
;
713 lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE
, 0, &kpw
,
720 lde_fec2map(struct fec
*fec
, struct map
*map
)
722 memset(map
, 0, sizeof(*map
));
726 map
->type
= MAP_TYPE_PREFIX
;
727 map
->fec
.prefix
.af
= AF_INET
;
728 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
729 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
732 map
->type
= MAP_TYPE_PREFIX
;
733 map
->fec
.prefix
.af
= AF_INET6
;
734 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
735 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
738 map
->type
= MAP_TYPE_PWID
;
739 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
740 map
->fec
.pwid
.group_id
= 0;
741 map
->flags
|= F_MAP_PW_ID
;
742 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
748 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
750 memset(fec
, 0, sizeof(*fec
));
753 case MAP_TYPE_PREFIX
:
754 switch (map
->fec
.prefix
.af
) {
756 fec
->type
= FEC_TYPE_IPV4
;
757 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
758 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
761 fec
->type
= FEC_TYPE_IPV6
;
762 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
763 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
766 fatalx("lde_map2fec: unknown af");
771 fec
->type
= FEC_TYPE_PWID
;
772 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
773 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
774 fec
->u
.pwid
.lsr_id
= lsr_id
;
780 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
788 * This function skips SL.1 - 3 and SL.9 - 14 because the label
789 * allocation is done way earlier (because of the merging nature of
793 lde_fec2map(&fn
->fec
, &map
);
794 switch (fn
->fec
.type
) {
804 pw
= (struct l2vpn_pw
*) fn
->data
;
805 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
806 /* not the remote end of the pseudowire */
809 map
.flags
|= F_MAP_PW_IFMTU
;
810 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
811 if (pw
->flags
& F_PW_CWORD
)
812 map
.flags
|= F_MAP_PW_CWORD
;
813 if (pw
->flags
& F_PW_STATUSTLV
) {
814 map
.flags
|= F_MAP_PW_STATUS
;
815 /* VPLS are always up */
816 map
.pw_status
= PW_FORWARDING
;
820 map
.label
= fn
->local_label
;
822 /* SL.6: is there a pending request for this mapping? */
823 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
825 /* set label request msg id in the mapping response. */
826 map
.requestid
= lre
->msg_id
;
827 map
.flags
= F_MAP_REQ_ID
;
829 /* SL.7: delete record of pending request */
830 lde_req_del(ln
, lre
, 0);
833 /* SL.4: send label mapping */
834 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
837 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
840 /* SL.5: record sent label mapping */
841 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
843 me
= lde_map_add(ln
, fn
, 1);
848 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
,
849 struct status_tlv
*st
)
851 struct lde_wdraw
*lw
;
857 lde_fec2map(&fn
->fec
, &map
);
858 switch (fn
->fec
.type
) {
868 pw
= (struct l2vpn_pw
*) fn
->data
;
869 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
870 /* not the remote end of the pseudowire */
873 if (pw
->flags
& F_PW_CWORD
)
874 map
.flags
|= F_MAP_PW_CWORD
;
877 map
.label
= fn
->local_label
;
879 memset(&map
, 0, sizeof(map
));
880 map
.type
= MAP_TYPE_WILDCARD
;
885 map
.st
.status_code
= st
->status_code
;
886 map
.st
.msg_id
= st
->msg_id
;
887 map
.st
.msg_type
= st
->msg_type
;
888 map
.flags
|= F_MAP_STATUS
;
891 /* SWd.1: send label withdraw. */
892 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
894 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
896 /* SWd.2: record label withdraw. */
898 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
900 lw
= lde_wdraw_add(ln
, fn
);
901 lw
->label
= map
.label
;
903 RB_FOREACH(f
, fec_tree
, &ft
) {
904 fn
= (struct fec_node
*)f
;
906 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
909 lw
= lde_wdraw_add(ln
, fn
);
910 lw
->label
= map
.label
;
916 lde_send_labelwithdraw_all(struct fec_node
*fn
, uint32_t label
)
920 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
921 lde_send_labelwithdraw(ln
, fn
, label
, NULL
);
925 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
)
931 lde_fec2map(&fn
->fec
, &map
);
932 switch (fn
->fec
.type
) {
942 pw
= (struct l2vpn_pw
*) fn
->data
;
943 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
944 /* not the remote end of the pseudowire */
947 if (pw
->flags
& F_PW_CWORD
)
948 map
.flags
|= F_MAP_PW_CWORD
;
952 memset(&map
, 0, sizeof(map
));
953 map
.type
= MAP_TYPE_WILDCARD
;
957 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
959 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
963 lde_send_notification(uint32_t peerid
, uint32_t status_code
, uint32_t msg_id
,
966 struct notify_msg nm
;
968 memset(&nm
, 0, sizeof(nm
));
969 nm
.status_code
= status_code
;
970 /* 'msg_id' and 'msg_type' should be in network byte order */
972 nm
.msg_type
= msg_type
;
974 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, peerid
, 0,
979 lde_nbr_compare(struct lde_nbr
*a
, struct lde_nbr
*b
)
981 return (a
->peerid
- b
->peerid
);
984 static struct lde_nbr
*
985 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
989 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
993 ln
->v4_enabled
= new->v4_enabled
;
994 ln
->v6_enabled
= new->v6_enabled
;
996 fec_init(&ln
->recv_map
);
997 fec_init(&ln
->sent_map
);
998 fec_init(&ln
->recv_req
);
999 fec_init(&ln
->sent_req
);
1000 fec_init(&ln
->sent_wdraw
);
1002 TAILQ_INIT(&ln
->addr_list
);
1004 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
1005 fatalx("lde_nbr_new: RB_INSERT failed");
1011 lde_nbr_del(struct lde_nbr
*ln
)
1014 struct fec_node
*fn
;
1016 struct l2vpn_pw
*pw
;
1021 /* uninstall received mappings */
1022 RB_FOREACH(f
, fec_tree
, &ft
) {
1023 fn
= (struct fec_node
*)f
;
1025 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1029 if (!lde_address_find(ln
, fnh
->af
,
1034 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1036 pw
= (struct l2vpn_pw
*) fn
->data
;
1044 lde_send_delete_klabel(fn
, fnh
);
1045 fnh
->remote_label
= NO_LABEL
;
1049 lde_address_list_free(ln
);
1051 fec_clear(&ln
->recv_map
, lde_map_free
);
1052 fec_clear(&ln
->sent_map
, lde_map_free
);
1053 fec_clear(&ln
->recv_req
, free
);
1054 fec_clear(&ln
->sent_req
, free
);
1055 fec_clear(&ln
->sent_wdraw
, free
);
1057 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1062 static struct lde_nbr
*
1063 lde_nbr_find(uint32_t peerid
)
1069 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1073 lde_nbr_find_by_lsrid(struct in_addr addr
)
1077 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1078 if (ln
->id
.s_addr
== addr
.s_addr
)
1085 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1089 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1090 if (lde_address_find(ln
, af
, addr
) != NULL
)
1101 while ((ln
= RB_ROOT(&lde_nbrs
)) != NULL
)
1106 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1109 struct fec_node
*fn
;
1113 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1114 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1115 switch (fec
->type
) {
1117 if (lde_addr
->af
!= AF_INET
)
1121 if (lde_addr
->af
!= AF_INET6
)
1128 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1129 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1134 lde_send_delete_klabel(fn
, fnh
);
1135 fnh
->remote_label
= NO_LABEL
;
1137 me
= (struct lde_map
*)fec
;
1138 fnh
->remote_label
= me
->map
.label
;
1139 lde_send_change_klabel(fn
, fnh
);
1147 lde_map_compare(struct lde_map
*a
, struct lde_map
*b
)
1149 return (ldp_addrcmp(AF_INET
, (union ldpd_addr
*)&a
->nexthop
->id
,
1150 (union ldpd_addr
*)&b
->nexthop
->id
));
1154 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1158 me
= calloc(1, sizeof(*me
));
1166 RB_INSERT(lde_map_head
, &fn
->upstream
, me
);
1167 me
->head
= &fn
->upstream
;
1168 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1169 log_warnx("failed to add %s to sent map",
1171 /* XXX on failure more cleanup is needed */
1173 RB_INSERT(lde_map_head
, &fn
->downstream
, me
);
1174 me
->head
= &fn
->downstream
;
1175 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1176 log_warnx("failed to add %s to recv map",
1184 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1187 fec_remove(&ln
->sent_map
, &me
->fec
);
1189 fec_remove(&ln
->recv_map
, &me
->fec
);
1195 lde_map_free(void *ptr
)
1197 struct lde_map
*map
= ptr
;
1199 RB_REMOVE(lde_map_head
, map
->head
, map
);
1204 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1207 struct lde_req
*lre
;
1209 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1211 lre
= calloc(1, sizeof(*lre
));
1215 if (fec_insert(t
, &lre
->fec
)) {
1216 log_warnx("failed to add %s to %s req",
1217 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1227 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1230 fec_remove(&ln
->sent_req
, &lre
->fec
);
1232 fec_remove(&ln
->recv_req
, &lre
->fec
);
1238 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1240 struct lde_wdraw
*lw
;
1242 lw
= calloc(1, sizeof(*lw
));
1248 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1249 log_warnx("failed to add %s to sent wdraw",
1256 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1258 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1263 lde_change_egress_label(int af
, int was_implicit
)
1267 struct fec_node
*fn
;
1269 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1270 /* explicit withdraw */
1272 lde_send_labelwithdraw(ln
, NULL
, MPLS_LABEL_IMPLNULL
,
1276 lde_send_labelwithdraw(ln
, NULL
,
1277 MPLS_LABEL_IPV4NULL
, NULL
);
1279 lde_send_labelwithdraw(ln
, NULL
,
1280 MPLS_LABEL_IPV6NULL
, NULL
);
1283 /* advertise new label of connected prefixes */
1284 RB_FOREACH(f
, fec_tree
, &ft
) {
1285 fn
= (struct fec_node
*)f
;
1286 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1291 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1295 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1299 fatalx("lde_change_egress_label: unknown af");
1302 fn
->local_label
= egress_label(fn
->fec
.type
);
1303 lde_send_labelmapping(ln
, fn
, 0);
1306 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1312 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1314 struct lde_addr
*new;
1316 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
1319 if ((new = calloc(1, sizeof(*new))) == NULL
)
1322 new->af
= lde_addr
->af
;
1323 new->addr
= lde_addr
->addr
;
1324 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
1326 /* reevaluate the previously received mappings from this neighbor */
1327 lde_nbr_addr_update(ln
, lde_addr
, 0);
1333 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1335 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
1336 if (lde_addr
== NULL
)
1339 /* reevaluate the previously received mappings from this neighbor */
1340 lde_nbr_addr_update(ln
, lde_addr
, 1);
1342 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
1349 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
1351 struct lde_addr
*lde_addr
;
1353 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
1354 if (lde_addr
->af
== af
&&
1355 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
1362 lde_address_list_free(struct lde_nbr
*ln
)
1364 struct lde_addr
*lde_addr
;
1366 while ((lde_addr
= TAILQ_FIRST(&ln
->addr_list
)) != NULL
) {
1367 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);