struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
static struct imsgev *iev_ldpe;
-static struct imsgev *iev_main;
+static struct imsgev *iev_main, *iev_main_sync;
/* Master of threads. */
struct thread_master *master;
/* setup signal handler */
signal_init(master, array_size(lde_signals), lde_signals);
- /* setup pipe and event handler to the parent process */
- if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipes and event handlers to the parent process */
+ if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_main->ibuf, 3);
+ imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = lde_dispatch_parent;
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
iev_main, iev_main->ibuf.fd);
iev_main->handler_write = ldp_write_handler;
- iev_main->ev_write = NULL;
+
+ if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
+ fatal(NULL);
+ imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
/* start the LIB garbage collector */
lde_gc_start_timer();
close(iev_ldpe->ibuf.fd);
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ msgbuf_clear(&iev_main_sync->ibuf.w);
+ close(iev_main_sync->ibuf.fd);
lde_gc_stop_timer();
lde_nbr_clear();
free(iev_ldpe);
free(iev_main);
+ free(iev_main_sync);
log_info("label decision engine exiting");
exit(0);
#include "qobj.h"
static void ldpd_shutdown(void);
-static pid_t start_child(enum ldpd_process, char *, int,
+static pid_t start_child(enum ldpd_process, char *, int, int,
const char *, const char *);
static int main_dispatch_ldpe(struct thread *);
static int main_dispatch_lde(struct thread *);
struct ldpd_global global;
struct ldpd_conf *ldpd_conf;
-static struct imsgev *iev_ldpe;
-static struct imsgev *iev_lde;
+static struct imsgev *iev_ldpe, *iev_ldpe_sync;
+static struct imsgev *iev_lde, *iev_lde_sync;
static pid_t ldpe_pid;
static pid_t lde_pid;
{
char *saved_argv0;
int lflag = 0, eflag = 0;
- int pipe_parent2ldpe[2];
- int pipe_parent2lde[2];
+ int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
+ int pipe_parent2lde[2], pipe_parent2lde_sync[2];
char *p;
char *vty_addr = NULL;
int vty_port = LDP_VTY_PORT;
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
fatal("socketpair");
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
+ pipe_parent2ldpe_sync) == -1)
+ fatal("socketpair");
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1)
fatal("socketpair");
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
+ pipe_parent2lde_sync) == -1)
+ fatal("socketpair");
sock_set_nonblock(pipe_parent2ldpe[0]);
sock_set_cloexec(pipe_parent2ldpe[0]);
sock_set_nonblock(pipe_parent2ldpe[1]);
sock_set_cloexec(pipe_parent2ldpe[1]);
+ sock_set_nonblock(pipe_parent2ldpe_sync[0]);
+ sock_set_cloexec(pipe_parent2ldpe_sync[0]);
+ sock_set_cloexec(pipe_parent2ldpe_sync[1]);
sock_set_nonblock(pipe_parent2lde[0]);
sock_set_cloexec(pipe_parent2lde[0]);
sock_set_nonblock(pipe_parent2lde[1]);
sock_set_cloexec(pipe_parent2lde[1]);
+ sock_set_nonblock(pipe_parent2lde_sync[0]);
+ sock_set_cloexec(pipe_parent2lde_sync[0]);
+ sock_set_cloexec(pipe_parent2lde_sync[1]);
/* start children */
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
- pipe_parent2lde[1], user, group);
+ pipe_parent2lde[1], pipe_parent2lde_sync[1], user, group);
ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
- pipe_parent2ldpe[1], user, group);
+ pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1], user, group);
/* drop privileges */
if (user)
ldp_zebra_init(master);
/* setup pipes to children */
- if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
- (iev_lde = malloc(sizeof(struct imsgev))) == NULL)
+ if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_lde = calloc(1, sizeof(struct imsgev))) == NULL ||
+ (iev_lde_sync = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
iev_ldpe->handler_read = main_dispatch_ldpe;
iev_ldpe->ev_read = thread_add_read(master, iev_ldpe->handler_read,
iev_ldpe, iev_ldpe->ibuf.fd);
iev_ldpe->handler_write = ldp_write_handler;
- iev_ldpe->ev_write = NULL;
+
+ imsg_init(&iev_ldpe_sync->ibuf, pipe_parent2ldpe_sync[0]);
+ iev_ldpe_sync->handler_read = main_dispatch_ldpe;
+ iev_ldpe_sync->ev_read = thread_add_read(master,
+ iev_ldpe_sync->handler_read, iev_ldpe_sync, iev_ldpe_sync->ibuf.fd);
+ iev_ldpe_sync->handler_write = ldp_write_handler;
imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
iev_lde->handler_read = main_dispatch_lde;
iev_lde->ev_read = thread_add_read(master, iev_lde->handler_read,
iev_lde, iev_lde->ibuf.fd);
iev_lde->handler_write = ldp_write_handler;
- iev_lde->ev_write = NULL;
+
+ imsg_init(&iev_lde_sync->ibuf, pipe_parent2lde_sync[0]);
+ iev_lde_sync->handler_read = main_dispatch_lde;
+ iev_lde_sync->ev_read = thread_add_read(master,
+ iev_lde_sync->handler_read, iev_lde_sync, iev_lde_sync->ibuf.fd);
+ iev_lde_sync->handler_write = ldp_write_handler;
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
fatal("could not establish imsg links");
}
static pid_t
-start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
- const char *group)
+start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
+ const char *user, const char *group)
{
char *argv[7];
int argc = 0;
case 0:
break;
default:
- close(fd);
+ close(fd_async);
+ close(fd_sync);
return (pid);
}
- if (dup2(fd, 3) == -1)
- fatal("cannot setup imsg fd");
+ if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
+ fatal("cannot setup imsg async fd");
+ if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
+ fatal("cannot setup imsg sync fd");
argv[argc++] = argv0;
switch (p) {
void
imsg_event_add(struct imsgev *iev)
{
- THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
- iev->ibuf.fd);
+ if (iev->handler_read)
+ THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
+ iev->ibuf.fd);
- if (iev->ibuf.w.queued)
+ if (iev->handler_write && iev->ibuf.w.queued)
THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
iev->ibuf.fd);
}
struct ldpd_sysdep sysdep;
#endif
-static struct imsgev *iev_main;
+static struct imsgev *iev_main, *iev_main_sync;
static struct imsgev *iev_lde;
#ifdef __OpenBSD__
static struct thread *pfkey_ev;
/* setup signal handler */
signal_init(master, array_size(ldpe_signals), ldpe_signals);
- /* setup pipe and event handler to the parent process */
- if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipes and event handlers to the parent process */
+ if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_main->ibuf, 3);
+ imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
iev_main->handler_read = ldpe_dispatch_main;
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
iev_main, iev_main->ibuf.fd);
iev_main->handler_write = ldp_write_handler;
- iev_main->ev_write = NULL;
+
+ if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
+ fatal(NULL);
+ imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
#ifdef __OpenBSD__
if (sysdep.no_pfkey == 0)
msgbuf_write(&iev_main->ibuf.w);
msgbuf_clear(&iev_main->ibuf.w);
close(iev_main->ibuf.fd);
+ msgbuf_clear(&iev_main_sync->ibuf.w);
+ close(iev_main_sync->ibuf.fd);
control_cleanup();
config_clear(leconf);
/* clean up */
free(iev_lde);
free(iev_main);
+ free(iev_main_sync);
free(pkt_ptr);
log_info("ldp engine exiting");