summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldpd/lde.c16
-rw-r--r--ldpd/ldpd.c66
-rw-r--r--ldpd/ldpd.h3
-rw-r--r--ldpd/ldpe.c16
4 files changed, 72 insertions, 29 deletions
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 91b2b1727f..a28862881d 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -58,7 +58,7 @@ struct ldpd_conf *ldeconf;
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;
@@ -133,15 +133,18 @@ lde(const char *user, const char *group)
/* 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();
@@ -162,6 +165,8 @@ lde_shutdown(void)
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();
@@ -171,6 +176,7 @@ lde_shutdown(void)
free(iev_ldpe);
free(iev_main);
+ free(iev_main_sync);
log_info("label decision engine exiting");
exit(0);
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index c9f4e37eee..6fd4251edc 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -42,7 +42,7 @@
#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 *);
@@ -77,8 +77,8 @@ DEFINE_QOBJ_TYPE(ldpd_conf)
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;
@@ -207,8 +207,8 @@ main(int argc, char *argv[])
{
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;
@@ -347,22 +347,34 @@ main(int argc, char *argv[])
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)
@@ -378,22 +390,34 @@ main(int argc, char *argv[])
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");
@@ -466,8 +490,8 @@ ldpd_shutdown(void)
}
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;
@@ -479,12 +503,15 @@ start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
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) {
@@ -702,10 +729,11 @@ main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
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);
}
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index 3f6d7ac569..2c9706cf47 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -33,6 +33,9 @@
#define CONF_FILE "/etc/ldpd.conf"
#define LDPD_USER "_ldpd"
+#define LDPD_FD_ASYNC 3
+#define LDPD_FD_SYNC 4
+
#define LDPD_OPT_VERBOSE 0x00000001
#define LDPD_OPT_VERBOSE2 0x00000002
#define LDPD_OPT_NOACTION 0x00000004
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 1a60af8f41..236e71f322 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -48,7 +48,7 @@ struct ldpd_conf *leconf;
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;
@@ -142,15 +142,18 @@ ldpe(const char *user, const char *group)
/* 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)
@@ -191,6 +194,8 @@ ldpe_shutdown(void)
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);
@@ -215,6 +220,7 @@ ldpe_shutdown(void)
/* clean up */
free(iev_lde);
free(iev_main);
+ free(iev_main_sync);
free(pkt_ptr);
log_info("ldp engine exiting");