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"
38 static void ldpe_shutdown(void);
39 static void ldpe_dispatch_main(struct thread
*thread
);
40 static void ldpe_dispatch_lde(struct thread
*thread
);
42 static void ldpe_dispatch_pfkey(struct thread
*thread
);
44 static void ldpe_setup_sockets(int, int, int, int);
45 static void ldpe_close_sockets(int);
46 static void ldpe_iface_af_ctl(struct ctl_conn
*c
, int af
, ifindex_t ifidx
);
47 static void ldpe_check_filter_af(int, struct ldpd_af_conf
*, const char *);
49 struct ldpd_conf
*leconf
;
51 struct ldpd_sysdep sysdep
;
54 static struct imsgev iev_main_data
;
55 static struct imsgev
*iev_main
, *iev_main_sync
;
56 static struct imsgev
*iev_lde
;
58 static struct thread
*pfkey_ev
;
62 static zebra_capabilities_t _caps_p
[] =
68 struct zebra_privs_t ldpe_privs
=
70 #if defined(VTY_GROUP)
71 .vty_group
= VTY_GROUP
,
74 .cap_num_p
= array_size(_caps_p
),
78 /* SIGINT / SIGTERM handler. */
85 static struct frr_signal_t ldpe_signals
[] =
101 char *pkt_ptr
; /* packet buffer */
103 /* label distribution protocol engine */
107 #ifdef HAVE_SETPROCTITLE
108 setproctitle("ldp engine");
110 ldpd_process
= PROC_LDP_ENGINE
;
111 log_procname
= log_procnames
[ldpd_process
];
114 /* no frr_config_fork() here, allow frr_pthread to create threads */
115 frr_is_after_fork
= true;
117 /* setup signal handler */
118 signal_init(master
, array_size(ldpe_signals
), ldpe_signals
);
120 /* setup pipes and event handlers to the parent process */
121 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
123 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
124 iev_main
->handler_read
= ldpe_dispatch_main
;
125 thread_add_read(master
, iev_main
->handler_read
, iev_main
, iev_main
->ibuf
.fd
,
127 iev_main
->handler_write
= ldp_write_handler
;
129 memset(&iev_main_data
, 0, sizeof(iev_main_data
));
130 iev_main_sync
= &iev_main_data
;
131 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
133 /* create base configuration */
134 leconf
= config_new_empty();
136 struct thread thread
;
137 while (thread_fetch(master
, &thread
))
138 thread_call(&thread
);
145 ldpe_init(struct ldpd_init
*init
)
148 /* This socket must be open before dropping privileges. */
149 global
.pfkeysock
= pfkey_init();
150 if (sysdep
.no_pfkey
== 0) {
151 thread_add_read(master
, ldpe_dispatch_pfkey
, NULL
, global
.pfkeysock
,
156 /* drop privileges */
157 ldpe_privs
.user
= init
->user
;
158 ldpe_privs
.group
= init
->group
;
159 zprivs_preinit(&ldpe_privs
);
160 zprivs_init(&ldpe_privs
);
162 /* listen on ldpd control socket */
163 strlcpy(ctl_sock_path
, init
->ctl_sock_path
, sizeof(ctl_sock_path
));
164 if (control_init(ctl_sock_path
) == -1)
165 fatalx("control socket setup failed");
166 TAILQ_INIT(&ctl_conns
);
169 LIST_INIT(&global
.addr_list
);
170 RB_INIT(global_adj_head
, &global
.adj_tree
);
171 TAILQ_INIT(&global
.pending_conns
);
172 if (inet_pton(AF_INET
, AllRouters_v4
, &global
.mcast_addr_v4
) != 1)
174 if (inet_pton(AF_INET6
, AllRouters_v6
, &global
.mcast_addr_v6
) != 1)
177 /* mark sockets as closed */
178 global
.ipv4
.ldp_disc_socket
= -1;
179 global
.ipv4
.ldp_edisc_socket
= -1;
180 global
.ipv4
.ldp_session_socket
= -1;
181 global
.ipv6
.ldp_disc_socket
= -1;
182 global
.ipv6
.ldp_edisc_socket
= -1;
183 global
.ipv6
.ldp_session_socket
= -1;
185 if ((pkt_ptr
= calloc(1, IBUF_READ_SIZE
)) == NULL
)
194 struct if_addr
*if_addr
;
199 msgbuf_clear(&iev_lde
->ibuf
.w
);
200 close(iev_lde
->ibuf
.fd
);
201 iev_lde
->ibuf
.fd
= -1;
203 msgbuf_clear(&iev_main
->ibuf
.w
);
204 close(iev_main
->ibuf
.fd
);
205 iev_main
->ibuf
.fd
= -1;
206 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
207 close(iev_main_sync
->ibuf
.fd
);
208 iev_main_sync
->ibuf
.fd
= -1;
210 control_cleanup(ctl_sock_path
);
213 if (sysdep
.no_pfkey
== 0) {
214 THREAD_OFF(pfkey_ev
);
215 close(global
.pfkeysock
);
218 ldpe_close_sockets(AF_INET
);
219 ldpe_close_sockets(AF_INET6
);
221 /* remove addresses from global list */
222 while ((if_addr
= LIST_FIRST(&global
.addr_list
)) != NULL
) {
223 LIST_REMOVE(if_addr
, entry
);
224 assert(if_addr
!= LIST_FIRST(&global
.addr_list
));
227 while (!RB_EMPTY(global_adj_head
, &global
.adj_tree
)) {
228 adj
= RB_ROOT(global_adj_head
, &global
.adj_tree
);
230 adj_del(adj
, S_SHUTDOWN
);
233 config_clear(leconf
);
240 log_info("ldp engine exiting");
249 ldpe_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
251 if (iev_main
->ibuf
.fd
== -1)
253 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
257 ldpe_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
259 if (iev_main_sync
->ibuf
.fd
== -1)
261 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
262 imsg_flush(&iev_main_sync
->ibuf
);
266 ldpe_imsg_compose_lde(int type
, uint32_t peerid
, pid_t pid
, void *data
,
269 if (iev_lde
->ibuf
.fd
== -1)
271 return (imsg_compose_event(iev_lde
, type
, peerid
, pid
, -1,
276 static void ldpe_dispatch_main(struct thread
*thread
)
278 static struct ldpd_conf
*nconf
;
279 struct iface
*niface
;
281 struct nbr_params
*nnbrp
;
282 static struct l2vpn
*l2vpn
, *nl2vpn
;
283 struct l2vpn_if
*lif
, *nlif
;
284 struct l2vpn_pw
*pw
, *npw
;
287 struct imsgev
*iev
= THREAD_ARG(thread
);
288 struct imsgbuf
*ibuf
= &iev
->ibuf
;
289 struct iface
*iface
= NULL
;
292 enum socket_type
*socket_type
;
293 static int disc_socket
= -1;
294 static int edisc_socket
= -1;
295 static int session_socket
= -1;
298 struct nbr_params
*nbrp
;
301 struct ldp_access
*laccess
;
302 struct ldp_igp_sync_if_state_req
*ldp_sync_if_state_req
;
303 struct ldp_rlfa_node
*rnode
, *rntmp
;
304 struct ldp_rlfa_client
*rclient
;
305 struct zapi_rlfa_request
*rlfa_req
;
306 struct zapi_rlfa_igp
*rlfa_igp
;
310 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
311 fatal("imsg_read error");
312 if (n
== 0) /* connection closed */
316 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
317 fatal("ldpe_dispatch_main: imsg_get error");
321 switch (imsg
.hdr
.type
) {
323 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
325 fatalx("IFSTATUS imsg with wrong len");
328 iface
= if_lookup_name(leconf
, kif
->ifname
);
330 if_update_info(iface
, kif
);
331 ldp_if_update(iface
, AF_UNSPEC
);
335 RB_FOREACH(l2vpn
, l2vpn_head
, &leconf
->l2vpn_tree
) {
336 lif
= l2vpn_if_find(l2vpn
, kif
->ifname
);
338 l2vpn_if_update_info(lif
, kif
);
339 l2vpn_if_update(lif
);
342 pw
= l2vpn_pw_find(l2vpn
, kif
->ifname
);
344 l2vpn_pw_update_info(pw
, kif
);
350 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
351 sizeof(struct kaddr
))
352 fatalx("NEWADDR imsg with wrong len");
354 if_addr_add(imsg
.data
);
357 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
358 sizeof(struct kaddr
))
359 fatalx("DELADDR imsg with wrong len");
361 if_addr_del(imsg
.data
);
363 case IMSG_SOCKET_IPC
:
365 log_warnx("%s: received unexpected imsg fd to lde", __func__
);
368 if ((fd
= imsg
.fd
) == -1) {
369 log_warnx("%s: expected to receive imsg fd to lde but didn't receive any", __func__
);
373 if ((iev_lde
= malloc(sizeof(struct imsgev
))) == NULL
)
375 imsg_init(&iev_lde
->ibuf
, fd
);
376 iev_lde
->handler_read
= ldpe_dispatch_lde
;
377 thread_add_read(master
, iev_lde
->handler_read
, iev_lde
, iev_lde
->ibuf
.fd
,
379 iev_lde
->handler_write
= ldp_write_handler
;
380 iev_lde
->ev_write
= NULL
;
383 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
384 sizeof(struct ldpd_init
))
385 fatalx("INIT imsg with wrong len");
387 memcpy(&init
, imsg
.data
, sizeof(init
));
390 case IMSG_AGENTX_ENABLED
:
391 ldp_agentx_enabled();
393 case IMSG_CLOSE_SOCKETS
:
394 af
= imsg
.hdr
.peerid
;
396 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
399 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
403 nbr
->auth
.method
= AUTH_NONE
;
405 ldpe_close_sockets(af
);
412 if ((ldp_af_conf_get(leconf
, af
))->flags
&
414 ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS
,
417 case IMSG_SOCKET_NET
:
418 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
419 sizeof(enum socket_type
))
420 fatalx("SOCKET_NET imsg with wrong len");
421 socket_type
= imsg
.data
;
423 switch (*socket_type
) {
424 case LDP_SOCKET_DISC
:
425 disc_socket
= imsg
.fd
;
427 case LDP_SOCKET_EDISC
:
428 edisc_socket
= imsg
.fd
;
430 case LDP_SOCKET_SESSION
:
431 session_socket
= imsg
.fd
;
435 case IMSG_SETUP_SOCKETS
:
436 af
= imsg
.hdr
.peerid
;
437 if (disc_socket
== -1 || edisc_socket
== -1 ||
438 session_socket
== -1) {
439 if (disc_socket
!= -1)
441 if (edisc_socket
!= -1)
443 if (session_socket
!= -1)
444 close(session_socket
);
448 ldpe_setup_sockets(af
, disc_socket
, edisc_socket
,
452 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
455 nbr
->laddr
= (ldp_af_conf_get(leconf
,
458 nbrp
= nbr_params_find(leconf
, nbr
->id
);
460 nbr
->auth
.method
= nbrp
->auth
.method
;
461 if (pfkey_establish(nbr
, nbrp
) == -1)
462 fatalx("pfkey setup failed");
465 if (nbr_session_active_role(nbr
))
466 nbr_establish_connection(nbr
);
469 case IMSG_RTRID_UPDATE
:
470 memcpy(&global
.rtr_id
, imsg
.data
,
471 sizeof(global
.rtr_id
));
472 if (leconf
->rtr_id
.s_addr
== INADDR_ANY
) {
473 ldpe_reset_nbrs(AF_UNSPEC
);
475 if_update_all(AF_UNSPEC
);
476 tnbr_update_all(AF_UNSPEC
);
478 case IMSG_RECONF_CONF
:
479 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) ==
482 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
484 RB_INIT(iface_head
, &nconf
->iface_tree
);
485 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
486 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
487 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
489 case IMSG_RECONF_IFACE
:
490 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
492 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
494 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
496 case IMSG_RECONF_TNBR
:
497 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
499 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
501 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
503 case IMSG_RECONF_NBRP
:
504 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
506 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
508 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
510 case IMSG_RECONF_L2VPN
:
511 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
513 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
515 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
516 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
517 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
519 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
521 case IMSG_RECONF_L2VPN_IF
:
522 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
524 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
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
));
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
));
540 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
542 case IMSG_RECONF_END
:
543 merge_config(leconf
, nconf
);
544 ldp_clear_config(nconf
);
546 global
.conf_seqnum
++;
549 control_imsg_relay(&imsg
);
551 case IMSG_DEBUG_UPDATE
:
552 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
554 log_warnx("%s: wrong imsg len", __func__
);
557 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
559 case IMSG_FILTER_UPDATE
:
560 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
561 sizeof(struct ldp_access
)) {
562 log_warnx("%s: wrong imsg len", __func__
);
566 ldpe_check_filter_af(AF_INET
, &leconf
->ipv4
,
568 ldpe_check_filter_af(AF_INET6
, &leconf
->ipv6
,
571 case IMSG_LDP_SYNC_IF_STATE_REQUEST
:
572 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
573 sizeof(struct ldp_igp_sync_if_state_req
)) {
574 log_warnx("%s: wrong imsg len", __func__
);
577 ldp_sync_if_state_req
= imsg
.data
;
578 ldp_sync_fsm_state_req(ldp_sync_if_state_req
);
581 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
582 sizeof(struct zapi_rlfa_request
)) {
583 log_warnx("%s: wrong imsg len", __func__
);
586 rlfa_req
= imsg
.data
;
588 rnode
= rlfa_node_find(&rlfa_req
->destination
,
589 rlfa_req
->pq_address
);
591 rnode
= rlfa_node_new(&rlfa_req
->destination
,
592 rlfa_req
->pq_address
);
593 rclient
= rlfa_client_find(rnode
, &rlfa_req
->igp
);
595 /* RLFA already registered - do nothing */
597 rclient
= rlfa_client_new(rnode
, &rlfa_req
->igp
);
598 ldpe_rlfa_init(rclient
);
600 case IMSG_RLFA_UNREG_ALL
:
601 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
602 sizeof(struct zapi_rlfa_igp
)) {
603 log_warnx("%s: wrong imsg len", __func__
);
606 rlfa_igp
= imsg
.data
;
608 RB_FOREACH_SAFE (rnode
, ldp_rlfa_node_head
,
609 &rlfa_node_tree
, rntmp
) {
610 rclient
= rlfa_client_find(rnode
, rlfa_igp
);
614 ldpe_rlfa_exit(rclient
);
615 rlfa_client_del(rclient
);
619 log_debug("%s: error handling imsg %d",
620 __func__
, imsg
.hdr
.type
);
628 /* this pipe is dead, so remove the event handlers and exit */
629 THREAD_OFF(iev
->ev_read
);
630 THREAD_OFF(iev
->ev_write
);
636 static void ldpe_dispatch_lde(struct thread
*thread
)
638 struct imsgev
*iev
= THREAD_ARG(thread
);
639 struct imsgbuf
*ibuf
= &iev
->ibuf
;
642 struct notify_msg
*nm
;
648 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
649 fatal("imsg_read error");
650 if (n
== 0) /* connection closed */
654 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
655 fatal("ldpe_dispatch_lde: imsg_get error");
659 switch (imsg
.hdr
.type
) {
660 case IMSG_MAPPING_ADD
:
661 case IMSG_RELEASE_ADD
:
662 case IMSG_REQUEST_ADD
:
663 case IMSG_WITHDRAW_ADD
:
664 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
666 fatalx("invalid size of map request");
669 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
672 if (nbr
->state
!= NBR_STA_OPER
)
675 switch (imsg
.hdr
.type
) {
676 case IMSG_MAPPING_ADD
:
677 mapping_list_add(&nbr
->mapping_list
, map
);
679 case IMSG_RELEASE_ADD
:
680 mapping_list_add(&nbr
->release_list
, map
);
682 case IMSG_REQUEST_ADD
:
683 mapping_list_add(&nbr
->request_list
, map
);
685 case IMSG_WITHDRAW_ADD
:
686 mapping_list_add(&nbr
->withdraw_list
, map
);
690 case IMSG_MAPPING_ADD_END
:
691 case IMSG_RELEASE_ADD_END
:
692 case IMSG_REQUEST_ADD_END
:
693 case IMSG_WITHDRAW_ADD_END
:
694 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
697 if (nbr
->state
!= NBR_STA_OPER
)
700 switch (imsg
.hdr
.type
) {
701 case IMSG_MAPPING_ADD_END
:
702 send_labelmessage(nbr
, MSG_TYPE_LABELMAPPING
,
705 case IMSG_RELEASE_ADD_END
:
706 send_labelmessage(nbr
, MSG_TYPE_LABELRELEASE
,
709 case IMSG_REQUEST_ADD_END
:
710 send_labelmessage(nbr
, MSG_TYPE_LABELREQUEST
,
713 case IMSG_WITHDRAW_ADD_END
:
714 send_labelmessage(nbr
, MSG_TYPE_LABELWITHDRAW
,
715 &nbr
->withdraw_list
);
719 case IMSG_NOTIFICATION_SEND
:
720 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!=
721 sizeof(struct notify_msg
))
722 fatalx("invalid size of OE request");
725 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
727 log_debug("%s: cannot find neighbor", __func__
);
730 if (nbr
->state
!= NBR_STA_OPER
)
733 send_notification_full(nbr
->tcp
, nm
);
736 case IMSG_CTL_SHOW_LIB_BEGIN
:
737 case IMSG_CTL_SHOW_LIB_RCVD
:
738 case IMSG_CTL_SHOW_LIB_SENT
:
739 case IMSG_CTL_SHOW_LIB_END
:
740 case IMSG_CTL_SHOW_L2VPN_PW
:
741 case IMSG_CTL_SHOW_L2VPN_BINDING
:
742 control_imsg_relay(&imsg
);
744 case IMSG_NBR_SHUTDOWN
:
745 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
747 log_debug("%s: cannot find neighbor", __func__
);
750 if (nbr
->state
!= NBR_STA_OPER
)
752 session_shutdown(nbr
,S_SHUTDOWN
,0,0);
755 log_debug("%s: error handling imsg %d",
756 __func__
, imsg
.hdr
.type
);
764 /* this pipe is dead, so remove the event handlers and exit */
765 THREAD_OFF(iev
->ev_read
);
766 THREAD_OFF(iev
->ev_write
);
773 static void ldpe_dispatch_pfkey(struct thread
*thread
)
775 int fd
= THREAD_FD(thread
);
777 thread_add_read(master
, ldpe_dispatch_pfkey
, NULL
, global
.pfkeysock
,
780 if (pfkey_read(fd
, NULL
) == -1)
781 fatal("pfkey_read failed, exiting...");
783 #endif /* __OpenBSD__ */
786 ldpe_setup_sockets(int af
, int disc_socket
, int edisc_socket
,
789 struct ldpd_af_global
*af_global
;
791 af_global
= ldp_af_global_get(&global
, af
);
793 /* discovery socket */
794 af_global
->ldp_disc_socket
= disc_socket
;
795 thread_add_read(master
, disc_recv_packet
, &af_global
->disc_ev
, af_global
->ldp_disc_socket
,
796 &af_global
->disc_ev
);
798 /* extended discovery socket */
799 af_global
->ldp_edisc_socket
= edisc_socket
;
800 thread_add_read(master
, disc_recv_packet
, &af_global
->edisc_ev
, af_global
->ldp_edisc_socket
,
801 &af_global
->edisc_ev
);
804 af_global
->ldp_session_socket
= session_socket
;
805 accept_add(af_global
->ldp_session_socket
, session_accept
, NULL
);
809 ldpe_close_sockets(int af
)
811 struct ldpd_af_global
*af_global
;
813 af_global
= ldp_af_global_get(&global
, af
);
815 /* discovery socket */
816 THREAD_OFF(af_global
->disc_ev
);
817 if (af_global
->ldp_disc_socket
!= -1) {
818 close(af_global
->ldp_disc_socket
);
819 af_global
->ldp_disc_socket
= -1;
822 /* extended discovery socket */
823 THREAD_OFF(af_global
->edisc_ev
);
824 if (af_global
->ldp_edisc_socket
!= -1) {
825 close(af_global
->ldp_edisc_socket
);
826 af_global
->ldp_edisc_socket
= -1;
830 if (af_global
->ldp_session_socket
!= -1) {
831 accept_del(af_global
->ldp_session_socket
);
832 close(af_global
->ldp_session_socket
);
833 af_global
->ldp_session_socket
= -1;
838 ldpe_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
840 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
844 ldpe_reset_nbrs(int af
)
848 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
849 if (af
== AF_UNSPEC
|| nbr
->af
== af
)
850 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
855 ldpe_reset_ds_nbrs(void)
859 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
861 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
866 ldpe_remove_dynamic_tnbrs(int af
)
868 struct tnbr
*tnbr
, *safe
;
870 RB_FOREACH_SAFE(tnbr
, tnbr_head
, &leconf
->tnbr_tree
, safe
) {
874 tnbr
->flags
&= ~F_TNBR_DYNAMIC
;
875 tnbr_check(leconf
, tnbr
);
880 ldpe_stop_init_backoff(int af
)
884 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
885 if (nbr
->af
== af
&& nbr_pending_idtimer(nbr
)) {
886 nbr_stop_idtimer(nbr
);
887 nbr_establish_connection(nbr
);
893 ldpe_iface_af_ctl(struct ctl_conn
*c
, int af
, ifindex_t idx
)
897 struct ctl_iface
*ictl
;
899 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
900 if (idx
== 0 || idx
== iface
->ifindex
) {
901 ia
= iface_af_get(iface
, af
);
905 ictl
= if_to_ctl(ia
);
906 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_INTERFACE
,
907 0, 0, -1, ictl
, sizeof(struct ctl_iface
));
913 ldpe_iface_ctl(struct ctl_conn
*c
, ifindex_t idx
)
915 ldpe_iface_af_ctl(c
, AF_INET
, idx
);
916 ldpe_iface_af_ctl(c
, AF_INET6
, idx
);
920 ldpe_adj_ctl(struct ctl_conn
*c
)
923 struct ctl_adj
*actl
;
925 RB_FOREACH(adj
, global_adj_head
, &global
.adj_tree
) {
926 actl
= adj_to_ctl(adj
);
927 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0,
928 -1, actl
, sizeof(struct ctl_adj
));
931 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
935 ldpe_adj_detail_ctl(struct ctl_conn
*c
)
940 struct ctl_adj
*actl
;
941 struct ctl_disc_if ictl
;
942 struct ctl_disc_tnbr tctl
;
944 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0, -1, NULL
, 0);
946 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
947 memset(&ictl
, 0, sizeof(ictl
));
948 ictl
.active_v4
= (iface
->ipv4
.state
== IF_STA_ACTIVE
);
949 ictl
.active_v6
= (iface
->ipv6
.state
== IF_STA_ACTIVE
);
951 if (!ictl
.active_v4
&& !ictl
.active_v6
)
954 strlcpy(ictl
.name
, iface
->name
, sizeof(ictl
.name
));
955 if (RB_EMPTY(ia_adj_head
, &iface
->ipv4
.adj_tree
) &&
956 RB_EMPTY(ia_adj_head
, &iface
->ipv6
.adj_tree
))
958 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_IFACE
, 0, 0,
959 -1, &ictl
, sizeof(ictl
));
961 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv4
.adj_tree
) {
962 actl
= adj_to_ctl(adj
);
963 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
964 0, 0, -1, actl
, sizeof(struct ctl_adj
));
966 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv6
.adj_tree
) {
967 actl
= adj_to_ctl(adj
);
968 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
969 0, 0, -1, actl
, sizeof(struct ctl_adj
));
973 RB_FOREACH(tnbr
, tnbr_head
, &leconf
->tnbr_tree
) {
974 memset(&tctl
, 0, sizeof(tctl
));
976 tctl
.addr
= tnbr
->addr
;
977 if (tnbr
->adj
== NULL
)
980 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_TNBR
, 0, 0,
981 -1, &tctl
, sizeof(tctl
));
983 if (tnbr
->adj
== NULL
)
986 actl
= adj_to_ctl(tnbr
->adj
);
987 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
, 0, 0,
988 -1, actl
, sizeof(struct ctl_adj
));
991 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
995 ldpe_nbr_ctl(struct ctl_conn
*c
)
998 struct ctl_adj
*actl
;
1000 struct ctl_nbr
*nctl
;
1002 RB_FOREACH(nbr
, nbr_addr_head
, &nbrs_by_addr
) {
1003 if (nbr
->state
== NBR_STA_PRESENT
)
1006 nctl
= nbr_to_ctl(nbr
);
1007 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR
, 0, 0, -1, nctl
,
1008 sizeof(struct ctl_nbr
));
1010 RB_FOREACH(adj
, nbr_adj_head
, &nbr
->adj_tree
) {
1011 actl
= adj_to_ctl(adj
);
1012 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_DISC
,
1013 0, 0, -1, actl
, sizeof(struct ctl_adj
));
1016 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_END
, 0, 0, -1,
1019 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
1023 ldpe_ldp_sync_ctl(struct ctl_conn
*c
)
1025 struct iface
*iface
;
1026 struct ctl_ldp_sync
*ictl
;
1028 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
1029 ictl
= ldp_sync_to_ctl(iface
);
1030 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_LDP_SYNC
,
1031 0, 0, -1, ictl
, sizeof(struct ctl_ldp_sync
));
1033 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
1037 mapping_list_add(struct mapping_head
*mh
, struct map
*map
)
1039 struct mapping_entry
*me
;
1041 me
= calloc(1, sizeof(*me
));
1046 TAILQ_INSERT_TAIL(mh
, me
, entry
);
1050 mapping_list_clr(struct mapping_head
*mh
)
1052 struct mapping_entry
*me
;
1054 while ((me
= TAILQ_FIRST(mh
)) != NULL
) {
1055 TAILQ_REMOVE(mh
, me
, entry
);
1056 assert(me
!= TAILQ_FIRST(mh
));
1062 ldpe_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
1063 const char *filter_name
)
1065 if (strcmp(af_conf
->acl_thello_accept_from
, filter_name
) == 0)
1066 ldpe_remove_dynamic_tnbrs(af
);
1070 ldpe_set_config_change_time(void)
1072 /* SNMP update time when ever there is a config change */
1073 leconf
->config_change_time
= time(NULL
);