summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2006-01-24 10:03:45 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2006-01-24 10:03:45 +0000
commit6bf83ade2a4168a5228b22830193d9ed67ef7f5d (patch)
treeb5cdecba6b979689e359ea17392418291e51908e /usr.sbin/bgpd
parent5cd3175274d02b20fea399bceaa0d520d67688b7 (diff)
introduce a second control socket, which is restricted to certain messages,
nameley the show ones. needed for looking glass style applications, monitoring etc. claudio ok
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.c12
-rw-r--r--usr.sbin/bgpd/bgpd.h9
-rw-r--r--usr.sbin/bgpd/config.c3
-rw-r--r--usr.sbin/bgpd/control.c71
-rw-r--r--usr.sbin/bgpd/log.h5
-rw-r--r--usr.sbin/bgpd/session.c27
-rw-r--r--usr.sbin/bgpd/session.h10
7 files changed, 95 insertions, 42 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index a3a2235fc19..ec73429e23a 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.129 2006/01/03 16:49:23 claudio Exp $ */
+/* $OpenBSD: bgpd.c,v 1.130 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -86,7 +86,7 @@ usage(void)
extern char *__progname;
fprintf(stderr, "usage: %s [-dnv] ", __progname);
- fprintf(stderr, "[-D macro=value] [-f file]\n");
+ fprintf(stderr, "[-D macro=value] [-f file] [-r path]\n");
exit(1);
}
@@ -131,7 +131,7 @@ main(int argc, char *argv[])
TAILQ_INIT(rules_l);
peer_l = NULL;
- while ((ch = getopt(argc, argv, "dD:f:nv")) != -1) {
+ while ((ch = getopt(argc, argv, "dD:f:nr:v")) != -1) {
switch (ch) {
case 'd':
debug = 1;
@@ -152,6 +152,9 @@ main(int argc, char *argv[])
conf.opts |= BGPD_OPT_VERBOSE2;
conf.opts |= BGPD_OPT_VERBOSE;
break;
+ case 'r':
+ conf.rcsock = optarg;
+ break;
default:
usage();
/* NOTREACHED */
@@ -352,7 +355,8 @@ main(int argc, char *argv[])
}
free(rules_l);
- control_cleanup();
+ control_cleanup(SOCKET_NAME);
+ control_cleanup(conf.rcsock);
kr_shutdown();
pftable_clear_all();
free(conf.listen_addrs);
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 9337fd548be..af774aa802e 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.187 2006/01/20 16:40:17 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.188 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -142,6 +142,7 @@ struct bgpd_config {
struct filter_set_head staticset;
struct filter_set_head staticset6;
struct listen_addrs *listen_addrs;
+ char *rcsock;
int opts;
int flags;
int log;
@@ -334,7 +335,8 @@ struct imsg {
enum ctl_results {
CTL_RES_OK,
- CTL_RES_NOSUCHPEER
+ CTL_RES_NOSUCHPEER,
+ CTL_RES_DENIED
};
/* needed for session.h parse prototype */
@@ -730,8 +732,7 @@ void inet6applymask(struct in6_addr *, const struct in6_addr *,
int);
/* control.c */
-int control_init(void);
-void control_cleanup(void);
+void control_cleanup(const char *);
int control_imsg_relay(struct imsg *);
/* pftable.c */
diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c
index fbee85d0421..d65a3af6c51 100644
--- a/usr.sbin/bgpd/config.c
+++ b/usr.sbin/bgpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.46 2005/07/14 09:24:38 dlg Exp $ */
+/* $OpenBSD: config.c,v 1.47 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -47,6 +47,7 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
/* preserve cmd line opts */
conf->opts = xconf->opts;
+ conf->rcsock = xconf->rcsock;
if (!conf->as) {
log_warnx("configuration error: AS not given");
diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c
index b2cb2418c67..6c498c1c642 100644
--- a/usr.sbin/bgpd/control.c
+++ b/usr.sbin/bgpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.46 2006/01/03 22:49:17 claudio Exp $ */
+/* $OpenBSD: control.c,v 1.47 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -32,6 +32,7 @@
struct {
int fd;
+ int restricted_fd;
} control_state;
struct ctl_conn *control_connbyfd(int);
@@ -40,11 +41,11 @@ int control_close(int);
void control_result(struct ctl_conn *, u_int);
int
-control_init(void)
+control_init(int restricted, char *path)
{
struct sockaddr_un sun;
int fd;
- mode_t old_umask;
+ mode_t old_umask, mode;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
log_warn("control_init: socket");
@@ -53,18 +54,25 @@ control_init(void)
bzero(&sun, sizeof(sun));
sun.sun_family = AF_UNIX;
- strlcpy(sun.sun_path, SOCKET_NAME, sizeof(sun.sun_path));
+ strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
- if (unlink(SOCKET_NAME) == -1)
+ if (unlink(path) == -1)
if (errno != ENOENT) {
- log_warn("unlink %s", SOCKET_NAME);
+ log_warn("unlink %s", path);
close(fd);
return (-1);
}
- old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
+ if (restricted) {
+ old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+ mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ } else {
+ old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
+ mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
+ }
+
if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
- log_warn("control_init: bind: %s", SOCKET_NAME);
+ log_warn("control_init: bind: %s", path);
close(fd);
umask(old_umask);
return (-1);
@@ -72,44 +80,44 @@ control_init(void)
umask(old_umask);
- if (chmod(SOCKET_NAME, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
- log_warn("control_init chmod");
+ if (chmod(path, mode) == -1) {
+ log_warn("control_init: chmod: %s", path);
close(fd);
- (void)unlink(SOCKET_NAME);
+ unlink(path);
return (-1);
}
session_socket_blockmode(fd, BM_NONBLOCK);
- control_state.fd = fd;
return (fd);
}
int
-control_listen(void)
+control_listen(int fd)
{
- if (listen(control_state.fd, CONTROL_BACKLOG) == -1) {
+ if (fd != -1 && listen(fd, CONTROL_BACKLOG) == -1) {
log_warn("control_listen: listen");
return (-1);
}
- return (control_state.fd);
+ return (0);
}
void
-control_shutdown(void)
+control_shutdown(int fd)
{
- close(control_state.fd);
+ close(fd);
}
void
-control_cleanup(void)
+control_cleanup(const char *path)
{
- unlink(SOCKET_NAME);
+ if (path)
+ unlink(path);
}
int
-control_accept(int listenfd)
+control_accept(int listenfd, int restricted)
{
int connfd;
socklen_t len;
@@ -132,6 +140,7 @@ control_accept(int listenfd)
}
imsg_init(&ctl_conn->ibuf, connfd);
+ ctl_conn->restricted = restricted;
TAILQ_INSERT_TAIL(&ctl_conns, ctl_conn, entry);
@@ -218,7 +227,29 @@ control_dispatch_msg(struct pollfd *pfd, u_int *ctl_cnt)
if (n == 0)
break;
+ if (c->restricted) {
+ switch (imsg.hdr.type) {
+ case IMSG_CTL_SHOW_NEIGHBOR:
+ case IMSG_CTL_SHOW_NEXTHOP:
+ case IMSG_CTL_SHOW_INTERFACE:
+ case IMSG_CTL_SHOW_RIB:
+ case IMSG_CTL_SHOW_RIB_AS:
+ case IMSG_CTL_SHOW_RIB_PREFIX:
+ case IMSG_CTL_SHOW_RIB_MEM:
+ case IMSG_CTL_SHOW_NETWORK:
+ break;
+ default:
+ /* clear imsg type to prevent processing */
+ imsg.hdr.type = IMSG_NONE;
+ control_result(c, CTL_RES_DENIED);
+ break;
+ }
+ }
+
switch (imsg.hdr.type) {
+ case IMSG_NONE:
+ /* message was filtered out, nothing to do */
+ break;
case IMSG_CTL_SHOW_NEIGHBOR:
c->ibuf.pid = imsg.hdr.pid;
if (imsg.hdr.len == IMSG_HEADER_SIZE +
diff --git a/usr.sbin/bgpd/log.h b/usr.sbin/bgpd/log.h
index a8387e00957..61ad86f3c30 100644
--- a/usr.sbin/bgpd/log.h
+++ b/usr.sbin/bgpd/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.5 2005/10/19 12:32:16 henning Exp $ */
+/* $OpenBSD: log.h,v 1.6 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -106,5 +106,6 @@ static const char * const procnames[] = {
static const char * const ctl_res_strerror[] = {
"no error",
- "no such neighbor"
+ "no such neighbor",
+ "permission denied"
};
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 15e8622e408..ca5a675c196 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.241 2006/01/03 22:49:17 claudio Exp $ */
+/* $OpenBSD: session.c,v 1.242 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -46,7 +46,8 @@
#define PFD_PIPE_MAIN 0
#define PFD_PIPE_ROUTE 1
#define PFD_SOCK_CTL 2
-#define PFD_LISTENERS_START 3
+#define PFD_SOCK_RCTL 3
+#define PFD_LISTENERS_START 4
void session_sighdlr(int);
int setup_listeners(u_int *);
@@ -91,7 +92,7 @@ struct bgpd_sysdep sysdep;
struct peer *npeers;
volatile sig_atomic_t session_quit = 0;
int pending_reconf = 0;
-int csock = -1;
+int csock = -1, rcsock = -1;
u_int peer_cnt;
struct imsgbuf *ibuf_rde;
struct imsgbuf *ibuf_main;
@@ -193,7 +194,10 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
}
/* control socket is outside chroot */
- if ((csock = control_init()) == -1)
+ if ((csock = control_init(0, SOCKET_NAME)) == -1)
+ fatalx("control socket setup failed");
+ if (conf->rcsock != NULL &&
+ (rcsock = control_init(1, conf->rcsock)) == -1)
fatalx("control socket setup failed");
if ((pw = getpwnam(BGPD_USER)) == NULL)
@@ -233,7 +237,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
imsg_init(ibuf_rde, pipe_s2r[0]);
imsg_init(ibuf_main, pipe_m2s[1]);
TAILQ_INIT(&ctl_conns);
- csock = control_listen();
+ control_listen(csock);
+ control_listen(rcsock);
LIST_INIT(&mrthead);
peer_cnt = 0;
ctl_cnt = 0;
@@ -351,6 +356,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
pfd[PFD_PIPE_ROUTE].events |= POLLOUT;
pfd[PFD_SOCK_CTL].fd = csock;
pfd[PFD_SOCK_CTL].events = POLLIN;
+ pfd[PFD_SOCK_RCTL].fd = rcsock;
+ pfd[PFD_SOCK_RCTL].events = POLLIN;
nextaction = time(NULL) + 240; /* loop every 240s at least */
i = PFD_LISTENERS_START;
@@ -463,7 +470,12 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
if (nfds > 0 && pfd[PFD_SOCK_CTL].revents & POLLIN) {
nfds--;
- ctl_cnt += control_accept(csock);
+ ctl_cnt += control_accept(csock, 0);
+ }
+
+ if (nfds > 0 && pfd[PFD_SOCK_RCTL].revents & POLLIN) {
+ nfds--;
+ ctl_cnt += control_accept(rcsock, 1);
}
for (j = PFD_LISTENERS_START; nfds > 0 && j < idx_listeners;
@@ -516,7 +528,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
msgbuf_clear(&ibuf_main->w);
free(ibuf_main);
- control_shutdown();
+ control_shutdown(csock);
+ control_shutdown(rcsock);
log_info("session engine exiting");
_exit(0);
}
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index a310266573a..0322a0ffcb4 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.80 2006/01/03 22:19:59 claudio Exp $ */
+/* $OpenBSD: session.h,v 1.81 2006/01/24 10:03:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -128,6 +128,7 @@ struct bgpd_sysdep {
struct ctl_conn {
TAILQ_ENTRY(ctl_conn) entry;
struct imsgbuf ibuf;
+ int restricted;
};
TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns;
@@ -214,10 +215,11 @@ pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *,
struct filter_head *, struct mrt_head *, int[2], int[2], int[2]);
/* control.c */
-int control_listen(void);
-void control_shutdown(void);
+int control_init(int, char *);
+int control_listen(int);
+void control_shutdown(int);
int control_dispatch_msg(struct pollfd *, u_int *);
-int control_accept(int);
+int control_accept(int, int);
/* pfkey.c */
int pfkey_establish(struct peer *);