1 // SPDX-License-Identifier: ISC
5 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
6 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
7 * Copyright (c) 2004, 2008 Esben Norby <norby@openbsd.org>
8 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
18 #include "ldp_debug.h"
27 static void ldpe_shutdown(void);
28 static void ldpe_dispatch_main(struct event
*thread
);
29 static void ldpe_dispatch_lde(struct event
*thread
);
31 static void ldpe_dispatch_pfkey(struct event
*thread
);
33 static void ldpe_setup_sockets(int, int, int, int);
34 static void ldpe_close_sockets(int);
35 static void ldpe_iface_af_ctl(struct ctl_conn
*c
, int af
, ifindex_t ifidx
);
36 static void ldpe_check_filter_af(int, struct ldpd_af_conf
*, const char *);
38 struct ldpd_conf
*leconf
;
40 struct ldpd_sysdep sysdep
;
43 static struct imsgev iev_main_data
;
44 static struct imsgev
*iev_main
, *iev_main_sync
;
45 static struct imsgev
*iev_lde
;
47 static struct event
*pfkey_ev
;
51 static zebra_capabilities_t _caps_p
[] =
57 struct zebra_privs_t ldpe_privs
=
59 #if defined(VTY_GROUP)
60 .vty_group
= VTY_GROUP
,
63 .cap_num_p
= array_size(_caps_p
),
67 /* SIGINT / SIGTERM handler. */
74 static struct frr_signal_t ldpe_signals
[] =
90 char *pkt_ptr
; /* packet buffer */
92 /* label distribution protocol engine */
96 #ifdef HAVE_SETPROCTITLE
97 setproctitle("ldp engine");
99 ldpd_process
= PROC_LDP_ENGINE
;
100 log_procname
= log_procnames
[ldpd_process
];
103 /* no frr_config_fork() here, allow frr_pthread to create threads */
104 frr_is_after_fork
= true;
106 /* setup signal handler */
107 signal_init(master
, array_size(ldpe_signals
), ldpe_signals
);
109 /* setup pipes and event handlers to the parent process */
110 if ((iev_main
= calloc(1, sizeof(struct imsgev
))) == NULL
)
112 imsg_init(&iev_main
->ibuf
, LDPD_FD_ASYNC
);
113 iev_main
->handler_read
= ldpe_dispatch_main
;
114 event_add_read(master
, iev_main
->handler_read
, iev_main
,
115 iev_main
->ibuf
.fd
, &iev_main
->ev_read
);
116 iev_main
->handler_write
= ldp_write_handler
;
118 memset(&iev_main_data
, 0, sizeof(iev_main_data
));
119 iev_main_sync
= &iev_main_data
;
120 imsg_init(&iev_main_sync
->ibuf
, LDPD_FD_SYNC
);
122 /* create base configuration */
123 leconf
= config_new_empty();
126 while (event_fetch(master
, &thread
))
134 ldpe_init(struct ldpd_init
*init
)
137 /* This socket must be open before dropping privileges. */
138 global
.pfkeysock
= pfkey_init();
139 if (sysdep
.no_pfkey
== 0) {
140 event_add_read(master
, ldpe_dispatch_pfkey
, NULL
,
141 global
.pfkeysock
, &pfkey_ev
);
145 /* drop privileges */
146 ldpe_privs
.user
= init
->user
;
147 ldpe_privs
.group
= init
->group
;
148 zprivs_preinit(&ldpe_privs
);
149 zprivs_init(&ldpe_privs
);
151 /* listen on ldpd control socket */
152 strlcpy(ctl_sock_path
, init
->ctl_sock_path
, sizeof(ctl_sock_path
));
153 if (control_init(ctl_sock_path
) == -1)
154 fatalx("control socket setup failed");
155 TAILQ_INIT(&ctl_conns
);
158 LIST_INIT(&global
.addr_list
);
159 RB_INIT(global_adj_head
, &global
.adj_tree
);
160 TAILQ_INIT(&global
.pending_conns
);
161 if (inet_pton(AF_INET
, AllRouters_v4
, &global
.mcast_addr_v4
) != 1)
163 if (inet_pton(AF_INET6
, AllRouters_v6
, &global
.mcast_addr_v6
) != 1)
166 /* mark sockets as closed */
167 global
.ipv4
.ldp_disc_socket
= -1;
168 global
.ipv4
.ldp_edisc_socket
= -1;
169 global
.ipv4
.ldp_session_socket
= -1;
170 global
.ipv6
.ldp_disc_socket
= -1;
171 global
.ipv6
.ldp_edisc_socket
= -1;
172 global
.ipv6
.ldp_session_socket
= -1;
174 if ((pkt_ptr
= calloc(1, IBUF_READ_SIZE
)) == NULL
)
183 struct if_addr
*if_addr
;
188 msgbuf_clear(&iev_lde
->ibuf
.w
);
189 close(iev_lde
->ibuf
.fd
);
190 iev_lde
->ibuf
.fd
= -1;
192 msgbuf_clear(&iev_main
->ibuf
.w
);
193 close(iev_main
->ibuf
.fd
);
194 iev_main
->ibuf
.fd
= -1;
195 msgbuf_clear(&iev_main_sync
->ibuf
.w
);
196 close(iev_main_sync
->ibuf
.fd
);
197 iev_main_sync
->ibuf
.fd
= -1;
199 control_cleanup(ctl_sock_path
);
202 if (sysdep
.no_pfkey
== 0) {
204 close(global
.pfkeysock
);
207 ldpe_close_sockets(AF_INET
);
208 ldpe_close_sockets(AF_INET6
);
210 /* remove addresses from global list */
211 while ((if_addr
= LIST_FIRST(&global
.addr_list
)) != NULL
) {
212 LIST_REMOVE(if_addr
, entry
);
213 assert(if_addr
!= LIST_FIRST(&global
.addr_list
));
216 while (!RB_EMPTY(global_adj_head
, &global
.adj_tree
)) {
217 adj
= RB_ROOT(global_adj_head
, &global
.adj_tree
);
219 adj_del(adj
, S_SHUTDOWN
);
222 config_clear(leconf
);
229 log_info("ldp engine exiting");
238 ldpe_imsg_compose_parent(int type
, pid_t pid
, void *data
, uint16_t datalen
)
240 if (iev_main
->ibuf
.fd
== -1)
242 return (imsg_compose_event(iev_main
, type
, 0, pid
, -1, data
, datalen
));
246 ldpe_imsg_compose_parent_sync(int type
, pid_t pid
, void *data
, uint16_t datalen
)
248 if (iev_main_sync
->ibuf
.fd
== -1)
250 imsg_compose_event(iev_main_sync
, type
, 0, pid
, -1, data
, datalen
);
251 imsg_flush(&iev_main_sync
->ibuf
);
255 ldpe_imsg_compose_lde(int type
, uint32_t peerid
, pid_t pid
, void *data
,
258 if (iev_lde
->ibuf
.fd
== -1)
260 return (imsg_compose_event(iev_lde
, type
, peerid
, pid
, -1, data
, datalen
));
264 static void ldpe_dispatch_main(struct event
*thread
)
266 static struct ldpd_conf
*nconf
;
267 struct iface
*niface
;
269 struct nbr_params
*nnbrp
;
270 static struct l2vpn
*l2vpn
, *nl2vpn
;
271 struct l2vpn_if
*lif
, *nlif
;
272 struct l2vpn_pw
*pw
, *npw
;
275 struct imsgev
*iev
= EVENT_ARG(thread
);
276 struct imsgbuf
*ibuf
= &iev
->ibuf
;
277 struct iface
*iface
= NULL
;
280 enum socket_type
*socket_type
;
281 static int disc_socket
= -1;
282 static int edisc_socket
= -1;
283 static int session_socket
= -1;
286 struct nbr_params
*nbrp
;
289 struct ldp_access
*laccess
;
290 struct ldp_igp_sync_if_state_req
*ldp_sync_if_state_req
;
291 struct ldp_rlfa_node
*rnode
, *rntmp
;
292 struct ldp_rlfa_client
*rclient
;
293 struct zapi_rlfa_request
*rlfa_req
;
294 struct zapi_rlfa_igp
*rlfa_igp
;
298 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
299 fatal("imsg_read error");
300 if (n
== 0) /* connection closed */
304 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
305 fatal("ldpe_dispatch_main: imsg_get error");
309 switch (imsg
.hdr
.type
) {
311 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct kif
))
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
+ sizeof(struct kaddr
))
338 fatalx("NEWADDR imsg with wrong len");
340 if_addr_add(imsg
.data
);
343 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct kaddr
))
344 fatalx("DELADDR imsg with wrong len");
346 if_addr_del(imsg
.data
);
348 case IMSG_SOCKET_IPC
:
350 log_warnx("%s: received unexpected imsg fd to lde", __func__
);
353 if ((fd
= imsg
.fd
) == -1) {
354 log_warnx("%s: expected to receive imsg fd to lde but didn't receive any", __func__
);
358 if ((iev_lde
= malloc(sizeof(struct imsgev
))) == NULL
)
360 imsg_init(&iev_lde
->ibuf
, fd
);
361 iev_lde
->handler_read
= ldpe_dispatch_lde
;
362 event_add_read(master
, iev_lde
->handler_read
, iev_lde
,
363 iev_lde
->ibuf
.fd
, &iev_lde
->ev_read
);
364 iev_lde
->handler_write
= ldp_write_handler
;
365 iev_lde
->ev_write
= NULL
;
368 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct ldpd_init
))
369 fatalx("INIT imsg with wrong len");
371 memcpy(&init
, imsg
.data
, sizeof(init
));
374 case IMSG_AGENTX_ENABLED
:
375 ldp_agentx_enabled();
377 case IMSG_CLOSE_SOCKETS
:
378 af
= imsg
.hdr
.peerid
;
380 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
383 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
387 nbr
->auth
.method
= AUTH_NONE
;
389 ldpe_close_sockets(af
);
396 if (CHECK_FLAG((ldp_af_conf_get(leconf
, af
))->flags
, F_LDPD_AF_ENABLED
))
397 ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS
, af
, NULL
, 0);
399 case IMSG_SOCKET_NET
:
400 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(enum socket_type
))
401 fatalx("SOCKET_NET imsg with wrong len");
402 socket_type
= imsg
.data
;
404 switch (*socket_type
) {
405 case LDP_SOCKET_DISC
:
406 disc_socket
= imsg
.fd
;
408 case LDP_SOCKET_EDISC
:
409 edisc_socket
= imsg
.fd
;
411 case LDP_SOCKET_SESSION
:
412 session_socket
= imsg
.fd
;
416 case IMSG_SETUP_SOCKETS
:
417 af
= imsg
.hdr
.peerid
;
418 if (disc_socket
== -1 || edisc_socket
== -1 ||
419 session_socket
== -1) {
420 if (disc_socket
!= -1)
422 if (edisc_socket
!= -1)
424 if (session_socket
!= -1)
425 close(session_socket
);
429 ldpe_setup_sockets(af
, disc_socket
, edisc_socket
, session_socket
);
432 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
435 nbr
->laddr
= (ldp_af_conf_get(leconf
, af
))->trans_addr
;
437 nbrp
= nbr_params_find(leconf
, nbr
->id
);
439 nbr
->auth
.method
= nbrp
->auth
.method
;
440 if (pfkey_establish(nbr
, nbrp
) == -1)
441 fatalx("pfkey setup failed");
444 if (nbr_session_active_role(nbr
))
445 nbr_establish_connection(nbr
);
448 case IMSG_RTRID_UPDATE
:
449 memcpy(&global
.rtr_id
, imsg
.data
, sizeof(global
.rtr_id
));
450 if (leconf
->rtr_id
.s_addr
== INADDR_ANY
) {
451 ldpe_reset_nbrs(AF_UNSPEC
);
453 if_update_all(AF_UNSPEC
);
454 tnbr_update_all(AF_UNSPEC
);
456 case IMSG_RECONF_CONF
:
457 if ((nconf
= malloc(sizeof(struct ldpd_conf
))) == NULL
)
459 memcpy(nconf
, imsg
.data
, sizeof(struct ldpd_conf
));
461 RB_INIT(iface_head
, &nconf
->iface_tree
);
462 RB_INIT(tnbr_head
, &nconf
->tnbr_tree
);
463 RB_INIT(nbrp_head
, &nconf
->nbrp_tree
);
464 RB_INIT(l2vpn_head
, &nconf
->l2vpn_tree
);
466 case IMSG_RECONF_IFACE
:
467 if ((niface
= malloc(sizeof(struct iface
))) == NULL
)
469 memcpy(niface
, imsg
.data
, sizeof(struct iface
));
471 RB_INSERT(iface_head
, &nconf
->iface_tree
, niface
);
473 case IMSG_RECONF_TNBR
:
474 if ((ntnbr
= malloc(sizeof(struct tnbr
))) == NULL
)
476 memcpy(ntnbr
, imsg
.data
, sizeof(struct tnbr
));
478 RB_INSERT(tnbr_head
, &nconf
->tnbr_tree
, ntnbr
);
480 case IMSG_RECONF_NBRP
:
481 if ((nnbrp
= malloc(sizeof(struct nbr_params
))) == NULL
)
483 memcpy(nnbrp
, imsg
.data
, sizeof(struct nbr_params
));
485 RB_INSERT(nbrp_head
, &nconf
->nbrp_tree
, nnbrp
);
487 case IMSG_RECONF_L2VPN
:
488 if ((nl2vpn
= malloc(sizeof(struct l2vpn
))) == NULL
)
490 memcpy(nl2vpn
, imsg
.data
, sizeof(struct l2vpn
));
492 RB_INIT(l2vpn_if_head
, &nl2vpn
->if_tree
);
493 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_tree
);
494 RB_INIT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
);
496 RB_INSERT(l2vpn_head
, &nconf
->l2vpn_tree
, nl2vpn
);
498 case IMSG_RECONF_L2VPN_IF
:
499 if ((nlif
= malloc(sizeof(struct l2vpn_if
))) == NULL
)
501 memcpy(nlif
, imsg
.data
, sizeof(struct l2vpn_if
));
503 RB_INSERT(l2vpn_if_head
, &nl2vpn
->if_tree
, nlif
);
505 case IMSG_RECONF_L2VPN_PW
:
506 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
508 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
510 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_tree
, npw
);
512 case IMSG_RECONF_L2VPN_IPW
:
513 if ((npw
= malloc(sizeof(struct l2vpn_pw
))) == NULL
)
515 memcpy(npw
, imsg
.data
, sizeof(struct l2vpn_pw
));
517 RB_INSERT(l2vpn_pw_head
, &nl2vpn
->pw_inactive_tree
, npw
);
519 case IMSG_RECONF_END
:
520 merge_config(leconf
, nconf
);
521 ldp_clear_config(nconf
);
523 global
.conf_seqnum
++;
526 control_imsg_relay(&imsg
);
528 case IMSG_DEBUG_UPDATE
:
529 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
531 log_warnx("%s: wrong imsg len", __func__
);
534 memcpy(&ldp_debug
, imsg
.data
, sizeof(ldp_debug
));
536 case IMSG_FILTER_UPDATE
:
537 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+ sizeof(struct ldp_access
)) {
538 log_warnx("%s: wrong imsg len", __func__
);
542 ldpe_check_filter_af(AF_INET
, &leconf
->ipv4
, laccess
->name
);
543 ldpe_check_filter_af(AF_INET6
, &leconf
->ipv6
, laccess
->name
);
545 case IMSG_LDP_SYNC_IF_STATE_REQUEST
:
546 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
547 sizeof(struct ldp_igp_sync_if_state_req
)) {
548 log_warnx("%s: wrong imsg len", __func__
);
551 ldp_sync_if_state_req
= imsg
.data
;
552 ldp_sync_fsm_state_req(ldp_sync_if_state_req
);
555 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
556 sizeof(struct zapi_rlfa_request
)) {
557 log_warnx("%s: wrong imsg len", __func__
);
560 rlfa_req
= imsg
.data
;
562 rnode
= rlfa_node_find(&rlfa_req
->destination
,
563 rlfa_req
->pq_address
);
565 rnode
= rlfa_node_new(&rlfa_req
->destination
,
566 rlfa_req
->pq_address
);
567 rclient
= rlfa_client_find(rnode
, &rlfa_req
->igp
);
569 /* RLFA already registered - do nothing */
571 rclient
= rlfa_client_new(rnode
, &rlfa_req
->igp
);
572 ldpe_rlfa_init(rclient
);
574 case IMSG_RLFA_UNREG_ALL
:
575 if (imsg
.hdr
.len
!= IMSG_HEADER_SIZE
+
576 sizeof(struct zapi_rlfa_igp
)) {
577 log_warnx("%s: wrong imsg len", __func__
);
580 rlfa_igp
= imsg
.data
;
582 RB_FOREACH_SAFE (rnode
, ldp_rlfa_node_head
,
583 &rlfa_node_tree
, rntmp
) {
584 rclient
= rlfa_client_find(rnode
, rlfa_igp
);
588 ldpe_rlfa_exit(rclient
);
589 rlfa_client_del(rclient
);
593 log_debug("%s: error handling imsg %d", __func__
, imsg
.hdr
.type
);
601 /* this pipe is dead, so remove the event handlers and exit */
602 EVENT_OFF(iev
->ev_read
);
603 EVENT_OFF(iev
->ev_write
);
609 static void ldpe_dispatch_lde(struct event
*thread
)
611 struct imsgev
*iev
= EVENT_ARG(thread
);
612 struct imsgbuf
*ibuf
= &iev
->ibuf
;
615 struct notify_msg
*nm
;
621 if ((n
= imsg_read(ibuf
)) == -1 && errno
!= EAGAIN
)
622 fatal("imsg_read error");
623 if (n
== 0) /* connection closed */
627 if ((n
= imsg_get(ibuf
, &imsg
)) == -1)
628 fatal("ldpe_dispatch_lde: imsg_get error");
632 switch (imsg
.hdr
.type
) {
633 case IMSG_MAPPING_ADD
:
634 case IMSG_RELEASE_ADD
:
635 case IMSG_REQUEST_ADD
:
636 case IMSG_WITHDRAW_ADD
:
637 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct map
))
638 fatalx("invalid size of map request");
641 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
644 if (nbr
->state
!= NBR_STA_OPER
)
647 switch (imsg
.hdr
.type
) {
648 case IMSG_MAPPING_ADD
:
649 mapping_list_add(&nbr
->mapping_list
, map
);
651 case IMSG_RELEASE_ADD
:
652 mapping_list_add(&nbr
->release_list
, map
);
654 case IMSG_REQUEST_ADD
:
655 mapping_list_add(&nbr
->request_list
, map
);
657 case IMSG_WITHDRAW_ADD
:
658 mapping_list_add(&nbr
->withdraw_list
, map
);
662 case IMSG_MAPPING_ADD_END
:
663 case IMSG_RELEASE_ADD_END
:
664 case IMSG_REQUEST_ADD_END
:
665 case IMSG_WITHDRAW_ADD_END
:
666 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
669 if (nbr
->state
!= NBR_STA_OPER
)
672 switch (imsg
.hdr
.type
) {
673 case IMSG_MAPPING_ADD_END
:
674 send_labelmessage(nbr
, MSG_TYPE_LABELMAPPING
,
677 case IMSG_RELEASE_ADD_END
:
678 send_labelmessage(nbr
, MSG_TYPE_LABELRELEASE
,
681 case IMSG_REQUEST_ADD_END
:
682 send_labelmessage(nbr
, MSG_TYPE_LABELREQUEST
,
685 case IMSG_WITHDRAW_ADD_END
:
686 send_labelmessage(nbr
, MSG_TYPE_LABELWITHDRAW
,
687 &nbr
->withdraw_list
);
691 case IMSG_NOTIFICATION_SEND
:
692 if (imsg
.hdr
.len
- IMSG_HEADER_SIZE
!= sizeof(struct notify_msg
))
693 fatalx("invalid size of OE request");
696 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
698 log_debug("%s: cannot find neighbor", __func__
);
701 if (nbr
->state
!= NBR_STA_OPER
)
704 send_notification_full(nbr
->tcp
, nm
);
707 case IMSG_CTL_SHOW_LIB_BEGIN
:
708 case IMSG_CTL_SHOW_LIB_RCVD
:
709 case IMSG_CTL_SHOW_LIB_SENT
:
710 case IMSG_CTL_SHOW_LIB_END
:
711 case IMSG_CTL_SHOW_L2VPN_PW
:
712 case IMSG_CTL_SHOW_L2VPN_BINDING
:
713 control_imsg_relay(&imsg
);
715 case IMSG_NBR_SHUTDOWN
:
716 nbr
= nbr_find_peerid(imsg
.hdr
.peerid
);
718 log_debug("%s: cannot find neighbor", __func__
);
721 if (nbr
->state
!= NBR_STA_OPER
)
723 session_shutdown(nbr
,S_SHUTDOWN
,0,0);
726 log_debug("%s: error handling imsg %d", __func__
, imsg
.hdr
.type
);
734 /* this pipe is dead, so remove the event handlers and exit */
735 EVENT_OFF(iev
->ev_read
);
736 EVENT_OFF(iev
->ev_write
);
743 static void ldpe_dispatch_pfkey(struct event
*thread
)
745 int fd
= EVENT_FD(thread
);
747 event_add_read(master
, ldpe_dispatch_pfkey
, NULL
, global
.pfkeysock
,
750 if (pfkey_read(fd
, NULL
) == -1)
751 fatal("pfkey_read failed, exiting...");
753 #endif /* __OpenBSD__ */
756 ldpe_setup_sockets(int af
, int disc_socket
, int edisc_socket
,
759 struct ldpd_af_global
*af_global
;
761 af_global
= ldp_af_global_get(&global
, af
);
763 /* discovery socket */
764 af_global
->ldp_disc_socket
= disc_socket
;
765 event_add_read(master
, disc_recv_packet
, &af_global
->disc_ev
,
766 af_global
->ldp_disc_socket
, &af_global
->disc_ev
);
768 /* extended discovery socket */
769 af_global
->ldp_edisc_socket
= edisc_socket
;
770 event_add_read(master
, disc_recv_packet
, &af_global
->edisc_ev
,
771 af_global
->ldp_edisc_socket
, &af_global
->edisc_ev
);
774 af_global
->ldp_session_socket
= session_socket
;
775 accept_add(af_global
->ldp_session_socket
, session_accept
, NULL
);
779 ldpe_close_sockets(int af
)
781 struct ldpd_af_global
*af_global
;
783 af_global
= ldp_af_global_get(&global
, af
);
785 /* discovery socket */
786 EVENT_OFF(af_global
->disc_ev
);
787 if (af_global
->ldp_disc_socket
!= -1) {
788 close(af_global
->ldp_disc_socket
);
789 af_global
->ldp_disc_socket
= -1;
792 /* extended discovery socket */
793 EVENT_OFF(af_global
->edisc_ev
);
794 if (af_global
->ldp_edisc_socket
!= -1) {
795 close(af_global
->ldp_edisc_socket
);
796 af_global
->ldp_edisc_socket
= -1;
800 if (af_global
->ldp_session_socket
!= -1) {
801 accept_del(af_global
->ldp_session_socket
);
802 close(af_global
->ldp_session_socket
);
803 af_global
->ldp_session_socket
= -1;
808 ldpe_acl_check(char *acl_name
, int af
, union ldpd_addr
*addr
, uint8_t prefixlen
)
810 return ldp_acl_request(iev_main_sync
, acl_name
, af
, addr
, prefixlen
);
814 ldpe_reset_nbrs(int af
)
818 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
819 if (af
== AF_UNSPEC
|| nbr
->af
== af
)
820 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
825 ldpe_reset_ds_nbrs(void)
829 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
831 session_shutdown(nbr
, S_SHUTDOWN
, 0, 0);
836 ldpe_remove_dynamic_tnbrs(int af
)
838 struct tnbr
*tnbr
, *safe
;
840 RB_FOREACH_SAFE(tnbr
, tnbr_head
, &leconf
->tnbr_tree
, safe
) {
844 UNSET_FLAG(tnbr
->flags
, F_TNBR_DYNAMIC
);
845 tnbr_check(leconf
, tnbr
);
850 ldpe_stop_init_backoff(int af
)
854 RB_FOREACH(nbr
, nbr_id_head
, &nbrs_by_id
) {
855 if (nbr
->af
== af
&& nbr_pending_idtimer(nbr
)) {
856 nbr_stop_idtimer(nbr
);
857 nbr_establish_connection(nbr
);
863 ldpe_iface_af_ctl(struct ctl_conn
*c
, int af
, ifindex_t idx
)
867 struct ctl_iface
*ictl
;
869 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
870 if (idx
== 0 || idx
== iface
->ifindex
) {
871 ia
= iface_af_get(iface
, af
);
875 ictl
= if_to_ctl(ia
);
876 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_INTERFACE
,
877 0, 0, -1, ictl
, sizeof(struct ctl_iface
));
883 ldpe_iface_ctl(struct ctl_conn
*c
, ifindex_t idx
)
885 ldpe_iface_af_ctl(c
, AF_INET
, idx
);
886 ldpe_iface_af_ctl(c
, AF_INET6
, idx
);
890 ldpe_adj_ctl(struct ctl_conn
*c
)
893 struct ctl_adj
*actl
;
895 RB_FOREACH(adj
, global_adj_head
, &global
.adj_tree
) {
896 actl
= adj_to_ctl(adj
);
897 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0,
898 -1, actl
, sizeof(struct ctl_adj
));
901 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
905 ldpe_adj_detail_ctl(struct ctl_conn
*c
)
910 struct ctl_adj
*actl
;
911 struct ctl_disc_if ictl
;
912 struct ctl_disc_tnbr tctl
;
914 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISCOVERY
, 0, 0, -1, NULL
, 0);
916 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
917 memset(&ictl
, 0, sizeof(ictl
));
918 ictl
.active_v4
= (iface
->ipv4
.state
== IF_STA_ACTIVE
);
919 ictl
.active_v6
= (iface
->ipv6
.state
== IF_STA_ACTIVE
);
921 if (!ictl
.active_v4
&& !ictl
.active_v6
)
924 strlcpy(ictl
.name
, iface
->name
, sizeof(ictl
.name
));
925 if (RB_EMPTY(ia_adj_head
, &iface
->ipv4
.adj_tree
) &&
926 RB_EMPTY(ia_adj_head
, &iface
->ipv6
.adj_tree
))
928 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_IFACE
, 0, 0,
929 -1, &ictl
, sizeof(ictl
));
931 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv4
.adj_tree
) {
932 actl
= adj_to_ctl(adj
);
933 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
934 0, 0, -1, actl
, sizeof(struct ctl_adj
));
936 RB_FOREACH(adj
, ia_adj_head
, &iface
->ipv6
.adj_tree
) {
937 actl
= adj_to_ctl(adj
);
938 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
,
939 0, 0, -1, actl
, sizeof(struct ctl_adj
));
943 RB_FOREACH(tnbr
, tnbr_head
, &leconf
->tnbr_tree
) {
944 memset(&tctl
, 0, sizeof(tctl
));
946 tctl
.addr
= tnbr
->addr
;
947 if (tnbr
->adj
== NULL
)
950 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_TNBR
, 0, 0,
951 -1, &tctl
, sizeof(tctl
));
953 if (tnbr
->adj
== NULL
)
956 actl
= adj_to_ctl(tnbr
->adj
);
957 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_DISC_ADJ
, 0, 0,
958 -1, actl
, sizeof(struct ctl_adj
));
961 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
965 ldpe_nbr_ctl(struct ctl_conn
*c
)
968 struct ctl_adj
*actl
;
970 struct ctl_nbr
*nctl
;
972 RB_FOREACH(nbr
, nbr_addr_head
, &nbrs_by_addr
) {
973 if (nbr
->state
== NBR_STA_PRESENT
)
976 nctl
= nbr_to_ctl(nbr
);
977 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR
, 0, 0, -1, nctl
,
978 sizeof(struct ctl_nbr
));
980 RB_FOREACH(adj
, nbr_adj_head
, &nbr
->adj_tree
) {
981 actl
= adj_to_ctl(adj
);
982 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_DISC
,
983 0, 0, -1, actl
, sizeof(struct ctl_adj
));
986 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_NBR_END
, 0, 0, -1,
989 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
993 ldpe_ldp_sync_ctl(struct ctl_conn
*c
)
996 struct ctl_ldp_sync
*ictl
;
998 RB_FOREACH(iface
, iface_head
, &leconf
->iface_tree
) {
999 ictl
= ldp_sync_to_ctl(iface
);
1000 imsg_compose_event(&c
->iev
, IMSG_CTL_SHOW_LDP_SYNC
,
1001 0, 0, -1, ictl
, sizeof(struct ctl_ldp_sync
));
1003 imsg_compose_event(&c
->iev
, IMSG_CTL_END
, 0, 0, -1, NULL
, 0);
1007 mapping_list_add(struct mapping_head
*mh
, struct map
*map
)
1009 struct mapping_entry
*me
;
1011 me
= calloc(1, sizeof(*me
));
1016 TAILQ_INSERT_TAIL(mh
, me
, entry
);
1020 mapping_list_clr(struct mapping_head
*mh
)
1022 struct mapping_entry
*me
;
1024 while ((me
= TAILQ_FIRST(mh
)) != NULL
) {
1025 TAILQ_REMOVE(mh
, me
, entry
);
1026 assert(me
!= TAILQ_FIRST(mh
));
1032 ldpe_check_filter_af(int af
, struct ldpd_af_conf
*af_conf
,
1033 const char *filter_name
)
1035 if (strcmp(af_conf
->acl_thello_accept_from
, filter_name
) == 0)
1036 ldpe_remove_dynamic_tnbrs(af
);
1040 ldpe_set_config_change_time(void)
1042 /* SNMP update time when ever there is a config change */
1043 leconf
->config_change_time
= time(NULL
);