summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorRenato Westphal <renato@cvs.openbsd.org>2016-06-05 03:36:42 +0000
committerRenato Westphal <renato@cvs.openbsd.org>2016-06-05 03:36:42 +0000
commit8c52fa46cd83fa18752be56c95efe5c5539052a5 (patch)
tree262d93a452db4bf397566c91a416b752ffac5ced /usr.sbin
parent0cd0e350cd3c14ca2f61e9ffbfe71e2815d6eaa2 (diff)
Improve security by calling exec after fork.
For each child process (rde and eigrpe), re-exec eigrpd with a special "per-role" getopt flag. This way we have seperate ASLR/cookies per process. Based on a similar patch for bgpd, from claudio@ ok deraadt
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/eigrpd/eigrpd.c162
-rw-r--r--usr.sbin/eigrpd/eigrpd.h6
-rw-r--r--usr.sbin/eigrpd/eigrpe.c73
-rw-r--r--usr.sbin/eigrpd/eigrpe.h4
-rw-r--r--usr.sbin/eigrpd/parse.y8
-rw-r--r--usr.sbin/eigrpd/rde.c69
-rw-r--r--usr.sbin/eigrpd/rde.h4
7 files changed, 206 insertions, 120 deletions
diff --git a/usr.sbin/eigrpd/eigrpd.c b/usr.sbin/eigrpd/eigrpd.c
index 98e99c640d3..2f274664c8c 100644
--- a/usr.sbin/eigrpd/eigrpd.c
+++ b/usr.sbin/eigrpd/eigrpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eigrpd.c,v 1.14 2016/05/12 00:15:24 renato Exp $ */
+/* $OpenBSD: eigrpd.c,v 1.15 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -41,19 +41,18 @@
void main_sig_handler(int, short, void *);
__dead void usage(void);
void eigrpd_shutdown(void);
+pid_t start_child(enum eigrpd_process, char *, int, int, int, char *);
int check_child(pid_t, const char *);
void main_dispatch_eigrpe(int, short, void *);
void main_dispatch_rde(int, short, void *);
+int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
+int main_imsg_send_config(struct eigrpd_conf *);
int eigrp_reload(void);
int eigrp_sendboth(enum imsg_type, void *, uint16_t);
void merge_instances(struct eigrpd_conf *, struct eigrp *, struct eigrp *);
-int pipe_parent2eigrpe[2];
-int pipe_parent2rde[2];
-int pipe_eigrpe2rde[2];
-
struct eigrpd_conf *eigrpd_conf = NULL;
struct imsgev *iev_eigrpe;
struct imsgev *iev_rde;
@@ -118,12 +117,15 @@ int
main(int argc, char *argv[])
{
struct event ev_sigint, ev_sigterm, ev_sigchld, ev_sighup;
+ char *saved_argv0;
int ch;
- int debug = 0;
+ int debug = 0, rflag = 0, eflag = 0;
int ipforwarding;
int mib[4];
size_t len;
char *sockname;
+ int pipe_parent2eigrpe[2];
+ int pipe_parent2rde[2];
conffile = CONF_FILE;
eigrpd_process = PROC_MAIN;
@@ -132,7 +134,11 @@ main(int argc, char *argv[])
log_init(1); /* log to stderr until daemonized */
log_verbose(1);
- while ((ch = getopt(argc, argv, "dD:f:ns:v")) != -1) {
+ saved_argv0 = argv[0];
+ if (saved_argv0 == NULL)
+ saved_argv0 = "eigrpd";
+
+ while ((ch = getopt(argc, argv, "dD:f:ns:vRE")) != -1) {
switch (ch) {
case 'd':
debug = 1;
@@ -156,6 +162,12 @@ main(int argc, char *argv[])
global.cmd_opts |= EIGRPD_OPT_VERBOSE2;
global.cmd_opts |= EIGRPD_OPT_VERBOSE;
break;
+ case 'R':
+ rflag = 1;
+ break;
+ case 'E':
+ eflag = 1;
+ break;
default:
usage();
/* NOTREACHED */
@@ -164,9 +176,14 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (argc > 0)
+ if (argc > 0 || (rflag && eflag))
usage();
+ if (rflag)
+ rde(debug, global.cmd_opts & EIGRPD_OPT_VERBOSE);
+ else if (eflag)
+ eigrpe(debug, global.cmd_opts & EIGRPD_OPT_VERBOSE, sockname);
+
mib[0] = CTL_NET;
mib[1] = PF_INET;
mib[2] = IPPROTO_IP;
@@ -186,7 +203,6 @@ main(int argc, char *argv[])
kif_clear();
exit(1);
}
- global.csock = sockname;
if (global.cmd_opts & EIGRPD_OPT_NOACTION) {
if (global.cmd_opts & EIGRPD_OPT_VERBOSE)
@@ -219,15 +235,13 @@ main(int argc, char *argv[])
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
PF_UNSPEC, pipe_parent2rde) == -1)
fatal("socketpair");
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- PF_UNSPEC, pipe_eigrpe2rde) == -1)
- fatal("socketpair");
/* start children */
- rde_pid = rde(eigrpd_conf, pipe_parent2rde, pipe_eigrpe2rde,
- pipe_parent2eigrpe);
- eigrpe_pid = eigrpe(eigrpd_conf, pipe_parent2eigrpe, pipe_eigrpe2rde,
- pipe_parent2rde);
+ rde_pid = start_child(PROC_RDE_ENGINE, saved_argv0, pipe_parent2rde[1],
+ debug, global.cmd_opts & EIGRPD_OPT_VERBOSE, NULL);
+ eigrpe_pid = start_child(PROC_EIGRP_ENGINE, saved_argv0,
+ pipe_parent2eigrpe[1], debug, global.cmd_opts & EIGRPD_OPT_VERBOSE,
+ sockname);
event_init();
@@ -243,11 +257,6 @@ main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
/* setup pipes to children */
- close(pipe_parent2eigrpe[1]);
- close(pipe_parent2rde[1]);
- close(pipe_eigrpe2rde[0]);
- close(pipe_eigrpe2rde[1]);
-
if ((iev_eigrpe = malloc(sizeof(struct imsgev))) == NULL ||
(iev_rde = malloc(sizeof(struct imsgev))) == NULL)
fatal(NULL);
@@ -256,6 +265,10 @@ main(int argc, char *argv[])
imsg_init(&iev_rde->ibuf, pipe_parent2rde[0]);
iev_rde->handler = main_dispatch_rde;
+ if (main_imsg_send_ipc_sockets(&iev_eigrpe->ibuf, &iev_rde->ibuf))
+ fatal("could not establish imsg links");
+ main_imsg_send_config(eigrpd_conf);
+
/* setup event handler */
iev_eigrpe->events = EV_READ;
event_set(&iev_eigrpe->ev, iev_eigrpe->ibuf.fd, iev_eigrpe->events,
@@ -274,7 +287,7 @@ main(int argc, char *argv[])
eigrpd_conf->rdomain) == -1)
fatalx("kr_init failed");
- if (pledge("inet rpath stdio proc", NULL) == -1)
+ if (pledge("inet rpath stdio proc sendfd", NULL) == -1)
fatal("pledge");
event_dispatch();
@@ -314,6 +327,52 @@ eigrpd_shutdown(void)
exit(0);
}
+pid_t
+start_child(enum eigrpd_process p, char *argv0, int fd, int debug, int verbose,
+ char *sockname)
+{
+ char *argv[7];
+ int argc = 0;
+ pid_t pid;
+
+ switch (pid = fork()) {
+ case -1:
+ fatal("cannot fork");
+ case 0:
+ break;
+ default:
+ close(fd);
+ return (pid);
+ }
+
+ if (dup2(fd, 3) == -1)
+ fatal("cannot setup imsg fd");
+
+ argv[argc++] = argv0;
+ switch (p) {
+ case PROC_MAIN:
+ fatalx("Can not start main process");
+ case PROC_RDE_ENGINE:
+ argv[argc++] = "-R";
+ break;
+ case PROC_EIGRP_ENGINE:
+ argv[argc++] = "-E";
+ break;
+ }
+ if (debug)
+ argv[argc++] = "-d";
+ if (verbose)
+ argv[argc++] = "-v";
+ if (sockname) {
+ argv[argc++] = "-s";
+ argv[argc++] = sockname;
+ }
+ argv[argc++] = NULL;
+
+ execvp(argv0, argv);
+ fatal("execvp");
+}
+
int
check_child(pid_t pid, const char *pname)
{
@@ -514,6 +573,25 @@ imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
return (ret);
}
+int
+main_imsg_send_ipc_sockets(struct imsgbuf *eigrpe_buf, struct imsgbuf *rde_buf)
+{
+ int pipe_eigrpe2rde[2];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+ PF_UNSPEC, pipe_eigrpe2rde) == -1)
+ return (-1);
+
+ if (imsg_compose(eigrpe_buf, IMSG_SOCKET_IPC, 0, 0, pipe_eigrpe2rde[0],
+ NULL, 0) == -1)
+ return (-1);
+ if (imsg_compose(rde_buf, IMSG_SOCKET_IPC, 0, 0, pipe_eigrpe2rde[1],
+ NULL, 0) == -1)
+ return (-1);
+
+ return (0);
+}
+
uint32_t
eigrp_router_id(struct eigrpd_conf *xconf)
{
@@ -533,14 +611,10 @@ eigrp_find(struct eigrpd_conf *xconf, int af, uint16_t as)
}
int
-eigrp_reload(void)
+main_imsg_send_config(struct eigrpd_conf *xconf)
{
struct eigrp *eigrp;
struct eigrp_iface *ei;
- struct eigrpd_conf *xconf;
-
- if ((xconf = parse_config(conffile)) == NULL)
- return (-1);
if (eigrp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
return (-1);
@@ -564,6 +638,20 @@ eigrp_reload(void)
if (eigrp_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
return (-1);
+ return (0);
+}
+
+int
+eigrp_reload(void)
+{
+ struct eigrpd_conf *xconf;
+
+ if ((xconf = parse_config(conffile)) == NULL)
+ return (-1);
+
+ if (main_imsg_send_config(xconf) == -1)
+ return (-1);
+
merge_config(eigrpd_conf, xconf);
return (0);
@@ -666,18 +754,28 @@ merge_instances(struct eigrpd_conf *xconf, struct eigrp *eigrp, struct eigrp *xe
/* TODO */
}
-void
-config_clear(struct eigrpd_conf *conf)
+struct eigrpd_conf *
+config_new_empty(void)
{
struct eigrpd_conf *xconf;
- /* merge current config with an empty config */
- xconf = malloc(sizeof(*xconf));
+ xconf = calloc(1, sizeof(*xconf));
if (xconf == NULL)
fatal(NULL);
- *xconf = *conf;
TAILQ_INIT(&xconf->instances);
+ TAILQ_INIT(&xconf->iface_list);
+
+ return (xconf);
+}
+
+void
+config_clear(struct eigrpd_conf *conf)
+{
+ struct eigrpd_conf *xconf;
+
+ /* merge current config with an empty config */
+ xconf = config_new_empty();
merge_config(conf, xconf);
free(conf);
diff --git a/usr.sbin/eigrpd/eigrpd.h b/usr.sbin/eigrpd/eigrpd.h
index 34dd0b1b71b..41ddb49e90d 100644
--- a/usr.sbin/eigrpd/eigrpd.h
+++ b/usr.sbin/eigrpd/eigrpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: eigrpd.h,v 1.14 2016/04/15 13:34:08 renato Exp $ */
+/* $OpenBSD: eigrpd.h,v 1.15 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -112,6 +112,7 @@ enum imsg_type {
IMSG_SEND_SIAREPLY_END,
IMSG_SEND_MUPDATE_END,
IMSG_SEND_MQUERY_END,
+ IMSG_SOCKET_IPC,
IMSG_RECONF_CONF,
IMSG_RECONF_IFACE,
IMSG_RECONF_INSTANCE,
@@ -302,7 +303,7 @@ struct eigrp {
};
/* eigrp_conf */
-enum {
+enum eigrpd_process {
PROC_MAIN,
PROC_EIGRP_ENGINE,
PROC_RDE_ENGINE
@@ -483,6 +484,7 @@ void clearscope(struct in6_addr *);
void main_imsg_compose_eigrpe(int, pid_t, void *, uint16_t);
void main_imsg_compose_rde(int, pid_t, void *, uint16_t);
void merge_config(struct eigrpd_conf *, struct eigrpd_conf *);
+struct eigrpd_conf *config_new_empty(void);
void config_clear(struct eigrpd_conf *);
void imsg_event_add(struct imsgev *);
int imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
diff --git a/usr.sbin/eigrpd/eigrpe.c b/usr.sbin/eigrpd/eigrpe.c
index d468c6978e9..75f310fe909 100644
--- a/usr.sbin/eigrpd/eigrpe.c
+++ b/usr.sbin/eigrpd/eigrpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: eigrpe.c,v 1.22 2016/05/12 00:18:27 renato Exp $ */
+/* $OpenBSD: eigrpe.c,v 1.23 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -66,24 +66,18 @@ eigrpe_sig_handler(int sig, short event, void *bula)
/* eigrp engine */
pid_t
-eigrpe(struct eigrpd_conf *xconf, int pipe_parent2eigrpe[2],
- int pipe_eigrpe2rde[2], int pipe_parent2rde[2])
+eigrpe(int debug, int verbose, char *sockname)
{
struct passwd *pw;
struct event ev_sigint, ev_sigterm;
- pid_t pid;
- struct iface *iface;
-
- switch (pid = fork()) {
- case -1:
- fatal("cannot fork");
- case 0:
- break;
- default:
- return (pid);
- }
+
+ econf = config_new_empty();
+
+ log_init(debug);
+ log_verbose(verbose);
/* create eigrpd control socket outside chroot */
+ global.csock = sockname;
if (control_init(global.csock) == -1)
fatalx("control socket setup failed");
@@ -118,8 +112,6 @@ eigrpe(struct eigrpd_conf *xconf, int pipe_parent2eigrpe[2],
fatal("if_set_ipv6_dscp");
if_set_sockbuf(global.eigrp_socket_v6);
- econf = xconf;
-
if ((pw = getpwnam(EIGRPD_USER)) == NULL)
fatal("getpwnam");
@@ -146,26 +138,11 @@ eigrpe(struct eigrpd_conf *xconf, int pipe_parent2eigrpe[2],
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
- /* setup pipes */
- close(pipe_parent2eigrpe[0]);
- close(pipe_eigrpe2rde[1]);
- close(pipe_parent2rde[0]);
- close(pipe_parent2rde[1]);
-
- if ((iev_rde = malloc(sizeof(struct imsgev))) == NULL ||
- (iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipe and event handler to the parent process */
+ if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_rde->ibuf, pipe_eigrpe2rde[0]);
- iev_rde->handler = eigrpe_dispatch_rde;
- imsg_init(&iev_main->ibuf, pipe_parent2eigrpe[1]);
+ imsg_init(&iev_main->ibuf, 3);
iev_main->handler = eigrpe_dispatch_main;
-
- /* setup event handler */
- iev_rde->events = EV_READ;
- event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events,
- iev_rde->handler, iev_rde);
- event_add(&iev_rde->ev, NULL);
-
iev_main->events = EV_READ;
event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
iev_main->handler, iev_main);
@@ -186,11 +163,7 @@ eigrpe(struct eigrpd_conf *xconf, int pipe_parent2eigrpe[2],
if ((pkt_ptr = calloc(1, READ_BUF_SIZE)) == NULL)
fatal("eigrpe");
- /* initialize interfaces */
- TAILQ_FOREACH(iface, &econf->iface_list, entry)
- if_init(xconf, iface);
-
- if (pledge("stdio cpath inet mcast", NULL) == -1)
+ if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
fatal("pledge");
event_dispatch();
@@ -329,6 +302,28 @@ eigrpe_dispatch_main(int fd, short event, void *bula)
if_addr_del(iface, ka);
break;
+ case IMSG_SOCKET_IPC:
+ if (iev_rde) {
+ log_warnx("%s: received unexpected imsg fd "
+ "to rde", __func__);
+ break;
+ }
+ if ((fd = imsg.fd) == -1) {
+ log_warnx("%s: expected to receive imsg fd to "
+ "rde but didn't receive any", __func__);
+ break;
+ }
+
+ iev_rde = malloc(sizeof(struct imsgev));
+ if (iev_rde == NULL)
+ fatal(NULL);
+ imsg_init(&iev_rde->ibuf, fd);
+ iev_rde->handler = eigrpe_dispatch_rde;
+ iev_rde->events = EV_READ;
+ event_set(&iev_rde->ev, iev_rde->ibuf.fd,
+ iev_rde->events, iev_rde->handler, iev_rde);
+ event_add(&iev_rde->ev, NULL);
+ break;
case IMSG_RECONF_CONF:
if ((nconf = malloc(sizeof(struct eigrpd_conf))) ==
NULL)
diff --git a/usr.sbin/eigrpd/eigrpe.h b/usr.sbin/eigrpd/eigrpe.h
index 0048e6c3091..75f2b64ca76 100644
--- a/usr.sbin/eigrpd/eigrpe.h
+++ b/usr.sbin/eigrpd/eigrpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: eigrpe.h,v 1.10 2016/04/15 13:10:56 renato Exp $ */
+/* $OpenBSD: eigrpe.h,v 1.11 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -70,7 +70,7 @@ struct nbr {
#define PREFIX_SIZE6(x) ((x == 128) ? 16 : ((x / 8) + 1))
/* eigrpe.c */
-pid_t eigrpe(struct eigrpd_conf *, int[2], int[2], int[2]);
+pid_t eigrpe(int, int, char *);
void eigrpe_dispatch_main(int, short, void *);
void eigrpe_dispatch_rde(int, short, void *);
int eigrpe_imsg_compose_parent(int, pid_t, void *, uint16_t);
diff --git a/usr.sbin/eigrpd/parse.y b/usr.sbin/eigrpd/parse.y
index 46b90ddbd9d..02e010f9a91 100644
--- a/usr.sbin/eigrpd/parse.y
+++ b/usr.sbin/eigrpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.14 2016/04/15 13:34:08 renato Exp $ */
+/* $OpenBSD: parse.y,v 1.15 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -951,8 +951,7 @@ parse_config(char *filename)
{
struct sym *sym, *next;
- if ((conf = calloc(1, sizeof(struct eigrpd_conf))) == NULL)
- fatal("parse_config");
+ conf = config_new_empty();
conf->rdomain = 0;
conf->fib_priority_internal = RTP_EIGRP;
conf->fib_priority_external = RTP_EIGRP;
@@ -977,9 +976,6 @@ parse_config(char *filename)
}
topfile = file;
- TAILQ_INIT(&conf->iface_list);
- TAILQ_INIT(&conf->instances);
-
yyparse();
errors = file->errors;
popfile();
diff --git a/usr.sbin/eigrpd/rde.c b/usr.sbin/eigrpd/rde.c
index 06e6a0ac1d0..1e302206aa6 100644
--- a/usr.sbin/eigrpd/rde.c
+++ b/usr.sbin/eigrpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.16 2016/05/12 00:15:24 renato Exp $ */
+/* $OpenBSD: rde.c,v 1.17 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -70,26 +70,16 @@ rde_sig_handler(int sig, short event, void *arg)
/* route decision engine */
pid_t
-rde(struct eigrpd_conf *xconf, int pipe_parent2rde[2], int pipe_eigrpe2rde[2],
- int pipe_parent2eigrpe[2])
+rde(int debug, int verbose)
{
struct event ev_sigint, ev_sigterm;
struct timeval now;
struct passwd *pw;
- pid_t pid;
- struct eigrp *eigrp;
- switch (pid = fork()) {
- case -1:
- fatal("cannot fork");
- /* NOTREACHED */
- case 0:
- break;
- default:
- return (pid);
- }
+ rdeconf = config_new_empty();
- rdeconf = xconf;
+ log_init(debug);
+ log_verbose(verbose);
if ((pw = getpwnam(EIGRPD_USER)) == NULL)
fatal("getpwnam");
@@ -107,7 +97,7 @@ rde(struct eigrpd_conf *xconf, int pipe_parent2rde[2], int pipe_eigrpe2rde[2],
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
- if (pledge("stdio", NULL) == -1)
+ if (pledge("stdio recvfd", NULL) == -1)
fatal("pledge");
event_init();
@@ -120,26 +110,11 @@ rde(struct eigrpd_conf *xconf, int pipe_parent2rde[2], int pipe_eigrpe2rde[2],
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
- /* setup pipes */
- close(pipe_eigrpe2rde[0]);
- close(pipe_parent2rde[0]);
- close(pipe_parent2eigrpe[0]);
- close(pipe_parent2eigrpe[1]);
-
- if ((iev_eigrpe = malloc(sizeof(struct imsgev))) == NULL ||
- (iev_main = malloc(sizeof(struct imsgev))) == NULL)
+ /* setup pipe and event handler to the parent process */
+ if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
fatal(NULL);
- imsg_init(&iev_eigrpe->ibuf, pipe_eigrpe2rde[1]);
- iev_eigrpe->handler = rde_dispatch_imsg;
- imsg_init(&iev_main->ibuf, pipe_parent2rde[1]);
+ imsg_init(&iev_main->ibuf, 3);
iev_main->handler = rde_dispatch_parent;
-
- /* setup event handler */
- iev_eigrpe->events = EV_READ;
- event_set(&iev_eigrpe->ev, iev_eigrpe->ibuf.fd, iev_eigrpe->events,
- iev_eigrpe->handler, iev_eigrpe);
- event_add(&iev_eigrpe->ev, NULL);
-
iev_main->events = EV_READ;
event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
iev_main->handler, iev_main);
@@ -148,9 +123,6 @@ rde(struct eigrpd_conf *xconf, int pipe_parent2rde[2], int pipe_eigrpe2rde[2],
gettimeofday(&now, NULL);
global.uptime = now.tv_sec;
- TAILQ_FOREACH(eigrp, &rdeconf->instances, entry)
- rde_instance_init(eigrp);
-
event_dispatch();
rde_shutdown();
@@ -377,6 +349,29 @@ rde_dispatch_parent(int fd, short event, void *bula)
fatalx("IMSG_NETWORK_DEL imsg with wrong len");
rt_redist_set(imsg.data, 1);
break;
+ case IMSG_SOCKET_IPC:
+ if (iev_eigrpe) {
+ log_warnx("%s: received unexpected imsg fd "
+ "to eigrpe", __func__);
+ break;
+ }
+ if ((fd = imsg.fd) == -1) {
+ log_warnx("%s: expected to receive imsg fd to "
+ "eigrpe but didn't receive any", __func__);
+ break;
+ }
+
+ iev_eigrpe = malloc(sizeof(struct imsgev));
+ if (iev_eigrpe == NULL)
+ fatal(NULL);
+ imsg_init(&iev_eigrpe->ibuf, fd);
+ iev_eigrpe->handler = rde_dispatch_imsg;
+ iev_eigrpe->events = EV_READ;
+ event_set(&iev_eigrpe->ev, iev_eigrpe->ibuf.fd,
+ iev_eigrpe->events, iev_eigrpe->handler,
+ iev_eigrpe);
+ event_add(&iev_eigrpe->ev, NULL);
+ break;
case IMSG_RECONF_CONF:
if ((nconf = malloc(sizeof(struct eigrpd_conf))) ==
NULL)
diff --git a/usr.sbin/eigrpd/rde.h b/usr.sbin/eigrpd/rde.h
index e2caa4b72d4..edabb2c3d33 100644
--- a/usr.sbin/eigrpd/rde.h
+++ b/usr.sbin/eigrpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.8 2016/04/15 13:34:08 renato Exp $ */
+/* $OpenBSD: rde.h,v 1.9 2016/06/05 03:36:41 renato Exp $ */
/*
* Copyright (c) 2015 Renato Westphal <renato@openbsd.org>
@@ -122,7 +122,7 @@ enum dual_event {
};
/* rde.c */
-pid_t rde(struct eigrpd_conf *, int [2], int [2], int [2]);
+pid_t rde(int, int);
int rde_imsg_compose_parent(int, pid_t, void *, uint16_t);
int rde_imsg_compose_eigrpe(int, uint32_t, pid_t, void *,
uint16_t);