mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 22:57:45 +00:00
ldpd: add synchronous IPC channels
By default all ldpd interprocess communication is asynchronous (non-blocking socketpairs). Under some circumstances, however, we'll need synchronous IPC as well. Examples: * the lde child process requesting labels to zebra (through the parent process); * apply an access-list on a given IP prefix (ACLs are only available in the parent process). This patch only adds the necessary infrastructure to allow the child processes to make synchronous requests to the parent process. Later patches will make use of this new infrastructure. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
be54d7449a
commit
28e8294caa
16
ldpd/lde.c
16
ldpd/lde.c
@ -58,7 +58,7 @@ struct ldpd_conf *ldeconf;
|
|||||||
struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
|
struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
|
||||||
|
|
||||||
static struct imsgev *iev_ldpe;
|
static struct imsgev *iev_ldpe;
|
||||||
static struct imsgev *iev_main;
|
static struct imsgev *iev_main, *iev_main_sync;
|
||||||
|
|
||||||
/* Master of threads. */
|
/* Master of threads. */
|
||||||
struct thread_master *master;
|
struct thread_master *master;
|
||||||
@ -133,15 +133,18 @@ lde(const char *user, const char *group)
|
|||||||
/* setup signal handler */
|
/* setup signal handler */
|
||||||
signal_init(master, array_size(lde_signals), lde_signals);
|
signal_init(master, array_size(lde_signals), lde_signals);
|
||||||
|
|
||||||
/* setup pipe and event handler to the parent process */
|
/* setup pipes and event handlers to the parent process */
|
||||||
if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
|
if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
|
||||||
fatal(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->handler_read = lde_dispatch_parent;
|
||||||
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
|
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
|
||||||
iev_main, iev_main->ibuf.fd);
|
iev_main, iev_main->ibuf.fd);
|
||||||
iev_main->handler_write = ldp_write_handler;
|
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 */
|
/* start the LIB garbage collector */
|
||||||
lde_gc_start_timer();
|
lde_gc_start_timer();
|
||||||
@ -162,6 +165,8 @@ lde_shutdown(void)
|
|||||||
close(iev_ldpe->ibuf.fd);
|
close(iev_ldpe->ibuf.fd);
|
||||||
msgbuf_clear(&iev_main->ibuf.w);
|
msgbuf_clear(&iev_main->ibuf.w);
|
||||||
close(iev_main->ibuf.fd);
|
close(iev_main->ibuf.fd);
|
||||||
|
msgbuf_clear(&iev_main_sync->ibuf.w);
|
||||||
|
close(iev_main_sync->ibuf.fd);
|
||||||
|
|
||||||
lde_gc_stop_timer();
|
lde_gc_stop_timer();
|
||||||
lde_nbr_clear();
|
lde_nbr_clear();
|
||||||
@ -171,6 +176,7 @@ lde_shutdown(void)
|
|||||||
|
|
||||||
free(iev_ldpe);
|
free(iev_ldpe);
|
||||||
free(iev_main);
|
free(iev_main);
|
||||||
|
free(iev_main_sync);
|
||||||
|
|
||||||
log_info("label decision engine exiting");
|
log_info("label decision engine exiting");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
66
ldpd/ldpd.c
66
ldpd/ldpd.c
@ -42,7 +42,7 @@
|
|||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
|
|
||||||
static void ldpd_shutdown(void);
|
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 *);
|
const char *, const char *);
|
||||||
static int main_dispatch_ldpe(struct thread *);
|
static int main_dispatch_ldpe(struct thread *);
|
||||||
static int main_dispatch_lde(struct thread *);
|
static int main_dispatch_lde(struct thread *);
|
||||||
@ -77,8 +77,8 @@ DEFINE_QOBJ_TYPE(ldpd_conf)
|
|||||||
struct ldpd_global global;
|
struct ldpd_global global;
|
||||||
struct ldpd_conf *ldpd_conf;
|
struct ldpd_conf *ldpd_conf;
|
||||||
|
|
||||||
static struct imsgev *iev_ldpe;
|
static struct imsgev *iev_ldpe, *iev_ldpe_sync;
|
||||||
static struct imsgev *iev_lde;
|
static struct imsgev *iev_lde, *iev_lde_sync;
|
||||||
static pid_t ldpe_pid;
|
static pid_t ldpe_pid;
|
||||||
static pid_t lde_pid;
|
static pid_t lde_pid;
|
||||||
|
|
||||||
@ -207,8 +207,8 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
char *saved_argv0;
|
char *saved_argv0;
|
||||||
int lflag = 0, eflag = 0;
|
int lflag = 0, eflag = 0;
|
||||||
int pipe_parent2ldpe[2];
|
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
|
||||||
int pipe_parent2lde[2];
|
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
|
||||||
char *p;
|
char *p;
|
||||||
char *vty_addr = NULL;
|
char *vty_addr = NULL;
|
||||||
int vty_port = LDP_VTY_PORT;
|
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)
|
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
|
||||||
fatal("socketpair");
|
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)
|
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1)
|
||||||
fatal("socketpair");
|
fatal("socketpair");
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
|
||||||
|
pipe_parent2lde_sync) == -1)
|
||||||
|
fatal("socketpair");
|
||||||
sock_set_nonblock(pipe_parent2ldpe[0]);
|
sock_set_nonblock(pipe_parent2ldpe[0]);
|
||||||
sock_set_cloexec(pipe_parent2ldpe[0]);
|
sock_set_cloexec(pipe_parent2ldpe[0]);
|
||||||
sock_set_nonblock(pipe_parent2ldpe[1]);
|
sock_set_nonblock(pipe_parent2ldpe[1]);
|
||||||
sock_set_cloexec(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_nonblock(pipe_parent2lde[0]);
|
||||||
sock_set_cloexec(pipe_parent2lde[0]);
|
sock_set_cloexec(pipe_parent2lde[0]);
|
||||||
sock_set_nonblock(pipe_parent2lde[1]);
|
sock_set_nonblock(pipe_parent2lde[1]);
|
||||||
sock_set_cloexec(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 */
|
/* start children */
|
||||||
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
|
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,
|
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 */
|
/* drop privileges */
|
||||||
if (user)
|
if (user)
|
||||||
@ -378,22 +390,34 @@ main(int argc, char *argv[])
|
|||||||
ldp_zebra_init(master);
|
ldp_zebra_init(master);
|
||||||
|
|
||||||
/* setup pipes to children */
|
/* setup pipes to children */
|
||||||
if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
|
if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
|
||||||
(iev_lde = malloc(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);
|
fatal(NULL);
|
||||||
imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
|
imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
|
||||||
iev_ldpe->handler_read = main_dispatch_ldpe;
|
iev_ldpe->handler_read = main_dispatch_ldpe;
|
||||||
iev_ldpe->ev_read = thread_add_read(master, iev_ldpe->handler_read,
|
iev_ldpe->ev_read = thread_add_read(master, iev_ldpe->handler_read,
|
||||||
iev_ldpe, iev_ldpe->ibuf.fd);
|
iev_ldpe, iev_ldpe->ibuf.fd);
|
||||||
iev_ldpe->handler_write = ldp_write_handler;
|
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]);
|
imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
|
||||||
iev_lde->handler_read = main_dispatch_lde;
|
iev_lde->handler_read = main_dispatch_lde;
|
||||||
iev_lde->ev_read = thread_add_read(master, iev_lde->handler_read,
|
iev_lde->ev_read = thread_add_read(master, iev_lde->handler_read,
|
||||||
iev_lde, iev_lde->ibuf.fd);
|
iev_lde, iev_lde->ibuf.fd);
|
||||||
iev_lde->handler_write = ldp_write_handler;
|
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))
|
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
|
||||||
fatal("could not establish imsg links");
|
fatal("could not establish imsg links");
|
||||||
@ -466,8 +490,8 @@ ldpd_shutdown(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static pid_t
|
static pid_t
|
||||||
start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
|
start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
|
||||||
const char *group)
|
const char *user, const char *group)
|
||||||
{
|
{
|
||||||
char *argv[7];
|
char *argv[7];
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
@ -479,12 +503,15 @@ start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
close(fd);
|
close(fd_async);
|
||||||
|
close(fd_sync);
|
||||||
return (pid);
|
return (pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dup2(fd, 3) == -1)
|
if (dup2(fd_async, LDPD_FD_ASYNC) == -1)
|
||||||
fatal("cannot setup imsg fd");
|
fatal("cannot setup imsg async fd");
|
||||||
|
if (dup2(fd_sync, LDPD_FD_SYNC) == -1)
|
||||||
|
fatal("cannot setup imsg sync fd");
|
||||||
|
|
||||||
argv[argc++] = argv0;
|
argv[argc++] = argv0;
|
||||||
switch (p) {
|
switch (p) {
|
||||||
@ -702,10 +729,11 @@ main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
|
|||||||
void
|
void
|
||||||
imsg_event_add(struct imsgev *iev)
|
imsg_event_add(struct imsgev *iev)
|
||||||
{
|
{
|
||||||
THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
|
if (iev->handler_read)
|
||||||
iev->ibuf.fd);
|
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,
|
THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
|
||||||
iev->ibuf.fd);
|
iev->ibuf.fd);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
#define CONF_FILE "/etc/ldpd.conf"
|
#define CONF_FILE "/etc/ldpd.conf"
|
||||||
#define LDPD_USER "_ldpd"
|
#define LDPD_USER "_ldpd"
|
||||||
|
|
||||||
|
#define LDPD_FD_ASYNC 3
|
||||||
|
#define LDPD_FD_SYNC 4
|
||||||
|
|
||||||
#define LDPD_OPT_VERBOSE 0x00000001
|
#define LDPD_OPT_VERBOSE 0x00000001
|
||||||
#define LDPD_OPT_VERBOSE2 0x00000002
|
#define LDPD_OPT_VERBOSE2 0x00000002
|
||||||
#define LDPD_OPT_NOACTION 0x00000004
|
#define LDPD_OPT_NOACTION 0x00000004
|
||||||
|
16
ldpd/ldpe.c
16
ldpd/ldpe.c
@ -48,7 +48,7 @@ struct ldpd_conf *leconf;
|
|||||||
struct ldpd_sysdep sysdep;
|
struct ldpd_sysdep sysdep;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct imsgev *iev_main;
|
static struct imsgev *iev_main, *iev_main_sync;
|
||||||
static struct imsgev *iev_lde;
|
static struct imsgev *iev_lde;
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
static struct thread *pfkey_ev;
|
static struct thread *pfkey_ev;
|
||||||
@ -142,15 +142,18 @@ ldpe(const char *user, const char *group)
|
|||||||
/* setup signal handler */
|
/* setup signal handler */
|
||||||
signal_init(master, array_size(ldpe_signals), ldpe_signals);
|
signal_init(master, array_size(ldpe_signals), ldpe_signals);
|
||||||
|
|
||||||
/* setup pipe and event handler to the parent process */
|
/* setup pipes and event handlers to the parent process */
|
||||||
if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
|
if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
|
||||||
fatal(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->handler_read = ldpe_dispatch_main;
|
||||||
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
|
iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
|
||||||
iev_main, iev_main->ibuf.fd);
|
iev_main, iev_main->ibuf.fd);
|
||||||
iev_main->handler_write = ldp_write_handler;
|
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__
|
#ifdef __OpenBSD__
|
||||||
if (sysdep.no_pfkey == 0)
|
if (sysdep.no_pfkey == 0)
|
||||||
@ -191,6 +194,8 @@ ldpe_shutdown(void)
|
|||||||
msgbuf_write(&iev_main->ibuf.w);
|
msgbuf_write(&iev_main->ibuf.w);
|
||||||
msgbuf_clear(&iev_main->ibuf.w);
|
msgbuf_clear(&iev_main->ibuf.w);
|
||||||
close(iev_main->ibuf.fd);
|
close(iev_main->ibuf.fd);
|
||||||
|
msgbuf_clear(&iev_main_sync->ibuf.w);
|
||||||
|
close(iev_main_sync->ibuf.fd);
|
||||||
|
|
||||||
control_cleanup();
|
control_cleanup();
|
||||||
config_clear(leconf);
|
config_clear(leconf);
|
||||||
@ -215,6 +220,7 @@ ldpe_shutdown(void)
|
|||||||
/* clean up */
|
/* clean up */
|
||||||
free(iev_lde);
|
free(iev_lde);
|
||||||
free(iev_main);
|
free(iev_main);
|
||||||
|
free(iev_main_sync);
|
||||||
free(pkt_ptr);
|
free(pkt_ptr);
|
||||||
|
|
||||||
log_info("ldp engine exiting");
|
log_info("ldp engine exiting");
|
||||||
|
Loading…
Reference in New Issue
Block a user