summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/unix/config.Y16
-rw-r--r--sysdep/unix/io.c2
-rw-r--r--sysdep/unix/main.c99
-rw-r--r--sysdep/unix/unix.h2
4 files changed, 104 insertions, 15 deletions
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index 24d1ae5d..665b0b09 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -21,6 +21,7 @@ CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT, CLI)
CF_KEYWORDS(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS)
+%type <cli> cli_opts
%type <i> log_mask log_mask_list log_cat cfg_timeout
%type <t> cfg_name
%type <tf> timeformat_which
@@ -123,6 +124,21 @@ mrtdump_base:
}
;
+conf: cli ;
+
+cli: CLI text cli_opts {
+ $3->name = $2;
+ cli_config_add_tail(&new_config->cli, $3);
+} ;
+
+cli_opts: ';' {
+ $$ = cfg_alloc(sizeof *$$);
+ *$$ = (typeof (*$$)) {
+ .config = new_config,
+ .mode = 0660,
+ };
+};
+
conf: debug_unix ;
debug_unix:
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 5a0dde8e..ba2e1661 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -2431,7 +2431,7 @@ io_loop(void)
}
void
-test_old_bird(char *path)
+test_old_bird(const char *path)
{
int fd;
struct sockaddr_un sa;
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index c712aee4..17f7edb5 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -29,6 +29,7 @@
#include "lib/socket.h"
#include "lib/event.h"
#include "lib/timer.h"
+#include "lib/tlists.h"
#include "lib/string.h"
#include "nest/route.h"
#include "nest/protocol.h"
@@ -183,6 +184,8 @@ cf_read(byte *dest, uint len, int fd)
return l;
}
+static void cli_preconfig(struct config *c);
+
void
sysdep_preconfig(struct config *c)
{
@@ -197,12 +200,17 @@ sysdep_preconfig(struct config *c)
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_scopes", "ips_", 255);
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff);
#endif
+
+ cli_preconfig(c);
}
+static void cli_commit(struct config *new, struct config *old);
+
int
-sysdep_commit(struct config *new, struct config *old UNUSED)
+sysdep_commit(struct config *new, struct config *old)
{
log_switch(0, &new->logfiles, new->syslog_name);
+ cli_commit(new, old);
return 0;
}
@@ -395,13 +403,29 @@ cmd_reconfig_status(void)
* Command-Line Interface
*/
-static char *path_control_socket = PATH_CONTROL_SOCKET;
+static struct cli_config initial_control_socket_config = {
+ .name = PATH_CONTROL_SOCKET,
+ .mode = 0660,
+};
+#define path_control_socket initial_control_socket_config.name
+
static struct cli_config *main_control_socket_config = NULL;
+
+#define TLIST_PREFIX cli_listener
+#define TLIST_TYPE struct cli_listener
+#define TLIST_ITEM n
+#define TLIST_WANT_ADD_TAIL
+#define TLIST_WANT_WALK
static struct cli_listener {
+ TLIST_DEFAULT_NODE;
sock *s;
struct cli_config *config;
} *main_control_socket = NULL;
+#include "lib/tlists.h"
+
+static TLIST_LIST(cli_listener) cli_listeners;
+
static void
cli_write(cli *c)
{
@@ -523,7 +547,7 @@ cli_connect(sock *s, uint size UNUSED)
}
static struct cli_listener *
-cli_listener(struct cli_config *cf)
+cli_listen(struct cli_config *cf)
{
struct cli_listener *l = mb_allocz(cli_pool, sizeof *l);
l->config = cf;
@@ -557,29 +581,78 @@ cli_listener(struct cli_config *cf)
return NULL;
}
+ cli_listener_add_tail(&cli_listeners, l);
+
return l;
}
static void
+cli_deafen(struct cli_listener *l)
+{
+ rfree(l->s);
+ unlink(l->config->name);
+ cli_listener_rem_node(&cli_listeners, l);
+ mb_free(l);
+}
+
+static void
cli_init_unix(uid_t use_uid, gid_t use_gid)
{
ASSERT_DIE(main_control_socket_config == NULL);
+ cli_init();
- main_control_socket_config = mb_alloc(&root_pool, sizeof *main_control_socket_config);
- *main_control_socket_config = (struct cli_config) {
- .name = path_control_socket,
- .uid = use_uid,
- .gid = use_gid,
- .mode = 0660,
- };
+ main_control_socket_config = &initial_control_socket_config;
+ main_control_socket_config->uid = use_uid;
+ main_control_socket_config->gid = use_gid;
ASSERT_DIE(main_control_socket == NULL);
- cli_init();
- main_control_socket = cli_listener(main_control_socket_config);
+ main_control_socket = cli_listen(main_control_socket_config);
if (!main_control_socket)
die("Won't run without control socket");
}
+static void
+cli_preconfig(struct config *c)
+{
+ struct cli_config *ccf = mb_alloc(cli_pool, sizeof *ccf);
+ memcpy(ccf, main_control_socket_config, sizeof *ccf);
+ ccf->n = (struct cli_config_node) {};
+ ccf->config = c;
+ cli_config_add_tail(&c->cli, ccf);
+}
+
+static void
+cli_commit(struct config *new, struct config *old)
+{
+ if (new->shutdown)
+ {
+ /* Keep the main CLI throughout the shutdown */
+ initial_control_socket_config.config = new;
+ main_control_socket->config = &initial_control_socket_config;
+ }
+
+ WALK_TLIST(cli_config, c, &new->cli)
+ {
+ _Bool seen = 0;
+ WALK_TLIST(cli_listener, l, &cli_listeners)
+ if (l->config->config != new)
+ if (!strcmp(l->config->name, c->name))
+ {
+ ASSERT_DIE(l->config->config == old);
+ l->config = c;
+ seen = 1;
+ break;
+ }
+
+ if (!seen)
+ cli_listen(c);
+ }
+
+ WALK_TLIST_DELSAFE(cli_listener, l, &cli_listeners)
+ if (l->config->config != new)
+ cli_deafen(l);
+}
+
/*
* PID file
@@ -658,7 +731,7 @@ void
sysdep_shutdown_done(void)
{
unlink_pid_file();
- unlink(path_control_socket);
+ cli_deafen(main_control_socket);
log_msg(L_FATAL "Shutdown completed");
exit(0);
}
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index 7c15e30d..33ece06c 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -112,7 +112,7 @@ struct rfile *rf_open(struct pool *, const char *name, const char *mode);
struct rfile *rf_fdopen(pool *p, int fd, const char *mode);
void *rf_file(struct rfile *f);
int rf_fileno(struct rfile *f);
-void test_old_bird(char *path);
+void test_old_bird(const char *path);
ip_addr resolve_hostname(const char *host, int type, const char **err_msg);
/* krt.c bits */