mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Additional CLI sockets can be now configured in the config file
If the user has such a need, they may configure additional sockets in the config file. This may work for e.g. some advanced access control.
This commit is contained in:
parent
9639f88bb1
commit
5b53fe36e7
@ -552,6 +552,7 @@ order_shutdown(int gr)
|
|||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
init_list(&c->mpls_domains);
|
init_list(&c->mpls_domains);
|
||||||
init_list(&c->symbols);
|
init_list(&c->symbols);
|
||||||
|
c->cli = (struct cli_config_list) {};
|
||||||
memset(c->def_tables, 0, sizeof(c->def_tables));
|
memset(c->def_tables, 0, sizeof(c->def_tables));
|
||||||
c->shutdown = 1;
|
c->shutdown = 1;
|
||||||
c->gr_down = gr;
|
c->gr_down = gr;
|
||||||
|
@ -100,6 +100,7 @@ CF_DECLS
|
|||||||
mpls_label_stack *mls;
|
mpls_label_stack *mls;
|
||||||
const struct adata *bs;
|
const struct adata *bs;
|
||||||
struct aggr_item_node *ai;
|
struct aggr_item_node *ai;
|
||||||
|
struct cli_config *cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
|
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
|
||||||
|
@ -1219,9 +1219,11 @@ protocol bgp {
|
|||||||
<chapt>Remote control
|
<chapt>Remote control
|
||||||
<label id="remote-control">
|
<label id="remote-control">
|
||||||
|
|
||||||
|
<sect>Overview
|
||||||
|
<label id="remote-control-overview">
|
||||||
|
|
||||||
<p>You can use the command-line client <file>birdc</file> to talk with a running
|
<p>You can use the command-line client <file>birdc</file> to talk with a running
|
||||||
BIRD. Communication is done using a <file/bird.ctl/ UNIX domain socket (unless
|
BIRD. Communication is done using the appropriate UNIX domain socket. The
|
||||||
changed with the <tt/-s/ option given to both the server and the client). The
|
|
||||||
commands can perform simple actions such as enabling/disabling of protocols,
|
commands can perform simple actions such as enabling/disabling of protocols,
|
||||||
telling BIRD to show various information, telling it to show routing table
|
telling BIRD to show various information, telling it to show routing table
|
||||||
filtered by filter, or asking BIRD to reconfigure. Press <tt/?/ at any time to
|
filtered by filter, or asking BIRD to reconfigure. Press <tt/?/ at any time to
|
||||||
@ -1237,10 +1239,27 @@ does not support command line editing and history and has minimal dependencies.
|
|||||||
This is useful for running BIRD in resource constrained environments, where
|
This is useful for running BIRD in resource constrained environments, where
|
||||||
Readline library (required for regular BIRD client) is not available.
|
Readline library (required for regular BIRD client) is not available.
|
||||||
|
|
||||||
<p>Many commands have the <m/name/ of the protocol instance as an argument.
|
<sect>Configuration
|
||||||
This argument can be omitted if there exists only a single instance.
|
<label id="remote-control-configuration">
|
||||||
|
|
||||||
<p>Here is a brief list of supported functions:
|
<p>By default, BIRD opens <file/bird.ctl/ UNIX domain socket and the CLI tool
|
||||||
|
connects to it. If changed on the command line by the <tt/-s/ option,
|
||||||
|
BIRD or the CLI tool connects there instead.
|
||||||
|
|
||||||
|
<p>It's also possible to configure additional remote control sockets in the
|
||||||
|
configuration file by <cf/cli "name";/ and you can open how many
|
||||||
|
sockets you wish. There are no checks whether the user configured the same
|
||||||
|
socket multiple times and BIRD may behave weirdly if this happens. On shutdown,
|
||||||
|
the additional sockets get removed immediately and only the main socket stays
|
||||||
|
until the very end.
|
||||||
|
|
||||||
|
<sect>Usage
|
||||||
|
<label id="remote-control-usage">
|
||||||
|
|
||||||
|
<p>Here is a brief list of supported functions.
|
||||||
|
|
||||||
|
<p>Note: Many commands have the <m/name/ of the protocol instance as an argument.
|
||||||
|
This argument can be omitted if there exists only a single instance.
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
<tag><label id="cli-show-status">show status</tag>
|
<tag><label id="cli-show-status">show status</tag>
|
||||||
|
@ -55,12 +55,16 @@ struct cli_config {
|
|||||||
#define TLIST_ITEM n
|
#define TLIST_ITEM n
|
||||||
#define TLIST_DEFINED_BEFORE
|
#define TLIST_DEFINED_BEFORE
|
||||||
#define TLIST_WANT_ADD_TAIL
|
#define TLIST_WANT_ADD_TAIL
|
||||||
|
#define TLIST_WANT_WALK
|
||||||
TLIST_DEFAULT_NODE;
|
TLIST_DEFAULT_NODE;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct config *config;
|
||||||
uint uid, gid, mode;
|
uint uid, gid, mode;
|
||||||
};
|
};
|
||||||
#include "lib/tlists.h"
|
#include "lib/tlists.h"
|
||||||
|
|
||||||
|
void cli_config_listen(struct cli_config *, const char *);
|
||||||
|
|
||||||
extern pool *cli_pool;
|
extern pool *cli_pool;
|
||||||
extern struct cli *this_cli; /* Used during parsing */
|
extern struct cli *this_cli; /* Used during parsing */
|
||||||
|
|
||||||
|
@ -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(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
|
||||||
CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS)
|
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 <i> log_mask log_mask_list log_cat cfg_timeout
|
||||||
%type <t> cfg_name
|
%type <t> cfg_name
|
||||||
%type <tf> timeformat_which
|
%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 ;
|
conf: debug_unix ;
|
||||||
|
|
||||||
debug_unix:
|
debug_unix:
|
||||||
|
@ -2427,7 +2427,7 @@ io_loop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
test_old_bird(char *path)
|
test_old_bird(const char *path)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "lib/socket.h"
|
#include "lib/socket.h"
|
||||||
#include "lib/event.h"
|
#include "lib/event.h"
|
||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
|
#include "lib/tlists.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
#include "nest/protocol.h"
|
#include "nest/protocol.h"
|
||||||
@ -183,6 +184,8 @@ cf_read(byte *dest, uint len, int fd)
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cli_preconfig(struct config *c);
|
||||||
|
|
||||||
void
|
void
|
||||||
sysdep_preconfig(struct config *c)
|
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_scopes", "ips_", 255);
|
||||||
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff);
|
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cli_preconfig(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cli_commit(struct config *new, struct config *old);
|
||||||
|
|
||||||
int
|
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);
|
log_switch(0, &new->logfiles, new->syslog_name);
|
||||||
|
cli_commit(new, old);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,13 +403,29 @@ cmd_reconfig_status(void)
|
|||||||
* Command-Line Interface
|
* 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;
|
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 {
|
static struct cli_listener {
|
||||||
|
TLIST_DEFAULT_NODE;
|
||||||
sock *s;
|
sock *s;
|
||||||
struct cli_config *config;
|
struct cli_config *config;
|
||||||
} *main_control_socket = NULL;
|
} *main_control_socket = NULL;
|
||||||
|
|
||||||
|
#include "lib/tlists.h"
|
||||||
|
|
||||||
|
static TLIST_LIST(cli_listener) cli_listeners;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cli_write(cli *c)
|
cli_write(cli *c)
|
||||||
{
|
{
|
||||||
@ -523,7 +547,7 @@ cli_connect(sock *s, uint size UNUSED)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct cli_listener *
|
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);
|
struct cli_listener *l = mb_allocz(cli_pool, sizeof *l);
|
||||||
l->config = cf;
|
l->config = cf;
|
||||||
@ -557,29 +581,78 @@ cli_listener(struct cli_config *cf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli_listener_add_tail(&cli_listeners, l);
|
||||||
|
|
||||||
return 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
|
static void
|
||||||
cli_init_unix(uid_t use_uid, gid_t use_gid)
|
cli_init_unix(uid_t use_uid, gid_t use_gid)
|
||||||
{
|
{
|
||||||
ASSERT_DIE(main_control_socket_config == NULL);
|
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 = &initial_control_socket_config;
|
||||||
*main_control_socket_config = (struct cli_config) {
|
main_control_socket_config->uid = use_uid;
|
||||||
.name = path_control_socket,
|
main_control_socket_config->gid = use_gid;
|
||||||
.uid = use_uid,
|
|
||||||
.gid = use_gid,
|
|
||||||
.mode = 0660,
|
|
||||||
};
|
|
||||||
|
|
||||||
ASSERT_DIE(main_control_socket == NULL);
|
ASSERT_DIE(main_control_socket == NULL);
|
||||||
cli_init();
|
main_control_socket = cli_listen(main_control_socket_config);
|
||||||
main_control_socket = cli_listener(main_control_socket_config);
|
|
||||||
if (!main_control_socket)
|
if (!main_control_socket)
|
||||||
die("Won't run without 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
|
* PID file
|
||||||
@ -658,7 +731,7 @@ void
|
|||||||
sysdep_shutdown_done(void)
|
sysdep_shutdown_done(void)
|
||||||
{
|
{
|
||||||
unlink_pid_file();
|
unlink_pid_file();
|
||||||
unlink(path_control_socket);
|
cli_deafen(main_control_socket);
|
||||||
log_msg(L_FATAL "Shutdown completed");
|
log_msg(L_FATAL "Shutdown completed");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
struct rfile *rf_fdopen(pool *p, int fd, const char *mode);
|
||||||
void *rf_file(struct rfile *f);
|
void *rf_file(struct rfile *f);
|
||||||
int rf_fileno(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);
|
ip_addr resolve_hostname(const char *host, int type, const char **err_msg);
|
||||||
|
|
||||||
/* krt.c bits */
|
/* krt.c bits */
|
||||||
|
Loading…
Reference in New Issue
Block a user