diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-01 23:46:48 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-01 23:46:48 +0000 |
commit | 4e446d5117aca066229a6eea302910120954f524 (patch) | |
tree | 4d69a449c6974ead1261a8a0dd5f6016b7252b2b /usr.sbin | |
parent | e739f0ace9d26fdcc465c4a0677813ff7e940037 (diff) |
listen on a AF_LOCAL socket for imsgs too.
only implemented type yet is IMSG_CTL_SHOW_NEIGHBOR which sends back
the struct peer for all neighbors.
will be used by bgpdctl
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/Makefile | 9 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 9 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 16 | ||||
-rw-r--r-- | usr.sbin/bgpd/control.c | 193 | ||||
-rw-r--r-- | usr.sbin/bgpd/imsg.c | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 44 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 18 |
7 files changed, 270 insertions, 23 deletions
diff --git a/usr.sbin/bgpd/Makefile b/usr.sbin/bgpd/Makefile index 90523deb1e3..420ab7c4879 100644 --- a/usr.sbin/bgpd/Makefile +++ b/usr.sbin/bgpd/Makefile @@ -1,8 +1,11 @@ -# $OpenBSD: Makefile,v 1.7 2003/12/23 17:06:32 henning Exp $ +# $OpenBSD: Makefile,v 1.8 2004/01/01 23:46:47 henning Exp $ + +.PATH: ${.CURDIR}/.. PROG= bgpd SRCS= bgpd.c buffer.c session.c log.c parse.y config.c imsg.c \ - rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c + rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c \ + control.c CFLAGS+= -Wall CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes CLFAGS+= -Wmissing-declarations -Wredundant-decls @@ -11,6 +14,4 @@ CFLAGS+= -Wsign-compare YFLAGS= MAN= bgpd.8 bgpd.conf.5 -CFLAGS+= -Wall - .include <bsd.prog.mk> diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index 370d8948948..916db012358 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.48 2004/01/01 23:09:08 henning Exp $ */ +/* $OpenBSD: bgpd.c,v 1.49 2004/01/01 23:46:47 henning Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -95,7 +95,7 @@ main(int argc, char *argv[]) pid_t io_pid = 0, rde_pid = 0; char *conffile; int debug = 0; - int ch, i, j, n, nfds; + int ch, i, j, n, nfds, csock; int pipe_m2s[2]; int pipe_m2r[2]; int pipe_s2r[2]; @@ -171,6 +171,9 @@ main(int argc, char *argv[]) fcntl(pipe_s2r[1], F_SETFL, O_NONBLOCK) == -1) fatal("fcntl"); + if ((csock = control_init()) == -1) + fatalx("control socket setup failed"); + /* fork children */ rde_pid = rde_main(&conf, pipe_m2r, pipe_s2r); io_pid = session_main(&conf, pipe_m2s, pipe_s2r); @@ -188,6 +191,7 @@ main(int argc, char *argv[]) close(pipe_m2r[1]); close(pipe_s2r[0]); close(pipe_s2r[1]); + close(csock); imsg_init(&ibuf_se, pipe_m2s[0]); imsg_init(&ibuf_rde, pipe_m2r[0]); @@ -289,6 +293,7 @@ main(int argc, char *argv[]) i = waitpid(-1, NULL, WNOHANG); } while (i > 0 || (i == -1 && errno == EINTR)); + control_cleanup(); kroute_shutdown(); logit(LOG_CRIT, "Terminating"); diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 8e766659d9e..0c6f5470fc9 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.45 2004/01/01 23:09:08 henning Exp $ */ +/* $OpenBSD: bgpd.h,v 1.46 2004/01/01 23:46:47 henning Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -23,6 +23,7 @@ #include <netinet/in.h> #include <arpa/inet.h> +#include <poll.h> #include <stdarg.h> #include <syslog.h> @@ -85,6 +86,11 @@ enum reconf_action { RECONF_DELETE }; +enum blockmodes { + BM_NORMAL, + BM_NONBLOCK +}; + struct buf { TAILQ_ENTRY(buf) entries; u_char *buf; @@ -209,7 +215,8 @@ enum imsg_type { IMSG_KROUTE_DELETE, IMSG_NEXTHOP_ADD, IMSG_NEXTHOP_REMOVE, - IMSG_NEXTHOP_UPDATE + IMSG_NEXTHOP_UPDATE, + IMSG_CTL_SHOW_NEIGHBOR }; struct imsg_hdr { @@ -256,6 +263,7 @@ struct kroute_nexthop { void send_nexthop_update(struct kroute_nexthop *); /* session.c */ +void session_socket_blockmode(int, enum blockmodes); int session_main(struct bgpd_config *, int[2], int[2]); /* buffer.c */ @@ -316,4 +324,8 @@ int kroute_dispatch_msg(void); int kroute_nexthop_add(in_addr_t); void kroute_nexthop_delete(in_addr_t); +/* control.c */ +int control_init(void); +void control_cleanup(void); + #endif /* __BGPD_H__ */ diff --git a/usr.sbin/bgpd/control.c b/usr.sbin/bgpd/control.c new file mode 100644 index 00000000000..75153ad677a --- /dev/null +++ b/usr.sbin/bgpd/control.c @@ -0,0 +1,193 @@ +/* $OpenBSD: control.c,v 1.1 2004/01/01 23:46:47 henning Exp $ */ + +/* + * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "bgpd.h" +#include "bgpdctl.h" +#include "session.h" + +#define CONTROL_BACKLOG 5 + +struct { + int fd; +} control_state; + +struct ctl_conn *control_connbyfd(int); + +int +control_init(void) +{ + struct sockaddr_un sun; + int fd; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + log_err("control_init: socket"); + return (-1); + } + + bzero(&sun, sizeof(sun)); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, SOCKET_NAME, sizeof(sun.sun_path)); + if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { + log_err("control_init: bind: %s", SOCKET_NAME); + return (-1); + } + + control_state.fd = fd; + + return (fd); +} + +int +control_listen(void) +{ + if (listen(control_state.fd, CONTROL_BACKLOG) == -1) { + log_err("control_listen: listen"); + return (-1); + } + + return (control_state.fd); +} + +void +control_shutdown(void) +{ + close(control_state.fd); +} + +void +control_cleanup(void) +{ + unlink(SOCKET_NAME); +} + +void +control_accept(int listenfd) +{ + int connfd; + socklen_t len; + struct sockaddr_un sun; + uid_t uid; + gid_t gid; + struct ctl_conn *ctl_conn; + + len = sizeof(sun); + if ((connfd = accept(listenfd, + (struct sockaddr *)&sun, &len)) == -1) { + if (errno == EWOULDBLOCK || errno == EINTR) + return; + else + log_err("session_control_accept"); + } + + if (getpeereid(connfd, &uid, &gid) == -1) { + log_err("session_control_accept"); + return; + } + + if (uid) { + log_err("Connection to control socket with uid %ld", uid); + return; + } + + if ((ctl_conn = malloc(sizeof(struct ctl_conn))) == NULL) { + log_err("session_control_accept"); + return; + } + + imsg_init(&ctl_conn->ibuf, connfd); + + TAILQ_INSERT_TAIL(&ctl_conns, ctl_conn, entries); +} + +struct ctl_conn * +control_connbyfd(int fd) +{ + struct ctl_conn *c; + + for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->ibuf.sock != fd; + c = TAILQ_NEXT(c, entries)) + ; /* nothing */ + + return (c); +} + +void +control_close(int fd) +{ + struct ctl_conn *c; + + if ((c = control_connbyfd(fd)) == NULL) { + log_err("control_close: fd %d: not found", fd); + return; + } + + TAILQ_REMOVE(&ctl_conns, c, entries); + + close(c->ibuf.sock); + free(c); +} + +int +control_dispatch_msg(struct pollfd *pfd, int i) +{ + struct imsg imsg; + struct ctl_conn *c; + int n; + struct peer *p; + + if ((c = control_connbyfd(pfd->fd)) == NULL) { + log_err("control_dispatch_msg: fd %d: not found", pfd->fd); + return (0); + } + + if (imsg_read(&c->ibuf) == -1) { + control_close(pfd->fd); + return (1); + } + + for (;;) { + if ((n = imsg_get(&c->ibuf, &imsg)) == -1) { + control_close(pfd->fd); + return (1); + } + + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_CTL_SHOW_NEIGHBOR: + for (p = conf->peers; p != NULL; p = p->next) + imsg_compose(&c->ibuf, IMSG_CTL_SHOW_NEIGHBOR, + 0, p, sizeof(struct peer)); + break; + default: + break; + } + imsg_free(&imsg); + } + + return (0); +} diff --git a/usr.sbin/bgpd/imsg.c b/usr.sbin/bgpd/imsg.c index f59a35eeda7..1d2a8d4abab 100644 --- a/usr.sbin/bgpd/imsg.c +++ b/usr.sbin/bgpd/imsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.16 2004/01/01 23:40:25 henning Exp $ */ +/* $OpenBSD: imsg.c,v 1.17 2004/01/01 23:46:47 henning Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -63,7 +63,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) ssize_t datalen = 0; size_t av, left; - av = ibuf->r.wpos; + av = ibuf->r.wpos; if (IMSG_HEADER_SIZE > av) return (0); diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 1bc5f7b08a8..6efc3ad2643 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.53 2004/01/01 23:09:09 henning Exp $ */ +/* $OpenBSD: session.c,v 1.54 2004/01/01 23:46:47 henning Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -22,6 +22,7 @@ #include <sys/mman.h> #include <sys/socket.h> +#include <sys/un.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -45,12 +46,8 @@ #define PFD_LISTEN 0 #define PFD_PIPE_MAIN 1 #define PFD_PIPE_ROUTE 2 -#define PFD_PEERS_START 3 - -enum blockmodes { - BM_NORMAL, - BM_NONBLOCK -}; +#define PFD_SOCK_CTL 3 +#define PFD_PEERS_START 4 void session_sighdlr(int); int setup_listener(void); @@ -64,7 +61,6 @@ void session_close_connection(struct peer *); void session_terminate(void); void change_state(struct peer *, enum session_state, enum session_events); int session_setup_socket(struct peer *); -void session_socket_blockmode(int, enum blockmodes); void session_accept(int); int session_connect(struct peer *); void session_open(struct peer *); @@ -84,10 +80,11 @@ void session_down(struct peer *); struct peer *getpeerbyip(in_addr_t); -struct bgpd_config *conf = NULL, *nconf = NULL; +struct bgpd_config *nconf = NULL; volatile sig_atomic_t session_quit = 0; int pending_reconf = 0; int sock = -1; +int csock = -1; struct imsgbuf ibuf_rde; struct imsgbuf ibuf_main; @@ -132,12 +129,13 @@ setup_listener(void) int session_main(struct bgpd_config *config, int pipe_m2s[2], int pipe_s2r[2]) { - int nfds, i, j, timeout; + int nfds, i, j, timeout, npeers; pid_t pid; time_t nextaction; struct passwd *pw; struct peer *p, *peers[OPEN_MAX], *last, *next; struct pollfd pfd[OPEN_MAX]; + struct ctl_conn *ctl_conn; conf = config; @@ -177,6 +175,8 @@ session_main(struct bgpd_config *config, int pipe_m2s[2], int pipe_s2r[2]) init_conf(conf); imsg_init(&ibuf_rde, pipe_s2r[0]); imsg_init(&ibuf_main, pipe_m2s[1]); + TAILQ_INIT(&ctl_conns); + csock = control_listen(); init_peers(); while (session_quit == 0) { @@ -189,6 +189,8 @@ session_main(struct bgpd_config *config, int pipe_m2s[2], int pipe_s2r[2]) pfd[PFD_PIPE_ROUTE].events = POLLIN; if (ibuf_rde.w.queued > 0) pfd[PFD_PIPE_ROUTE].events |= POLLOUT; + pfd[PFD_SOCK_CTL].fd = csock; + pfd[PFD_SOCK_CTL].events = POLLIN; nextaction = time(NULL) + 240; /* loop every 240s at least */ i = PFD_PEERS_START; @@ -256,6 +258,16 @@ session_main(struct bgpd_config *config, int pipe_m2s[2], int pipe_s2r[2]) } } + npeers = i; + + TAILQ_FOREACH(ctl_conn, &ctl_conns, entries) { + pfd[i].fd = ctl_conn->ibuf.sock; + pfd[i].events = POLLIN; + if (ctl_conn->ibuf.w.queued > 0) + pfd[i].events |= POLLOUT; + i++; + } + timeout = nextaction - time(NULL); if (timeout < 0) timeout = 0; @@ -282,11 +294,19 @@ session_main(struct bgpd_config *config, int pipe_m2s[2], int pipe_s2r[2]) session_dispatch_imsg(&ibuf_rde, PFD_PIPE_ROUTE); } - for (j = PFD_PEERS_START; nfds > 0 && j < i; j++) { - nfds -= session_dispatch_msg(&pfd[j], peers[j]); + if (nfds > 0 && pfd[PFD_SOCK_CTL].revents & POLLIN) { + nfds--; + control_accept(csock); } + + for (j = PFD_PEERS_START; nfds > 0 && j < npeers; j++) + nfds -= session_dispatch_msg(&pfd[j], peers[j]); + + for (; nfds > 0 && j < i; j++) + nfds -= control_dispatch_msg(&pfd[j], j); } + control_shutdown(); logit(LOG_INFO, "session engine exiting"); _exit(0); } diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index fb25cf017de..ef99c5a85c1 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.2 2003/12/19 21:07:05 henning Exp $ */ +/* $OpenBSD: session.h,v 1.3 2004/01/01 23:46:47 henning Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -75,3 +75,19 @@ struct msg_open { u_int32_t bgpid; u_int8_t optparamlen; }; + +struct ctl_conn { + TAILQ_ENTRY(ctl_conn) entries; + struct imsgbuf ibuf; +}; + +TAILQ_HEAD(ctl_conns, ctl_conn) ctl_conns; + +struct bgpd_config *conf; + +/* control.c */ +int control_listen(void); +void control_shutdown(void); +int control_dispatch_msg(struct pollfd *, int); +void control_accept(int); +void control_close(int); |