diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/unix/config.Y | 16 | ||||
-rw-r--r-- | sysdep/unix/io.c | 2 | ||||
-rw-r--r-- | sysdep/unix/main.c | 99 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 2 |
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 */ |