static int control_fd;
int
-control_init(void)
+control_init(char *path)
{
struct sockaddr_un s_un;
int fd;
memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX;
- strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
+ strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
- if (unlink(ctl_sock_path) == -1)
+ if (unlink(path) == -1)
if (errno != ENOENT) {
- log_warn("%s: unlink %s", __func__, ctl_sock_path);
+ log_warn("%s: unlink %s", __func__, path);
close(fd);
return (-1);
}
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
- log_warn("%s: bind: %s", __func__, ctl_sock_path);
+ log_warn("%s: bind: %s", __func__, path);
close(fd);
umask(old_umask);
return (-1);
}
umask(old_umask);
- if (chmod(ctl_sock_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+ if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
log_warn("%s: chmod", __func__);
close(fd);
- (void)unlink(ctl_sock_path);
+ (void)unlink(path);
return (-1);
}
}
void
-control_cleanup(void)
+control_cleanup(char *path)
{
accept_del(control_fd);
close(control_fd);
- unlink(ctl_sock_path);
+ unlink(path);
}
/* ARGSUSED */
extern struct ctl_conns ctl_conns;
-int control_init(void);
+int control_init(char *);
int control_listen(void);
-void control_cleanup(void);
+void control_cleanup(char *);
int control_imsg_relay(struct imsg *);
#endif /* _CONTROL_H_ */
/* label decision engine */
void
-lde(const char *user, const char *group, u_short instance)
+lde(void)
{
struct thread thread;
- struct timeval now;
-
- ldeconf = config_new_empty();
#ifdef HAVE_SETPROCTITLE
setproctitle("label decision engine");
ldpd_process = PROC_LDE_ENGINE;
log_procname = log_procnames[PROC_LDE_ENGINE];
- /* drop privileges */
- if (user)
- lde_privs.user = user;
- if (group)
- lde_privs.group = group;
- zprivs_init(&lde_privs);
-
-#ifdef HAVE_PLEDGE
- if (pledge("stdio recvfd unix", NULL) == -1)
- fatal("pledge");
-#endif
-
master = thread_master_create();
/* setup signal handler */
fatal(NULL);
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
+ /* create base configuration */
+ ldeconf = config_new_empty();
+
+ /* Fetch next active thread. */
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+}
+
+void
+lde_init(struct ldpd_init *init)
+{
+ /* drop privileges */
+ if (init->user)
+ lde_privs.user = init->user;
+ if (init->group)
+ lde_privs.group = init->group;
+ zprivs_init(&lde_privs);
+
+#ifdef HAVE_PLEDGE
+ if (pledge("stdio recvfd unix", NULL) == -1)
+ fatal("pledge");
+#endif
+
/* start the LIB garbage collector */
lde_gc_start_timer();
- gettimeofday(&now, NULL);
- global.uptime = now.tv_sec;
-
/* Init synchronous zclient and label list */
- zclient_sync_init(instance);
+ zclient_serv_path_set(init->zclient_serv_path);
+ zclient_sync_init(init->instance);
lde_label_list_init();
-
- /* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
}
static void
iev_ldpe->handler_write = ldp_write_handler;
iev_ldpe->ev_write = NULL;
break;
+ case IMSG_INIT:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct ldpd_init))
+ fatalx("INIT imsg with wrong len");
+
+ memcpy(&init, imsg.data, sizeof(init));
+ lde_init(&init);
+ break;
case IMSG_RECONF_CONF:
if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
NULL)
extern struct thread *gc_timer;
/* lde.c */
-void lde(const char *, const char *, u_short instance);
+void lde(void);
+void lde_init(struct ldpd_init *);
int lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
int lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
#include "libfrr.h"
static void ldpd_shutdown(void);
-static pid_t start_child(enum ldpd_process, char *, int, int,
- const char *, const char *, const char *, const char *);
+static pid_t start_child(enum ldpd_process, char *, int, int);
static int main_dispatch_ldpe(struct thread *);
static int main_dispatch_lde(struct thread *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *,
DEFINE_QOBJ_TYPE(ldpd_conf)
struct ldpd_global global;
+struct ldpd_init init;
struct ldpd_conf *ldpd_conf, *vty_conf;
static struct imsgev *iev_ldpe, *iev_ldpe_sync;
int lflag = 0, eflag = 0;
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
- char *ctl_sock_custom_path = NULL;
char *ctl_sock_name;
- const char *user = NULL;
- const char *group = NULL;
- u_short instance = 0;
- const char *instance_char = NULL;
ldpd_process = PROC_MAIN;
log_procname = log_procnames[ldpd_process];
* sensible config
*/
ctl_sock_name = (char *)LDPD_SOCKET;
- ctl_sock_custom_path = optarg;
- strlcpy(ctl_sock_path, ctl_sock_custom_path,
- sizeof(ctl_sock_path));
+ strlcpy(ctl_sock_path, optarg, sizeof(ctl_sock_path));
strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
strlcat(ctl_sock_path, ctl_sock_name,
sizeof(ctl_sock_path));
break;
case 'n':
- instance = atoi(optarg);
- instance_char = optarg;
- if (instance < 1)
+ init.instance = atoi(optarg);
+ if (init.instance < 1)
exit(0);
break;
case 'L':
}
}
- user = ldpd_privs.user;
- group = ldpd_privs.group;
+ strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
+ strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
+ strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
+ strlcpy(init.zclient_serv_path, zclient_serv_path_get(),
+ sizeof(init.zclient_serv_path));
argc -= optind;
argv += optind;
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
if (lflag)
- lde(user, group, instance);
+ lde();
else if (eflag)
- ldpe(user, group, ctl_sock_path);
+ ldpe();
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
fatal("socketpair");
/* start children */
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
- pipe_parent2lde[1], pipe_parent2lde_sync[1],
- user, group, ctl_sock_custom_path, instance_char);
+ pipe_parent2lde[1], pipe_parent2lde_sync[1]);
ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
- pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1],
- user, group, ctl_sock_custom_path, instance_char);
+ pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1]);
/* drop privileges */
zprivs_init(&ldpd_privs);
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
fatal("could not establish imsg links");
+ main_imsg_compose_both(IMSG_INIT, &init, sizeof(init));
main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
sizeof(ldp_debug));
main_imsg_send_config(ldpd_conf);
}
static pid_t
-start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
- const char *user, const char *group, const char *ctl_sock_custom_path,
- const char *instance)
+start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
{
- char *argv[13];
+ char *argv[3];
int argc = 0;
pid_t pid;
argv[argc++] = (char *)"-E";
break;
}
- if (user) {
- argv[argc++] = (char *)"-u";
- argv[argc++] = (char *)user;
- }
- if (group) {
- argv[argc++] = (char *)"-g";
- argv[argc++] = (char *)group;
- }
- if (ctl_sock_custom_path) {
- argv[argc++] = (char *)"--ctl_socket";
- argv[argc++] = (char *)ctl_sock_custom_path;
- }
- /* zclient serv path */
-#ifdef HAVE_TCP_ZEBRA
-#else
- argv[argc++] = (char *)"-z";
- argv[argc++] = (char *)zclient_serv_path_get();
-#endif
- /* instance */
- if (instance) {
- argv[argc++] = (char *)"-n";
- argv[argc++] = (char *)instance;
- }
argv[argc++] = NULL;
execvp(argv0, argv);
IMSG_LOG,
IMSG_ACL_CHECK,
IMSG_GET_LABEL_CHUNK,
- IMSG_RELEASE_LABEL_CHUNK
+ IMSG_RELEASE_LABEL_CHUNK,
+ IMSG_INIT
+};
+
+struct ldpd_init {
+ char user[256];
+ char group[256];
+ char ctl_sock_path[MAXPATHLEN];
+ char zclient_serv_path[MAXPATHLEN];
+ u_short instance;
};
union ldpd_addr {
struct ldpd_global {
int cmd_opts;
int sighup;
- time_t uptime;
struct in_addr rtr_id;
struct ldpd_af_global ipv4;
struct ldpd_af_global ipv6;
extern struct ldpd_conf *ldpd_conf, *vty_conf;
extern struct ldpd_global global;
+extern struct ldpd_init init;
/* parse.y */
struct ldpd_conf *parse_config(char *);
/* label distribution protocol engine */
void
-ldpe(const char *user, const char *group, const char *ctl_path)
+ldpe(void)
{
struct thread thread;
- leconf = config_new_empty();
-
#ifdef HAVE_SETPROCTITLE
setproctitle("ldp engine");
#endif
ldpd_process = PROC_LDP_ENGINE;
log_procname = log_procnames[ldpd_process];
- LIST_INIT(&global.addr_list);
- RB_INIT(&global.adj_tree);
- TAILQ_INIT(&global.pending_conns);
- if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
- fatal("inet_pton");
- if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
- fatal("inet_pton");
-#ifdef __OpenBSD__
- global.pfkeysock = pfkey_init();
-#endif
-
- /* drop privileges */
- if (user)
- ldpe_privs.user = user;
- if (group)
- ldpe_privs.group = group;
- zprivs_init(&ldpe_privs);
-
- strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
- if (control_init() == -1)
- fatalx("control socket setup failed");
-
-#ifdef HAVE_PLEDGE
- if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
- fatal("pledge");
-#endif
-
master = thread_master_create();
- accept_init();
/* setup signal handler */
signal_init(master, array_size(ldpe_signals), ldpe_signals);
fatal(NULL);
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
+ /* create base configuration */
+ leconf = config_new_empty();
+
+ /* Fetch next active thread. */
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+}
+
+void
+ldpe_init(struct ldpd_init *init)
+{
+ /* drop privileges */
+ if (init->user)
+ ldpe_privs.user = init->user;
+ if (init->group)
+ ldpe_privs.group = init->group;
+ zprivs_init(&ldpe_privs);
+
+ /* listen on ldpd control socket */
+ strlcpy(ctl_sock_path, init->ctl_sock_path, sizeof(ctl_sock_path));
+ if (control_init(ctl_sock_path) == -1)
+ fatalx("control socket setup failed");
+ TAILQ_INIT(&ctl_conns);
+ control_listen();
+
+#ifdef HAVE_PLEDGE
+ if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
+ fatal("pledge");
+#endif
+
+ LIST_INIT(&global.addr_list);
+ RB_INIT(&global.adj_tree);
+ TAILQ_INIT(&global.pending_conns);
+ if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
+ fatal("inet_pton");
+ if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
+ fatal("inet_pton");
#ifdef __OpenBSD__
+ global.pfkeysock = pfkey_init();
if (sysdep.no_pfkey == 0)
pfkey_ev = thread_add_read(master, ldpe_dispatch_pfkey,
NULL, global.pfkeysock);
global.ipv6.ldp_edisc_socket = -1;
global.ipv6.ldp_session_socket = -1;
- /* listen on ldpd control socket */
- TAILQ_INIT(&ctl_conns);
- control_listen();
-
if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
fatal(__func__);
- /* Fetch next active thread. */
- while (thread_fetch(master, &thread))
- thread_call(&thread);
+ accept_init();
}
static void
msgbuf_clear(&iev_main_sync->ibuf.w);
close(iev_main_sync->ibuf.fd);
- control_cleanup();
+ control_cleanup(ctl_sock_path);
config_clear(leconf);
#ifdef __OpenBSD__
iev_lde->handler_write = ldp_write_handler;
iev_lde->ev_write = NULL;
break;
+ case IMSG_INIT:
+ if (imsg.hdr.len != IMSG_HEADER_SIZE +
+ sizeof(struct ldpd_init))
+ fatalx("INIT imsg with wrong len");
+
+ memcpy(&init, imsg.data, sizeof(init));
+ ldpe_init(&init);
+ break;
case IMSG_CLOSE_SOCKETS:
af = imsg.hdr.peerid;
uint16_t, struct map *);
/* ldpe.c */
-void ldpe(const char *, const char *, const char *);
+void ldpe(void);
+void ldpe_init(struct ldpd_init *);
int ldpe_imsg_compose_parent(int, pid_t, void *,
uint16_t);
int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,