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 void lde_map_free(void *);
49 static int lde_address_add(struct lde_nbr
*, struct lde_addr
*);
50 static int lde_address_del(struct lde_nbr
*, struct lde_addr
*);
51 static void lde_address_list_free(struct lde_nbr
*);
53 RB_GENERATE(nbr_tree
, lde_nbr
, entry
, lde_nbr_compare
)
55 struct ldpd_conf
*ldeconf
;
56 struct nbr_tree lde_nbrs
= RB_INITIALIZER(&lde_nbrs
);
58 static struct imsgev
*iev_ldpe
;
59 static struct imsgev
*iev_main
;
61 /* Master of threads. */
62 struct thread_master
*master
;
65 static zebra_capabilities_t _caps_p
[] =
70 static struct zebra_privs_t lde_privs
=
72 #if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
74 .group
= QUAGGA_GROUP
,
76 #if defined(VTY_GROUP)
77 .vty_group
= VTY_GROUP
,
80 .cap_num_p
= array_size(_caps_p
),
84 /* SIGINT / SIGTERM handler. */
91 static struct quagga_signal_t lde_signals
[] =
103 /* label decision engine */
105 lde(const char *user
, const char *group
)
107 struct thread thread
;
110 ldeconf
= config_new_empty();
112 #ifdef HAVE_SETPROCTITLE
113 setproctitle("label decision engine");
115 ldpd_process
= PROC_LDE_ENGINE
;
117 /* drop privileges */
119 lde_privs
.user
= user
;
121 lde_privs
.group
= group
;
122 zprivs_init(&lde_privs
);
125 if (pledge("stdio recvfd", NULL
) == -1)
129 master
= thread_master_create();
131 /* setup signal handler */
132 signal_init(master
, array_size(lde_signals
), lde_signals
);
134 /* setup pipe and event handler to the parent process */
135 if ((iev_main
= malloc(sizeof(struct imsgev
))) == NULL
)
137 imsg_init(&iev_main
->ibuf
, 3);
138 iev_main
->handler_read
= lde_dispatch_parent
;
139 iev_main
->ev_read
= thread_add_read(master
, iev_main
->handler_read
,
140 iev_main
, iev_main
->ibuf
.fd
);
141 iev_main
->handler_write
= ldp_write_handler
;
142 iev_main
->ev_write
= NULL
;
144 /* start the LIB garbage collector */
145 lde_gc_start_timer();
147 gettimeofday(&now
, NULL
);
148 global
.uptime
= now
.tv_sec
;
150 /* Fetch next active thread. */
151 while (thread_fetch(master
, &thread
))
152 thread_call(&thread
);
159 msgbuf_clear(&iev_ldpe
->ibuf
.w
);
160 close(iev_ldpe
->ibuf
.fd
);
161 msgbuf_clear(&iev_main
->ibuf
.w
);
162 close(iev_main
->ibuf
.fd
);
168 config_clear(ldeconf
);
173 log_info("label decision engine exiting");
179 lde_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
181 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
185 lde_imsg_compose_ldpe(int type
, uint32_t peerid
, pid_t pid
, void *data
,
188 return (imsg_compose_event(iev_ldpe
, type
, peerid
, pid
,
194 lde_dispatch_imsg(struct thread
*thread
)
196 struct imsgev
*iev
= THREAD_ARG(thread
);
197 struct imsgbuf
*ibuf
= &iev
->ibuf
;
201 struct lde_addr lde_addr
;
202 struct notify_msg nm
;
208 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
209 fatal("imsg_read error");
210 if (n
== 0) /* connection closed */
214 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
215 fatal("lde_dispatch_imsg: imsg_get error");
219 switch (imsg
.hdr
.type
) {
220 case IMSG_LABEL_MAPPING_FULL
:
221 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
223 log_debug("%s: cannot find lde neighbor",
230 case IMSG_LABEL_MAPPING
:
231 case IMSG_LABEL_REQUEST
:
232 case IMSG_LABEL_RELEASE
:
233 case IMSG_LABEL_WITHDRAW
:
234 case IMSG_LABEL_ABORT
:
235 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(map
))
236 fatalx("lde_dispatch_imsg: wrong imsg len");
237 memcpy(&map
, imsg
.data
, sizeof(map
));
239 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
241 log_debug("%s: cannot find lde neighbor",
246 switch (imsg
.hdr
.type
) {
247 case IMSG_LABEL_MAPPING
:
248 lde_check_mapping(&map
, ln
);
250 case IMSG_LABEL_REQUEST
:
251 lde_check_request(&map
, ln
);
253 case IMSG_LABEL_RELEASE
:
254 if (map
.type
== MAP_TYPE_WILDCARD
)
255 lde_check_release_wcard(&map
, ln
);
257 lde_check_release(&map
, ln
);
259 case IMSG_LABEL_WITHDRAW
:
260 if (map
.type
== MAP_TYPE_WILDCARD
)
261 lde_check_withdraw_wcard(&map
, ln
);
263 lde_check_withdraw(&map
, ln
);
265 case IMSG_LABEL_ABORT
:
270 case IMSG_ADDRESS_ADD
:
271 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
272 fatalx("lde_dispatch_imsg: wrong imsg len");
273 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
275 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
277 log_debug("%s: cannot find lde neighbor",
281 if (lde_address_add(ln
, &lde_addr
) < 0) {
282 log_debug("%s: cannot add address %s, it "
283 "already exists", __func__
,
284 log_addr(lde_addr
.af
, &lde_addr
.addr
));
287 case IMSG_ADDRESS_DEL
:
288 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(lde_addr
))
289 fatalx("lde_dispatch_imsg: wrong imsg len");
290 memcpy(&lde_addr
, imsg
.data
, sizeof(lde_addr
));
292 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
294 log_debug("%s: cannot find lde neighbor",
298 if (lde_address_del(ln
, &lde_addr
) < 0) {
299 log_debug("%s: cannot delete address %s, it "
300 "does not exist", __func__
,
301 log_addr(lde_addr
.af
, &lde_addr
.addr
));
304 case IMSG_NOTIFICATION
:
305 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(nm
))
306 fatalx("lde_dispatch_imsg: wrong imsg len");
307 memcpy(&nm
, imsg
.data
, sizeof(nm
));
309 ln
= lde_nbr_find(imsg
.hdr
.peerid
);
311 log_debug("%s: cannot find lde neighbor",
316 switch (nm
.status_code
) {
318 l2vpn_recv_pw_status(ln
, &nm
);
324 case IMSG_NEIGHBOR_UP
:
325 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
326 sizeof(struct lde_nbr
))
327 fatalx("lde_dispatch_imsg: wrong imsg len");
329 if (lde_nbr_find(imsg
.hdr
.peerid
))
330 fatalx("lde_dispatch_imsg: "
331 "neighbor already exists");
332 lde_nbr_new(imsg
.hdr
.peerid
, imsg
.data
);
334 case IMSG_NEIGHBOR_DOWN
:
335 lde_nbr_del(lde_nbr_find(imsg
.hdr
.peerid
));
337 case IMSG_CTL_SHOW_LIB
:
338 rt_dump(imsg
.hdr
.pid
);
340 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
341 imsg
.hdr
.pid
, NULL
, 0);
343 case IMSG_CTL_SHOW_L2VPN_PW
:
344 l2vpn_pw_ctl(imsg
.hdr
.pid
);
346 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
347 imsg
.hdr
.pid
, NULL
, 0);
349 case IMSG_CTL_SHOW_L2VPN_BINDING
:
350 l2vpn_binding_ctl(imsg
.hdr
.pid
);
352 lde_imsg_compose_ldpe(IMSG_CTL_END
, 0,
353 imsg
.hdr
.pid
, NULL
, 0);
356 log_debug("%s: unexpected imsg %d", __func__
,
365 /* this pipe is dead, so remove the event handlers and exit */
366 THREAD_READ_OFF(iev
->ev_read
);
367 THREAD_WRITE_OFF(iev
->ev_write
);
376 lde_dispatch_parent(struct thread
*thread
)
378 static struct ldpd_conf
*nconf
;
379 struct iface
*niface
;
381 struct nbr_params
*nnbrp
;
382 static struct l2vpn
*nl2vpn
;
383 struct l2vpn_if
*nlif
;
384 struct l2vpn_pw
*npw
;
387 int fd
= THREAD_FD(thread
);
388 struct imsgev
*iev
= THREAD_ARG(thread
);
389 struct imsgbuf
*ibuf
= &iev
->ibuf
;
396 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
397 fatal("imsg_read error");
398 if (n
== 0) /* connection closed */
402 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
403 fatal("lde_dispatch_parent: imsg_get error");
407 switch (imsg
.hdr
.type
) {
408 case IMSG_NETWORK_ADD
:
409 case IMSG_NETWORK_ADD_END
:
410 case IMSG_NETWORK_DEL
:
411 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(kr
)) {
412 log_warnx("%s: wrong imsg len", __func__
);
415 memcpy(&kr
, imsg
.data
, sizeof(kr
));
419 fec
.type
= FEC_TYPE_IPV4
;
420 fec
.u
.ipv4
.prefix
= kr
.prefix
.v4
;
421 fec
.u
.ipv4
.prefixlen
= kr
.prefixlen
;
424 fec
.type
= FEC_TYPE_IPV6
;
425 fec
.u
.ipv6
.prefix
= kr
.prefix
.v6
;
426 fec
.u
.ipv6
.prefixlen
= kr
.prefixlen
;
429 fatalx("lde_dispatch_parent: unknown af");
432 switch (imsg
.hdr
.type
) {
433 case IMSG_NETWORK_ADD
:
434 lde_kernel_insert(&fec
, kr
.af
, &kr
.nexthop
,
435 kr
.priority
, kr
.flags
& F_CONNECTED
, NULL
);
437 case IMSG_NETWORK_ADD_END
:
438 lde_kernel_reevaluate(&fec
);
440 case IMSG_NETWORK_DEL
:
441 lde_kernel_remove(&fec
, kr
.af
, &kr
.nexthop
,
446 case IMSG_SOCKET_IPC
:
448 log_warnx("%s: received unexpected imsg fd "
449 "to ldpe", __func__
);
452 if ((fd
= imsg
.fd
) == -1) {
453 log_warnx("%s: expected to receive imsg fd to "
454 "ldpe but didn't receive any", __func__
);
458 if ((iev_ldpe
= malloc(sizeof(struct imsgev
))) == NULL
)
460 imsg_init(&iev_ldpe
->ibuf
, fd
);
461 iev_ldpe
->handler_read
= lde_dispatch_imsg
;
462 iev_ldpe
->ev_read
= thread_add_read(master
,
463 iev_ldpe
->handler_read
, iev_ldpe
, iev_ldpe
->ibuf
.fd
);
464 iev_ldpe
->handler_write
= ldp_write_handler
;
465 iev_ldpe
->ev_write
= NULL
;
467 case IMSG_RECONF_CONF
:
468 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
471 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
473 LIST_INIT(&nconf
->iface_list
);
474 LIST_INIT(&nconf
->tnbr_list
);
475 LIST_INIT(&nconf
->nbrp_list
);
476 LIST_INIT(&nconf
->l2vpn_list
);
478 case IMSG_RECONF_IFACE
:
479 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
481 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
483 LIST_INIT(&niface
->addr_list
);
484 LIST_INIT(&niface
->ipv4
.adj_list
);
485 LIST_INIT(&niface
->ipv6
.adj_list
);
486 niface
->ipv4
.iface
= niface
;
487 niface
->ipv6
.iface
= niface
;
489 LIST_INSERT_HEAD(&nconf
->iface_list
, niface
, entry
);
491 case IMSG_RECONF_TNBR
:
492 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
494 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
496 LIST_INSERT_HEAD(&nconf
->tnbr_list
, ntnbr
, entry
);
498 case IMSG_RECONF_NBRP
:
499 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
501 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
503 LIST_INSERT_HEAD(&nconf
->nbrp_list
, nnbrp
, entry
);
505 case IMSG_RECONF_L2VPN
:
506 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
508 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
510 LIST_INIT(&nl2vpn
->if_list
);
511 LIST_INIT(&nl2vpn
->pw_list
);
512 LIST_INIT(&nl2vpn
->pw_inactive_list
);
514 LIST_INSERT_HEAD(&nconf
->l2vpn_list
, nl2vpn
, entry
);
516 case IMSG_RECONF_L2VPN_IF
:
517 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
519 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
521 nlif
->l2vpn
= nl2vpn
;
522 LIST_INSERT_HEAD(&nl2vpn
->if_list
, nlif
, entry
);
524 case IMSG_RECONF_L2VPN_PW
:
525 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
527 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
530 LIST_INSERT_HEAD(&nl2vpn
->pw_list
, npw
, entry
);
532 case IMSG_RECONF_L2VPN_IPW
:
533 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
535 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
538 LIST_INSERT_HEAD(&nl2vpn
->pw_inactive_list
, npw
, entry
);
540 case IMSG_RECONF_END
:
541 merge_config(ldeconf
, nconf
);
544 case IMSG_DEBUG_UPDATE
:
545 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
547 log_warnx("%s: wrong imsg len", __func__
);
550 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
553 log_debug("%s: unexpected imsg %d", __func__
,
562 /* this pipe is dead, so remove the event handlers and exit */
563 THREAD_READ_OFF(iev
->ev_read
);
564 THREAD_WRITE_OFF(iev
->ev_write
);
572 lde_assign_label(void)
574 static uint32_t label
= MPLS_LABEL_RESERVED_MAX
;
577 * TODO: request label to zebra or define a range of labels for ldpd.
585 lde_send_change_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
591 switch (fn
->fec
.type
) {
593 memset(&kr
, 0, sizeof(kr
));
595 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
596 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
597 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
598 kr
.local_label
= fn
->local_label
;
599 kr
.remote_label
= fnh
->remote_label
;
600 kr
.priority
= fnh
->priority
;
602 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
605 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
606 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
607 &fn
->fec
.u
.ipv4
.prefix
);
610 memset(&kr
, 0, sizeof(kr
));
612 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
613 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
614 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
615 kr
.local_label
= fn
->local_label
;
616 kr
.remote_label
= fnh
->remote_label
;
617 kr
.priority
= fnh
->priority
;
619 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE
, 0, &kr
,
622 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
623 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
624 &fn
->fec
.u
.ipv6
.prefix
);
627 if (fn
->local_label
== NO_LABEL
||
628 fnh
->remote_label
== NO_LABEL
)
631 pw
= (struct l2vpn_pw
*) fn
->data
;
632 pw
->flags
|= F_PW_STATUS_UP
;
634 memset(&kpw
, 0, sizeof(kpw
));
635 kpw
.ifindex
= pw
->ifindex
;
636 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
638 kpw
.nexthop
= pw
->addr
;
639 kpw
.local_label
= fn
->local_label
;
640 kpw
.remote_label
= fnh
->remote_label
;
641 kpw
.flags
= pw
->flags
;
643 lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE
, 0, &kpw
,
650 lde_send_delete_klabel(struct fec_node
*fn
, struct fec_nh
*fnh
)
656 switch (fn
->fec
.type
) {
658 memset(&kr
, 0, sizeof(kr
));
660 kr
.prefix
.v4
= fn
->fec
.u
.ipv4
.prefix
;
661 kr
.prefixlen
= fn
->fec
.u
.ipv4
.prefixlen
;
662 kr
.nexthop
.v4
= fnh
->nexthop
.v4
;
663 kr
.local_label
= fn
->local_label
;
664 kr
.remote_label
= fnh
->remote_label
;
665 kr
.priority
= fnh
->priority
;
667 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
670 if (fn
->fec
.u
.ipv4
.prefixlen
== 32)
671 l2vpn_sync_pws(AF_INET
, (union ldpd_addr
*)
672 &fn
->fec
.u
.ipv4
.prefix
);
675 memset(&kr
, 0, sizeof(kr
));
677 kr
.prefix
.v6
= fn
->fec
.u
.ipv6
.prefix
;
678 kr
.prefixlen
= fn
->fec
.u
.ipv6
.prefixlen
;
679 kr
.nexthop
.v6
= fnh
->nexthop
.v6
;
680 kr
.local_label
= fn
->local_label
;
681 kr
.remote_label
= fnh
->remote_label
;
682 kr
.priority
= fnh
->priority
;
684 lde_imsg_compose_parent(IMSG_KLABEL_DELETE
, 0, &kr
,
687 if (fn
->fec
.u
.ipv6
.prefixlen
== 128)
688 l2vpn_sync_pws(AF_INET6
, (union ldpd_addr
*)
689 &fn
->fec
.u
.ipv6
.prefix
);
692 pw
= (struct l2vpn_pw
*) fn
->data
;
693 if (!(pw
->flags
& F_PW_STATUS_UP
))
695 pw
->flags
&= ~F_PW_STATUS_UP
;
697 memset(&kpw
, 0, sizeof(kpw
));
698 kpw
.ifindex
= pw
->ifindex
;
699 kpw
.pw_type
= fn
->fec
.u
.pwid
.type
;
701 kpw
.nexthop
= pw
->addr
;
702 kpw
.local_label
= fn
->local_label
;
703 kpw
.remote_label
= fnh
->remote_label
;
704 kpw
.flags
= pw
->flags
;
706 lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE
, 0, &kpw
,
713 lde_fec2map(struct fec
*fec
, struct map
*map
)
715 memset(map
, 0, sizeof(*map
));
719 map
->type
= MAP_TYPE_PREFIX
;
720 map
->fec
.prefix
.af
= AF_INET
;
721 map
->fec
.prefix
.prefix
.v4
= fec
->u
.ipv4
.prefix
;
722 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv4
.prefixlen
;
725 map
->type
= MAP_TYPE_PREFIX
;
726 map
->fec
.prefix
.af
= AF_INET6
;
727 map
->fec
.prefix
.prefix
.v6
= fec
->u
.ipv6
.prefix
;
728 map
->fec
.prefix
.prefixlen
= fec
->u
.ipv6
.prefixlen
;
731 map
->type
= MAP_TYPE_PWID
;
732 map
->fec
.pwid
.type
= fec
->u
.pwid
.type
;
733 map
->fec
.pwid
.group_id
= 0;
734 map
->flags
|= F_MAP_PW_ID
;
735 map
->fec
.pwid
.pwid
= fec
->u
.pwid
.pwid
;
741 lde_map2fec(struct map
*map
, struct in_addr lsr_id
, struct fec
*fec
)
743 memset(fec
, 0, sizeof(*fec
));
746 case MAP_TYPE_PREFIX
:
747 switch (map
->fec
.prefix
.af
) {
749 fec
->type
= FEC_TYPE_IPV4
;
750 fec
->u
.ipv4
.prefix
= map
->fec
.prefix
.prefix
.v4
;
751 fec
->u
.ipv4
.prefixlen
= map
->fec
.prefix
.prefixlen
;
754 fec
->type
= FEC_TYPE_IPV6
;
755 fec
->u
.ipv6
.prefix
= map
->fec
.prefix
.prefix
.v6
;
756 fec
->u
.ipv6
.prefixlen
= map
->fec
.prefix
.prefixlen
;
759 fatalx("lde_map2fec: unknown af");
764 fec
->type
= FEC_TYPE_PWID
;
765 fec
->u
.pwid
.type
= map
->fec
.pwid
.type
;
766 fec
->u
.pwid
.pwid
= map
->fec
.pwid
.pwid
;
767 fec
->u
.pwid
.lsr_id
= lsr_id
;
773 lde_send_labelmapping(struct lde_nbr
*ln
, struct fec_node
*fn
, int single
)
781 * This function skips SL.1 - 3 and SL.9 - 14 because the label
782 * allocation is done way earlier (because of the merging nature of
786 lde_fec2map(&fn
->fec
, &map
);
787 switch (fn
->fec
.type
) {
797 pw
= (struct l2vpn_pw
*) fn
->data
;
798 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
799 /* not the remote end of the pseudowire */
802 map
.flags
|= F_MAP_PW_IFMTU
;
803 map
.fec
.pwid
.ifmtu
= pw
->l2vpn
->mtu
;
804 if (pw
->flags
& F_PW_CWORD
)
805 map
.flags
|= F_MAP_PW_CWORD
;
806 if (pw
->flags
& F_PW_STATUSTLV
) {
807 map
.flags
|= F_MAP_PW_STATUS
;
808 /* VPLS are always up */
809 map
.pw_status
= PW_FORWARDING
;
813 map
.label
= fn
->local_label
;
815 /* SL.6: is there a pending request for this mapping? */
816 lre
= (struct lde_req
*)fec_find(&ln
->recv_req
, &fn
->fec
);
818 /* set label request msg id in the mapping response. */
819 map
.requestid
= lre
->msg_id
;
820 map
.flags
= F_MAP_REQ_ID
;
822 /* SL.7: delete record of pending request */
823 lde_req_del(ln
, lre
, 0);
826 /* SL.4: send label mapping */
827 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD
, ln
->peerid
, 0,
830 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
833 /* SL.5: record sent label mapping */
834 me
= (struct lde_map
*)fec_find(&ln
->sent_map
, &fn
->fec
);
836 me
= lde_map_add(ln
, fn
, 1);
841 lde_send_labelwithdraw(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
,
842 struct status_tlv
*st
)
844 struct lde_wdraw
*lw
;
850 lde_fec2map(&fn
->fec
, &map
);
851 switch (fn
->fec
.type
) {
861 pw
= (struct l2vpn_pw
*) fn
->data
;
862 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
863 /* not the remote end of the pseudowire */
866 if (pw
->flags
& F_PW_CWORD
)
867 map
.flags
|= F_MAP_PW_CWORD
;
870 map
.label
= fn
->local_label
;
872 memset(&map
, 0, sizeof(map
));
873 map
.type
= MAP_TYPE_WILDCARD
;
878 map
.st
.status_code
= st
->status_code
;
879 map
.st
.msg_id
= st
->msg_id
;
880 map
.st
.msg_type
= st
->msg_type
;
881 map
.flags
|= F_MAP_STATUS
;
884 /* SWd.1: send label withdraw. */
885 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD
, ln
->peerid
, 0,
887 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END
, ln
->peerid
, 0, NULL
, 0);
889 /* SWd.2: record label withdraw. */
891 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
, &fn
->fec
);
893 lw
= lde_wdraw_add(ln
, fn
);
894 lw
->label
= map
.label
;
896 RB_FOREACH(f
, fec_tree
, &ft
) {
897 fn
= (struct fec_node
*)f
;
899 lw
= (struct lde_wdraw
*)fec_find(&ln
->sent_wdraw
,
902 lw
= lde_wdraw_add(ln
, fn
);
903 lw
->label
= map
.label
;
909 lde_send_labelwithdraw_all(struct fec_node
*fn
, uint32_t label
)
913 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
914 lde_send_labelwithdraw(ln
, fn
, label
, NULL
);
918 lde_send_labelrelease(struct lde_nbr
*ln
, struct fec_node
*fn
, uint32_t label
)
924 lde_fec2map(&fn
->fec
, &map
);
925 switch (fn
->fec
.type
) {
935 pw
= (struct l2vpn_pw
*) fn
->data
;
936 if (pw
== NULL
|| pw
->lsr_id
.s_addr
!= ln
->id
.s_addr
)
937 /* not the remote end of the pseudowire */
940 if (pw
->flags
& F_PW_CWORD
)
941 map
.flags
|= F_MAP_PW_CWORD
;
945 memset(&map
, 0, sizeof(map
));
946 map
.type
= MAP_TYPE_WILDCARD
;
950 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD
, ln
->peerid
, 0,
952 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END
, ln
->peerid
, 0, NULL
, 0);
956 lde_send_notification(uint32_t peerid
, uint32_t status_code
, uint32_t msg_id
,
959 struct notify_msg nm
;
961 memset(&nm
, 0, sizeof(nm
));
962 nm
.status_code
= status_code
;
963 /* 'msg_id' and 'msg_type' should be in network byte order */
965 nm
.msg_type
= msg_type
;
967 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND
, peerid
, 0,
972 lde_nbr_compare(struct lde_nbr
*a
, struct lde_nbr
*b
)
974 return (a
->peerid
- b
->peerid
);
977 static struct lde_nbr
*
978 lde_nbr_new(uint32_t peerid
, struct lde_nbr
*new)
982 if ((ln
= calloc(1, sizeof(*ln
))) == NULL
)
986 ln
->v4_enabled
= new->v4_enabled
;
987 ln
->v6_enabled
= new->v6_enabled
;
989 fec_init(&ln
->recv_map
);
990 fec_init(&ln
->sent_map
);
991 fec_init(&ln
->recv_req
);
992 fec_init(&ln
->sent_req
);
993 fec_init(&ln
->sent_wdraw
);
995 TAILQ_INIT(&ln
->addr_list
);
997 if (RB_INSERT(nbr_tree
, &lde_nbrs
, ln
) != NULL
)
998 fatalx("lde_nbr_new: RB_INSERT failed");
1004 lde_nbr_del(struct lde_nbr
*ln
)
1007 struct fec_node
*fn
;
1009 struct l2vpn_pw
*pw
;
1014 /* uninstall received mappings */
1015 RB_FOREACH(f
, fec_tree
, &ft
) {
1016 fn
= (struct fec_node
*)f
;
1018 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1022 if (!lde_address_find(ln
, fnh
->af
,
1027 if (f
->u
.pwid
.lsr_id
.s_addr
!= ln
->id
.s_addr
)
1029 pw
= (struct l2vpn_pw
*) fn
->data
;
1037 lde_send_delete_klabel(fn
, fnh
);
1038 fnh
->remote_label
= NO_LABEL
;
1042 lde_address_list_free(ln
);
1044 fec_clear(&ln
->recv_map
, lde_map_free
);
1045 fec_clear(&ln
->sent_map
, lde_map_free
);
1046 fec_clear(&ln
->recv_req
, free
);
1047 fec_clear(&ln
->sent_req
, free
);
1048 fec_clear(&ln
->sent_wdraw
, free
);
1050 RB_REMOVE(nbr_tree
, &lde_nbrs
, ln
);
1055 static struct lde_nbr
*
1056 lde_nbr_find(uint32_t peerid
)
1062 return (RB_FIND(nbr_tree
, &lde_nbrs
, &ln
));
1066 lde_nbr_find_by_lsrid(struct in_addr addr
)
1070 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1071 if (ln
->id
.s_addr
== addr
.s_addr
)
1078 lde_nbr_find_by_addr(int af
, union ldpd_addr
*addr
)
1082 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
)
1083 if (lde_address_find(ln
, af
, addr
) != NULL
)
1094 while ((ln
= RB_ROOT(&lde_nbrs
)) != NULL
)
1099 lde_nbr_addr_update(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
, int removed
)
1102 struct fec_node
*fn
;
1106 RB_FOREACH(fec
, fec_tree
, &ln
->recv_map
) {
1107 fn
= (struct fec_node
*)fec_find(&ft
, fec
);
1108 switch (fec
->type
) {
1110 if (lde_addr
->af
!= AF_INET
)
1114 if (lde_addr
->af
!= AF_INET6
)
1121 LIST_FOREACH(fnh
, &fn
->nexthops
, entry
) {
1122 if (ldp_addrcmp(fnh
->af
, &fnh
->nexthop
,
1127 lde_send_delete_klabel(fn
, fnh
);
1128 fnh
->remote_label
= NO_LABEL
;
1130 me
= (struct lde_map
*)fec
;
1131 fnh
->remote_label
= me
->map
.label
;
1132 lde_send_change_klabel(fn
, fnh
);
1140 lde_map_add(struct lde_nbr
*ln
, struct fec_node
*fn
, int sent
)
1144 me
= calloc(1, sizeof(*me
));
1152 LIST_INSERT_HEAD(&fn
->upstream
, me
, entry
);
1153 if (fec_insert(&ln
->sent_map
, &me
->fec
))
1154 log_warnx("failed to add %s to sent map",
1156 /* XXX on failure more cleanup is needed */
1158 LIST_INSERT_HEAD(&fn
->downstream
, me
, entry
);
1159 if (fec_insert(&ln
->recv_map
, &me
->fec
))
1160 log_warnx("failed to add %s to recv map",
1168 lde_map_del(struct lde_nbr
*ln
, struct lde_map
*me
, int sent
)
1171 fec_remove(&ln
->sent_map
, &me
->fec
);
1173 fec_remove(&ln
->recv_map
, &me
->fec
);
1179 lde_map_free(void *ptr
)
1181 struct lde_map
*map
= ptr
;
1183 LIST_REMOVE(map
, entry
);
1188 lde_req_add(struct lde_nbr
*ln
, struct fec
*fec
, int sent
)
1191 struct lde_req
*lre
;
1193 t
= sent
? &ln
->sent_req
: &ln
->recv_req
;
1195 lre
= calloc(1, sizeof(*lre
));
1199 if (fec_insert(t
, &lre
->fec
)) {
1200 log_warnx("failed to add %s to %s req",
1201 log_fec(&lre
->fec
), sent
? "sent" : "recv");
1211 lde_req_del(struct lde_nbr
*ln
, struct lde_req
*lre
, int sent
)
1214 fec_remove(&ln
->sent_req
, &lre
->fec
);
1216 fec_remove(&ln
->recv_req
, &lre
->fec
);
1222 lde_wdraw_add(struct lde_nbr
*ln
, struct fec_node
*fn
)
1224 struct lde_wdraw
*lw
;
1226 lw
= calloc(1, sizeof(*lw
));
1232 if (fec_insert(&ln
->sent_wdraw
, &lw
->fec
))
1233 log_warnx("failed to add %s to sent wdraw",
1240 lde_wdraw_del(struct lde_nbr
*ln
, struct lde_wdraw
*lw
)
1242 fec_remove(&ln
->sent_wdraw
, &lw
->fec
);
1247 lde_change_egress_label(int af
, int was_implicit
)
1251 struct fec_node
*fn
;
1253 RB_FOREACH(ln
, nbr_tree
, &lde_nbrs
) {
1254 /* explicit withdraw */
1256 lde_send_labelwithdraw(ln
, NULL
, MPLS_LABEL_IMPLNULL
,
1260 lde_send_labelwithdraw(ln
, NULL
,
1261 MPLS_LABEL_IPV4NULL
, NULL
);
1263 lde_send_labelwithdraw(ln
, NULL
,
1264 MPLS_LABEL_IPV6NULL
, NULL
);
1267 /* advertise new label of connected prefixes */
1268 RB_FOREACH(f
, fec_tree
, &ft
) {
1269 fn
= (struct fec_node
*)f
;
1270 if (fn
->local_label
> MPLS_LABEL_RESERVED_MAX
)
1275 if (fn
->fec
.type
!= FEC_TYPE_IPV4
)
1279 if (fn
->fec
.type
!= FEC_TYPE_IPV6
)
1283 fatalx("lde_change_egress_label: unknown af");
1286 fn
->local_label
= egress_label(fn
->fec
.type
);
1287 lde_send_labelmapping(ln
, fn
, 0);
1290 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END
, ln
->peerid
, 0,
1296 lde_address_add(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1298 struct lde_addr
*new;
1300 if (lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
) != NULL
)
1303 if ((new = calloc(1, sizeof(*new))) == NULL
)
1306 new->af
= lde_addr
->af
;
1307 new->addr
= lde_addr
->addr
;
1308 TAILQ_INSERT_TAIL(&ln
->addr_list
, new, entry
);
1310 /* reevaluate the previously received mappings from this neighbor */
1311 lde_nbr_addr_update(ln
, lde_addr
, 0);
1317 lde_address_del(struct lde_nbr
*ln
, struct lde_addr
*lde_addr
)
1319 lde_addr
= lde_address_find(ln
, lde_addr
->af
, &lde_addr
->addr
);
1320 if (lde_addr
== NULL
)
1323 /* reevaluate the previously received mappings from this neighbor */
1324 lde_nbr_addr_update(ln
, lde_addr
, 1);
1326 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);
1333 lde_address_find(struct lde_nbr
*ln
, int af
, union ldpd_addr
*addr
)
1335 struct lde_addr
*lde_addr
;
1337 TAILQ_FOREACH(lde_addr
, &ln
->addr_list
, entry
)
1338 if (lde_addr
->af
== af
&&
1339 ldp_addrcmp(af
, &lde_addr
->addr
, addr
) == 0)
1346 lde_address_list_free(struct lde_nbr
*ln
)
1348 struct lde_addr
*lde_addr
;
1350 while ((lde_addr
= TAILQ_FIRST(&ln
->addr_list
)) != NULL
) {
1351 TAILQ_REMOVE(&ln
->addr_list
, lde_addr
, entry
);