4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004, 2008 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 static void ldpe_shutdown(void);
37 static int ldpe_dispatch_main(struct thread
*);
38 static int ldpe_dispatch_lde(struct thread
*);
40 static int ldpe_dispatch_pfkey(struct thread
*);
42 static void ldpe_setup_sockets(int, int, int, int);
43 static void ldpe_close_sockets(int);
44 static void ldpe_iface_af_ctl(struct ctl_conn
*, int, unsigned int);
46 struct ldpd_conf
*leconf
;
48 struct ldpd_sysdep sysdep
;
51 static struct imsgev
*iev_main
, *iev_main_sync
;
52 static struct imsgev
*iev_lde
;
54 static struct thread
*pfkey_ev
;
57 /* Master of threads. */
58 struct thread_master
*master
;
61 static zebra_capabilities_t _caps_p
[] =
67 struct zebra_privs_t ldpe_privs
=
69 #if defined(VTY_GROUP)
70 .vty_group
= VTY_GROUP
,
73 .cap_num_p
= array_size(_caps_p
),
77 /* SIGINT / SIGTERM handler. */
84 static struct quagga_signal_t ldpe_signals
[] =
100 /* label distribution protocol engine */
104 struct thread thread
;
106 #ifdef HAVE_SETPROCTITLE
107 setproctitle("ldp engine");
109 ldpd_process
= PROC_LDP_ENGINE
;
110 log_procname
= log_procnames
[ldpd_process
];
112 master
= thread_master_create(NULL
);
114 /* setup signal handler */
115 signal_init(master
, array_size(ldpe_signals
), ldpe_signals
);
117 /* setup pipes and event handlers to the parent process */
118 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
120 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
121 iev_main
->handler_read
= ldpe_dispatch_main
;
122 iev_main
->ev_read
= NULL
;
123 thread_add_read(master
, iev_main
->handler_read
, iev_main
, iev_main
->ibuf
.fd
,
125 iev_main
->handler_write
= ldp_write_handler
;
127 if ((iev_main_sync
= calloc(1, sizeof(struct imsgev
))) == NULL
)
129 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
131 /* create base configuration */
132 leconf
= config_new_empty();
134 /* Fetch next active thread. */
135 while (thread_fetch(master
, &thread
))
136 thread_call(&thread
);
140 ldpe_init(struct ldpd_init
*init
)
142 /* drop privileges */
143 ldpe_privs
.user
= init
->user
;
144 ldpe_privs
.group
= init
->group
;
145 zprivs_preinit(&ldpe_privs
);
146 zprivs_init(&ldpe_privs
);
148 /* listen on ldpd control socket */
149 strlcpy(ctl_sock_path
, init
->ctl_sock_path
, sizeof(ctl_sock_path
));
150 if (control_init(ctl_sock_path
) == -1)
151 fatalx("control socket setup failed");
152 TAILQ_INIT(&ctl_conns
);
155 LIST_INIT(&global
.addr_list
);
156 RB_INIT(global_adj_head
, &global
.adj_tree
);
157 TAILQ_INIT(&global
.pending_conns
);
158 if (inet_pton(AF_INET
, AllRouters_v4
, &global
.mcast_addr_v4
) != 1)
160 if (inet_pton(AF_INET6
, AllRouters_v6
, &global
.mcast_addr_v6
) != 1)
163 global
.pfkeysock
= pfkey_init();
164 if (sysdep
.no_pfkey
== 0) {
166 thread_add_read(master
, ldpe_dispatch_pfkey
, NULL
, global
.pfkeysock
,
171 /* mark sockets as closed */
172 global
.ipv4
.ldp_disc_socket
= -1;
173 global
.ipv4
.ldp_edisc_socket
= -1;
174 global
.ipv4
.ldp_session_socket
= -1;
175 global
.ipv6
.ldp_disc_socket
= -1;
176 global
.ipv6
.ldp_edisc_socket
= -1;
177 global
.ipv6
.ldp_session_socket
= -1;
179 if ((pkt_ptr
= calloc(1, IBUF_READ_SIZE
)) == NULL
)
188 struct if_addr
*if_addr
;
193 msgbuf_clear(&iev_lde
->ibuf
.w
);
194 close(iev_lde
->ibuf
.fd
);
195 iev_lde
->ibuf
.fd
= -1;
197 msgbuf_clear(&iev_main
->ibuf
.w
);
198 close(iev_main
->ibuf
.fd
);
199 iev_main
->ibuf
.fd
= -1;
200 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
201 close(iev_main_sync
->ibuf
.fd
);
202 iev_main_sync
->ibuf
.fd
= -1;
204 control_cleanup(ctl_sock_path
);
205 config_clear(leconf
);
208 if (sysdep
.no_pfkey
== 0) {
209 THREAD_READ_OFF(pfkey_ev
);
210 close(global
.pfkeysock
);
213 ldpe_close_sockets(AF_INET
);
214 ldpe_close_sockets(AF_INET6
);
216 /* remove addresses from global list */
217 while ((if_addr
= LIST_FIRST(&global
.addr_list
)) != NULL
) {
218 LIST_REMOVE(if_addr
, entry
);
219 assert(if_addr
!= LIST_FIRST(&global
.addr_list
));
222 while (!RB_EMPTY(global_adj_head
, &global
.adj_tree
)) {
223 adj
= RB_ROOT(global_adj_head
, &global
.adj_tree
);
225 adj_del(adj
, S_SHUTDOWN
);
235 log_info("ldp engine exiting");
241 ldpe_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
243 if (iev_main
->ibuf
.fd
== -1)
245 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
249 ldpe_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
251 if (iev_main_sync
->ibuf
.fd
== -1)
253 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
254 imsg_flush(&iev_main_sync
->ibuf
);
258 ldpe_imsg_compose_lde(int type
, uint32_t peerid
, pid_t pid
, void *data
,
261 if (iev_lde
->ibuf
.fd
== -1)
263 return (imsg_compose_event(iev_lde
, type
, peerid
, pid
, -1,
269 ldpe_dispatch_main(struct thread
*thread
)
271 static struct ldpd_conf
*nconf
;
272 struct iface
*niface
;
274 struct nbr_params
*nnbrp
;
275 static struct l2vpn
*l2vpn
, *nl2vpn
;
276 struct l2vpn_if
*lif
, *nlif
;
277 struct l2vpn_pw
*pw
, *npw
;
280 struct imsgev
*iev
= THREAD_ARG(thread
);
281 struct imsgbuf
*ibuf
= &iev
->ibuf
;
282 struct iface
*iface
= NULL
;
285 enum socket_type
*socket_type
;
286 static int disc_socket
= -1;
287 static int edisc_socket
= -1;
288 static int session_socket
= -1;
291 struct nbr_params
*nbrp
;
297 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
298 fatal("imsg_read error");
299 if (n
== 0) /* connection closed */
303 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
304 fatal("ldpe_dispatch_main: imsg_get error");
308 switch (imsg
.hdr
.type
) {
310 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
312 fatalx("IFSTATUS imsg with wrong len");
315 iface
= if_lookup_name(leconf
, kif
->ifname
);
317 if_update_info(iface
, kif
);
318 ldp_if_update(iface
, AF_UNSPEC
);
322 RB_FOREACH(l2vpn
, l2vpn_head
, &leconf
->l2vpn_tree
) {
323 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
325 l2vpn_if_update_info(lif
, kif
);
326 l2vpn_if_update(lif
);
329 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
331 l2vpn_pw_update_info(pw
, kif
);
337 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
338 sizeof(struct kaddr
))
339 fatalx("NEWADDR imsg with wrong len");
341 if_addr_add(imsg
.data
);
344 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
345 sizeof(struct kaddr
))
346 fatalx("DELADDR imsg with wrong len");
348 if_addr_del(imsg
.data
);
350 case IMSG_SOCKET_IPC
:
352 log_warnx("%s: received unexpected imsg fd "
356 if ((fd
= imsg
.fd
) == -1) {
357 log_warnx("%s: expected to receive imsg fd to "
358 "lde but didn't receive any", __func__
);
362 if ((iev_lde
= malloc(sizeof(struct imsgev
))) == NULL
)
364 imsg_init(&iev_lde
->ibuf
, fd
);
365 iev_lde
->handler_read
= ldpe_dispatch_lde
;
366 iev_lde
->ev_read
= NULL
;
367 thread_add_read(master
, iev_lde
->handler_read
, iev_lde
, iev_lde
->ibuf
.fd
,
369 iev_lde
->handler_write
= ldp_write_handler
;
370 iev_lde
->ev_write
= NULL
;
373 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
374 sizeof(struct ldpd_init
))
375 fatalx("INIT imsg with wrong len");
377 memcpy(&init
, imsg
.data
, sizeof(init
));
380 case IMSG_CLOSE_SOCKETS
:
381 af
= imsg
.hdr
.peerid
;
383 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
386 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
390 nbr
->auth
.method
= AUTH_NONE
;
392 ldpe_close_sockets(af
);
399 if ((ldp_af_conf_get(leconf
, af
))->flags
&
401 ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS
,
404 case IMSG_SOCKET_NET
:
405 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
406 sizeof(enum socket_type
))
407 fatalx("SOCKET_NET imsg with wrong len");
408 socket_type
= imsg
.data
;
410 switch (*socket_type
) {
411 case LDP_SOCKET_DISC
:
412 disc_socket
= imsg
.fd
;
414 case LDP_SOCKET_EDISC
:
415 edisc_socket
= imsg
.fd
;
417 case LDP_SOCKET_SESSION
:
418 session_socket
= imsg
.fd
;
422 case IMSG_SETUP_SOCKETS
:
423 af
= imsg
.hdr
.peerid
;
424 if (disc_socket
== -1 || edisc_socket
== -1 ||
425 session_socket
== -1) {
426 if (disc_socket
!= -1)
428 if (edisc_socket
!= -1)
430 if (session_socket
!= -1)
431 close(session_socket
);
435 ldpe_setup_sockets(af
, disc_socket
, edisc_socket
,
439 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
442 nbr
->laddr
= (ldp_af_conf_get(leconf
,
445 nbrp
= nbr_params_find(leconf
, nbr
->id
);
447 nbr
->auth
.method
= nbrp
->auth
.method
;
448 if (pfkey_establish(nbr
, nbrp
) == -1)
449 fatalx("pfkey setup failed");
452 if (nbr_session_active_role(nbr
))
453 nbr_establish_connection(nbr
);
456 case IMSG_RTRID_UPDATE
:
457 memcpy(&global
.rtr_id
, imsg
.data
,
458 sizeof(global
.rtr_id
));
459 if (leconf
->rtr_id
.s_addr
== INADDR_ANY
) {
460 ldpe_reset_nbrs(AF_UNSPEC
);
462 if_update_all(AF_UNSPEC
);
463 tnbr_update_all(AF_UNSPEC
);
465 case IMSG_RECONF_CONF
:
466 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
469 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
471 RB_INIT(iface_head
, &nconf
->iface_tree
);
472 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
473 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
474 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
476 case IMSG_RECONF_IFACE
:
477 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
479 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
481 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
483 case IMSG_RECONF_TNBR
:
484 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
486 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
488 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
490 case IMSG_RECONF_NBRP
:
491 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
493 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
495 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
497 case IMSG_RECONF_L2VPN
:
498 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
500 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
502 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
503 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
504 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
506 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
508 case IMSG_RECONF_L2VPN_IF
:
509 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
511 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
513 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
515 case IMSG_RECONF_L2VPN_PW
:
516 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
518 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
520 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
522 case IMSG_RECONF_L2VPN_IPW
:
523 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
525 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
527 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
529 case IMSG_RECONF_END
:
530 merge_config(leconf
, nconf
);
531 ldp_clear_config(nconf
);
533 global
.conf_seqnum
++;
536 control_imsg_relay(&imsg
);
538 case IMSG_DEBUG_UPDATE
:
539 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
541 log_warnx("%s: wrong imsg len", __func__
);
544 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
547 log_debug("ldpe_dispatch_main: error handling imsg %d",
556 /* this pipe is dead, so remove the event handlers and exit */
557 THREAD_READ_OFF(iev
->ev_read
);
558 THREAD_WRITE_OFF(iev
->ev_write
);
567 ldpe_dispatch_lde(struct thread
*thread
)
569 struct imsgev
*iev
= THREAD_ARG(thread
);
570 struct imsgbuf
*ibuf
= &iev
->ibuf
;
573 struct notify_msg
*nm
;
579 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
580 fatal("imsg_read error");
581 if (n
== 0) /* connection closed */
585 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
586 fatal("ldpe_dispatch_lde: imsg_get error");
590 switch (imsg
.hdr
.type
) {
591 case IMSG_MAPPING_ADD
:
592 case IMSG_RELEASE_ADD
:
593 case IMSG_REQUEST_ADD
:
594 case IMSG_WITHDRAW_ADD
:
595 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
597 fatalx("invalid size of map request");
600 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
602 log_debug("ldpe_dispatch_lde: cannot find "
606 if (nbr
->state
!= NBR_STA_OPER
)
609 switch (imsg
.hdr
.type
) {
610 case IMSG_MAPPING_ADD
:
611 mapping_list_add(&nbr
->mapping_list
, map
);
613 case IMSG_RELEASE_ADD
:
614 mapping_list_add(&nbr
->release_list
, map
);
616 case IMSG_REQUEST_ADD
:
617 mapping_list_add(&nbr
->request_list
, map
);
619 case IMSG_WITHDRAW_ADD
:
620 mapping_list_add(&nbr
->withdraw_list
, map
);
624 case IMSG_MAPPING_ADD_END
:
625 case IMSG_RELEASE_ADD_END
:
626 case IMSG_REQUEST_ADD_END
:
627 case IMSG_WITHDRAW_ADD_END
:
628 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
630 log_debug("ldpe_dispatch_lde: cannot find "
634 if (nbr
->state
!= NBR_STA_OPER
)
637 switch (imsg
.hdr
.type
) {
638 case IMSG_MAPPING_ADD_END
:
639 send_labelmessage(nbr
, MSG_TYPE_LABELMAPPING
,
642 case IMSG_RELEASE_ADD_END
:
643 send_labelmessage(nbr
, MSG_TYPE_LABELRELEASE
,
646 case IMSG_REQUEST_ADD_END
:
647 send_labelmessage(nbr
, MSG_TYPE_LABELREQUEST
,
650 case IMSG_WITHDRAW_ADD_END
:
651 send_labelmessage(nbr
, MSG_TYPE_LABELWITHDRAW
,
652 &nbr
->withdraw_list
);
656 case IMSG_NOTIFICATION_SEND
:
657 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
658 sizeof(struct notify_msg
))
659 fatalx("invalid size of OE request");
662 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
664 log_debug("ldpe_dispatch_lde: cannot find "
668 if (nbr
->state
!= NBR_STA_OPER
)
671 send_notification_full(nbr
->tcp
, nm
);
674 case IMSG_CTL_SHOW_LIB_BEGIN
:
675 case IMSG_CTL_SHOW_LIB_RCVD
:
676 case IMSG_CTL_SHOW_LIB_SENT
:
677 case IMSG_CTL_SHOW_LIB_END
:
678 case IMSG_CTL_SHOW_L2VPN_PW
:
679 case IMSG_CTL_SHOW_L2VPN_BINDING
:
680 control_imsg_relay(&imsg
);
683 log_debug("ldpe_dispatch_lde: error handling imsg %d",
692 /* this pipe is dead, so remove the event handlers and exit */
693 THREAD_READ_OFF(iev
->ev_read
);
694 THREAD_WRITE_OFF(iev
->ev_write
);
704 ldpe_dispatch_pfkey(struct thread
*thread
)
706 int fd
= THREAD_FD(thread
);
709 thread_add_read(master
, ldpe_dispatch_pfkey
, NULL
, global
.pfkeysock
,
712 if (pfkey_read(fd
, NULL
) == -1)
713 fatal("pfkey_read failed, exiting...");
717 #endif /* __OpenBSD__ */
720 ldpe_setup_sockets(int af
, int disc_socket
, int edisc_socket
,
723 struct ldpd_af_global
*af_global
;
725 af_global
= ldp_af_global_get(&global
, af
);
727 /* discovery socket */
728 af_global
->ldp_disc_socket
= disc_socket
;
729 af_global
->disc_ev
= NULL
;
730 thread_add_read(master
, disc_recv_packet
, &af_global
->disc_ev
, af_global
->ldp_disc_socket
,
731 &af_global
->disc_ev
);
733 /* extended discovery socket */
734 af_global
->ldp_edisc_socket
= edisc_socket
;
735 af_global
->edisc_ev
= NULL
;
736 thread_add_read(master
, disc_recv_packet
, &af_global
->edisc_ev
, af_global
->ldp_edisc_socket
,
737 &af_global
->edisc_ev
);
740 af_global
->ldp_session_socket
= session_socket
;
741 accept_add(af_global
->ldp_session_socket
, session_accept
, NULL
);
745 ldpe_close_sockets(int af
)
747 struct ldpd_af_global
*af_global
;
749 af_global
= ldp_af_global_get(&global
, af
);
751 /* discovery socket */
752 THREAD_READ_OFF(af_global
->disc_ev
);
753 if (af_global
->ldp_disc_socket
!= -1) {
754 close(af_global
->ldp_disc_socket
);
755 af_global
->ldp_disc_socket
= -1;
758 /* extended discovery socket */
759 THREAD_READ_OFF(af_global
->edisc_ev
);
760 if (af_global
->ldp_edisc_socket
!= -1) {
761 close(af_global
->ldp_edisc_socket
);
762 af_global
->ldp_edisc_socket
= -1;
766 if (af_global
->ldp_session_socket
!= -1) {
767 accept_del(af_global
->ldp_session_socket
);
768 close(af_global
->ldp_session_socket
);
769 af_global
->ldp_session_socket
= -1;
774 ldpe_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
776 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
780 ldpe_reset_nbrs(int af
)
784 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
785 if (af
== AF_UNSPEC
|| nbr
->af
== af
)
786 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
791 ldpe_reset_ds_nbrs(void)
795 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
797 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
802 ldpe_remove_dynamic_tnbrs(int af
)
804 struct tnbr
*tnbr
, *safe
;
806 RB_FOREACH_SAFE(tnbr
, tnbr_head
, &leconf
->tnbr_tree
, safe
) {
810 tnbr
->flags
&= ~F_TNBR_DYNAMIC
;
811 tnbr_check(leconf
, tnbr
);
816 ldpe_stop_init_backoff(int af
)
820 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
821 if (nbr
->af
== af
&& nbr_pending_idtimer(nbr
)) {
822 nbr_stop_idtimer(nbr
);
823 nbr_establish_connection(nbr
);
829 ldpe_iface_af_ctl(struct ctl_conn
*c
, int af
, unsigned int idx
)
833 struct ctl_iface
*ictl
;
835 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
836 if (idx
== 0 || idx
== iface
->ifindex
) {
837 ia
= iface_af_get(iface
, af
);
841 ictl
= if_to_ctl(ia
);
842 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_INTERFACE
,
843 0, 0, -1, ictl
, sizeof(struct ctl_iface
));
849 ldpe_iface_ctl(struct ctl_conn
*c
, unsigned int idx
)
851 ldpe_iface_af_ctl(c
, AF_INET
, idx
);
852 ldpe_iface_af_ctl(c
, AF_INET6
, idx
);
856 ldpe_adj_ctl(struct ctl_conn
*c
)
859 struct ctl_adj
*actl
;
861 RB_FOREACH(adj
, global_adj_head
, &global
.adj_tree
) {
862 actl
= adj_to_ctl(adj
);
863 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0,
864 -1, actl
, sizeof(struct ctl_adj
));
867 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
871 ldpe_adj_detail_ctl(struct ctl_conn
*c
)
876 struct ctl_adj
*actl
;
877 struct ctl_disc_if ictl
;
878 struct ctl_disc_tnbr tctl
;
880 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0, -1, NULL
, 0);
882 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
883 memset(&ictl
, 0, sizeof(ictl
));
884 ictl
.active_v4
= (iface
->ipv4
.state
== IF_STA_ACTIVE
);
885 ictl
.active_v6
= (iface
->ipv6
.state
== IF_STA_ACTIVE
);
887 if (!ictl
.active_v4
&& !ictl
.active_v6
)
890 strlcpy(ictl
.name
, iface
->name
, sizeof(ictl
.name
));
891 if (RB_EMPTY(ia_adj_head
, &iface
->ipv4
.adj_tree
) &&
892 RB_EMPTY(ia_adj_head
, &iface
->ipv6
.adj_tree
))
894 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_IFACE
, 0, 0,
895 -1, &ictl
, sizeof(ictl
));
897 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv4
.adj_tree
) {
898 actl
= adj_to_ctl(adj
);
899 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
900 0, 0, -1, actl
, sizeof(struct ctl_adj
));
902 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv6
.adj_tree
) {
903 actl
= adj_to_ctl(adj
);
904 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
905 0, 0, -1, actl
, sizeof(struct ctl_adj
));
909 RB_FOREACH(tnbr
, tnbr_head
, &leconf
->tnbr_tree
) {
910 memset(&tctl
, 0, sizeof(tctl
));
912 tctl
.addr
= tnbr
->addr
;
913 if (tnbr
->adj
== NULL
)
916 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_TNBR
, 0, 0,
917 -1, &tctl
, sizeof(tctl
));
919 if (tnbr
->adj
== NULL
)
922 actl
= adj_to_ctl(tnbr
->adj
);
923 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
, 0, 0,
924 -1, actl
, sizeof(struct ctl_adj
));
927 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
931 ldpe_nbr_ctl(struct ctl_conn
*c
)
934 struct ctl_adj
*actl
;
936 struct ctl_nbr
*nctl
;
938 RB_FOREACH(nbr
, nbr_addr_head
, &nbrs_by_addr
) {
939 if (nbr
->state
== NBR_STA_PRESENT
)
942 nctl
= nbr_to_ctl(nbr
);
943 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR
, 0, 0, -1, nctl
,
944 sizeof(struct ctl_nbr
));
946 RB_FOREACH(adj
, nbr_adj_head
, &nbr
->adj_tree
) {
947 actl
= adj_to_ctl(adj
);
948 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_DISC
,
949 0, 0, -1, actl
, sizeof(struct ctl_adj
));
952 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_END
, 0, 0, -1,
955 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
959 mapping_list_add(struct mapping_head
*mh
, struct map
*map
)
961 struct mapping_entry
*me
;
963 me
= calloc(1, sizeof(*me
));
968 TAILQ_INSERT_TAIL(mh
, me
, entry
);
972 mapping_list_clr(struct mapping_head
*mh
)
974 struct mapping_entry
*me
;
976 while ((me
= TAILQ_FIRST(mh
)) != NULL
) {
977 TAILQ_REMOVE(mh
, me
, entry
);
978 assert(me
!= TAILQ_FIRST(mh
));