diff options
author | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2009-06-05 19:34:00 +0000 |
---|---|---|
committer | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2009-06-05 19:34:00 +0000 |
commit | 1602fb21c249be1b31193fdce7680df0b641b4a8 (patch) | |
tree | 4dbe76394c9a5b14ff01caa07a6bfc979407a243 /usr.sbin/ospfd | |
parent | afb1c16a00506939d346089ba9c0e151425809da (diff) |
make ospfd's imsg lib ready as well.
ok claudio@
Diffstat (limited to 'usr.sbin/ospfd')
-rw-r--r-- | usr.sbin/ospfd/auth.c | 4 | ||||
-rw-r--r-- | usr.sbin/ospfd/buffer.c | 41 | ||||
-rw-r--r-- | usr.sbin/ospfd/control.c | 10 | ||||
-rw-r--r-- | usr.sbin/ospfd/imsg.c | 141 | ||||
-rw-r--r-- | usr.sbin/ospfd/imsg.h | 108 | ||||
-rw-r--r-- | usr.sbin/ospfd/lsreq.c | 5 | ||||
-rw-r--r-- | usr.sbin/ospfd/lsupdate.c | 6 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.c | 22 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfd.h | 81 | ||||
-rw-r--r-- | usr.sbin/ospfd/ospfe.c | 24 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde.c | 75 |
11 files changed, 340 insertions, 177 deletions
diff --git a/usr.sbin/ospfd/auth.c b/usr.sbin/ospfd/auth.c index 4e92a50b029..f35701d3b40 100644 --- a/usr.sbin/ospfd/auth.c +++ b/usr.sbin/ospfd/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.15 2009/03/04 12:51:01 claudio Exp $ */ +/* $OpenBSD: auth.c,v 1.16 2009/06/05 19:33:58 pyr Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -264,7 +264,7 @@ md_list_send(struct auth_md_head *head, struct imsgbuf *to) struct auth_md *m; TAILQ_FOREACH(m, head, entry) - if (imsg_compose(to, IMSG_RECONF_AUTHMD, 0, 0, m, + if (imsg_compose_event(to, IMSG_RECONF_AUTHMD, 0, 0, -1, m, sizeof(*m)) == -1) return (-1); diff --git a/usr.sbin/ospfd/buffer.c b/usr.sbin/ospfd/buffer.c index ab6bad9169a..a03a2470afa 100644 --- a/usr.sbin/ospfd/buffer.c +++ b/usr.sbin/ospfd/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.12 2009/06/05 01:19:09 pyr Exp $ */ +/* $OpenBSD: buffer.c,v 1.13 2009/06/05 19:33:58 pyr Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -16,17 +16,17 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/socket.h> #include <sys/uio.h> #include <errno.h> -#include <limits.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "ospfd.h" +#include "imsg.h" int buf_realloc(struct buf *, size_t); void buf_enqueue(struct msgbuf *, struct buf *); @@ -44,6 +44,7 @@ buf_open(size_t len) return (NULL); } buf->size = buf->max = len; + buf->fd = -1; return (buf); } @@ -171,6 +172,11 @@ msgbuf_write(struct msgbuf *msgbuf) unsigned int i = 0; ssize_t n; struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; bzero(&iov, sizeof(iov)); bzero(&msg, sizeof(msg)); @@ -180,11 +186,23 @@ msgbuf_write(struct msgbuf *msgbuf) iov[i].iov_base = buf->buf + buf->rpos; iov[i].iov_len = buf->wpos - buf->rpos; i++; + if (buf->fd != -1) + break; } msg.msg_iov = iov; msg.msg_iovlen = i; + if (buf != NULL && buf->fd != -1) { + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = buf->fd; + } + if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { if (errno == EAGAIN || errno == ENOBUFS || errno == EINTR) /* try later */ @@ -198,6 +216,15 @@ msgbuf_write(struct msgbuf *msgbuf) return (-2); } + /* + * assumption: fd got sent if sendmsg sent anything + * this works because fds are passed one at a time + */ + if (buf != NULL && buf->fd != -1) { + close(buf->fd); + buf->fd = -1; + } + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; buf = next) { next = TAILQ_NEXT(buf, entry); @@ -224,6 +251,10 @@ void buf_dequeue(struct msgbuf *msgbuf, struct buf *buf) { TAILQ_REMOVE(&msgbuf->bufs, buf, entry); + + if (buf->fd != -1) + close(buf->fd); + msgbuf->queued--; buf_free(buf); } diff --git a/usr.sbin/ospfd/control.c b/usr.sbin/ospfd/control.c index d82712b45f8..7619dda9d61 100644 --- a/usr.sbin/ospfd/control.c +++ b/usr.sbin/ospfd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.25 2009/05/31 18:46:01 jacekm Exp $ */ +/* $OpenBSD: control.c,v 1.26 2009/06/05 19:33:58 pyr Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -242,8 +242,8 @@ control_dispatch_imsg(int fd, short event, void *bula) sizeof(ifidx)) { memcpy(&ifidx, imsg.data, sizeof(ifidx)); ospfe_iface_ctl(c, ifidx); - imsg_compose(&c->ibuf, IMSG_CTL_END, 0, - 0, NULL, 0); + imsg_compose_event(&c->ibuf, IMSG_CTL_END, 0, + 0, -1, NULL, 0); } break; case IMSG_CTL_SHOW_DATABASE: @@ -281,8 +281,8 @@ control_imsg_relay(struct imsg *imsg) if ((c = control_connbypid(imsg->hdr.pid)) == NULL) return (0); - return (imsg_compose(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, - imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE)); + return (imsg_compose_event(&c->ibuf, imsg->hdr.type, 0, imsg->hdr.pid, + -1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE)); } void diff --git a/usr.sbin/ospfd/imsg.c b/usr.sbin/ospfd/imsg.c index e3baac0c432..67f77a6c002 100644 --- a/usr.sbin/ospfd/imsg.c +++ b/usr.sbin/ospfd/imsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg.c,v 1.11 2009/06/05 01:19:09 pyr Exp $ */ +/* $OpenBSD: imsg.c,v 1.12 2009/06/05 19:33:58 pyr Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -16,7 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> +#include <sys/param.h> +#include <sys/queue.h> +#include <sys/socket.h> #include <sys/uio.h> #include <errno.h> @@ -24,30 +26,47 @@ #include <string.h> #include <unistd.h> -#include "ospfd.h" -#include "log.h" +#include "imsg.h" void imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *)) { - msgbuf_init(&ibuf->w); - bzero(&ibuf->r, sizeof(ibuf->r)); + if (!ibuf->pid) { + msgbuf_init(&ibuf->w); + bzero(&ibuf->r, sizeof(ibuf->r)); + ibuf->pid = getpid(); + ibuf->handler = handler; + TAILQ_INIT(&ibuf->fds); + } ibuf->fd = fd; ibuf->w.fd = fd; - ibuf->pid = getpid(); - ibuf->handler = handler; - TAILQ_INIT(&ibuf->fds); } ssize_t imsg_read(struct imsgbuf *ibuf) { + struct msghdr msg; + struct cmsghdr *cmsg; + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int) * 16)]; + } cmsgbuf; + struct iovec iov; ssize_t n; + int fd; + struct imsg_fd *ifd; + + bzero(&msg, sizeof(msg)); + + iov.iov_base = ibuf->r.buf + ibuf->r.wpos; + iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); - if ((n = recv(ibuf->fd, ibuf->r.buf + ibuf->r.wpos, - sizeof(ibuf->r.buf) - ibuf->r.wpos, 0)) == -1) { + if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { if (errno != EINTR && errno != EAGAIN) { - log_warn("imsg_read: pipe read error"); return (-1); } return (-2); @@ -55,6 +74,21 @@ imsg_read(struct imsgbuf *ibuf) ibuf->r.wpos += n; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + fd = (*(int *)CMSG_DATA(cmsg)); + if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) { + /* XXX: this return can leak */ + return (-1); + } + ifd->fd = fd; + TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry); + } + /* we do not handle other ctl data level */ + } + return (n); } @@ -71,8 +105,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); if (imsg->hdr.len < IMSG_HEADER_SIZE || imsg->hdr.len > MAX_IMSGSIZE) { - log_warnx("imsg_get: imsg hdr len %u out of bounds, type=%u", - imsg->hdr.len, imsg->hdr.type); + errno = ERANGE; return (-1); } if (imsg->hdr.len > av) @@ -80,7 +113,6 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) datalen = imsg->hdr.len - IMSG_HEADER_SIZE; ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; if ((imsg->data = malloc(datalen)) == NULL) { - log_warn("imsg_get"); return (-1); } memcpy(imsg->data, ibuf->r.rptr, datalen); @@ -96,11 +128,10 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) } int -imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, - pid_t pid, void *data, u_int16_t datalen) +imsg_compose(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid, + pid_t pid, int fd, void *data, u_int16_t datalen) { struct buf *wbuf; - int n; if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) return (-1); @@ -108,15 +139,40 @@ imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, if (imsg_add(wbuf, data, datalen) == -1) return (-1); - if ((n = imsg_close(ibuf, wbuf)) < 0) + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); +} + +int +imsg_composev(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid, + pid_t pid, int fd, const struct iovec *iov, int iovcnt) +{ + struct buf *wbuf; + int i, datalen = 0; + + for (i = 0; i < iovcnt; i++) + datalen += iov[i].iov_len; + + if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) return (-1); - return (n); + for (i = 0; i < iovcnt; i++) + if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) + return (-1); + + wbuf->fd = fd; + + imsg_close(ibuf, wbuf); + + return (1); } /* ARGSUSED */ struct buf * -imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, +imsg_create(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid, pid_t pid, u_int16_t datalen) { struct buf *wbuf; @@ -124,9 +180,7 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, datalen += IMSG_HEADER_SIZE; if (datalen > MAX_IMSGSIZE) { - log_warnx("imsg_create: len %u > MAX_IMSGSIZE; " - "type %u peerid %lu", datalen + IMSG_HEADER_SIZE, - type, peerid); + errno = ERANGE; return (NULL); } @@ -135,7 +189,6 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid, if ((hdr.pid = pid) == 0) hdr.pid = ibuf->pid; if ((wbuf = buf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { - log_warn("imsg_create: buf_open"); return (NULL); } if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) @@ -149,14 +202,13 @@ imsg_add(struct buf *msg, void *data, u_int16_t datalen) { if (datalen) if (buf_add(msg, data, datalen) == -1) { - log_warnx("imsg_add: buf_add error"); buf_free(msg); return (-1); } return (datalen); } -int +void imsg_close(struct imsgbuf *ibuf, struct buf *msg) { struct imsg_hdr *hdr; @@ -164,9 +216,6 @@ imsg_close(struct imsgbuf *ibuf, struct buf *msg) hdr = (struct imsg_hdr *)msg->buf; hdr->len = (u_int16_t)msg->wpos; buf_close(&ibuf->w, msg); - imsg_event_add(ibuf); - - return (0); } void @@ -174,3 +223,35 @@ imsg_free(struct imsg *imsg) { free(imsg->data); } + +int +imsg_get_fd(struct imsgbuf *ibuf) +{ + int fd; + struct imsg_fd *ifd; + + if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) + return (-1); + + fd = ifd->fd; + TAILQ_REMOVE(&ibuf->fds, ifd, entry); + free(ifd); + + return (fd); +} + +int +imsg_flush(struct imsgbuf *ibuf) +{ + while (ibuf->w.queued) + if (msgbuf_write(&ibuf->w) < 0) + return (-1); + return (0); +} + +void +imsg_clear(struct imsgbuf *ibuf) +{ + while (ibuf->w.queued) + msgbuf_clear(&ibuf->w); +} diff --git a/usr.sbin/ospfd/imsg.h b/usr.sbin/ospfd/imsg.h new file mode 100644 index 00000000000..ce89b281534 --- /dev/null +++ b/usr.sbin/ospfd/imsg.h @@ -0,0 +1,108 @@ +/* $OpenBSD: imsg.h,v 1.1 2009/06/05 19:33:59 pyr Exp $ */ + +/* + * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> + * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org> + * Copyright (c) 2003, 2004 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/tree.h> +#include <event.h> + +#define READ_BUF_SIZE 65535 +#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) +#define MAX_IMSGSIZE 8192 + +struct buf { + TAILQ_ENTRY(buf) entry; + u_char *buf; + size_t size; + size_t max; + size_t wpos; + size_t rpos; + int fd; +}; + +struct msgbuf { + TAILQ_HEAD(, buf) bufs; + u_int32_t queued; + int fd; +}; + +struct buf_read { + u_char buf[READ_BUF_SIZE]; + u_char *rptr; + size_t wpos; +}; + +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + +struct imsgbuf { + TAILQ_HEAD(, imsg_fd) fds; + struct buf_read r; + struct msgbuf w; + struct event ev; + void (*handler)(int, short, void *); + int fd; + pid_t pid; + short events; +}; + +struct imsg_hdr { + u_int16_t type; + u_int16_t len; + u_int32_t peerid; + pid_t pid; +}; + +struct imsg { + struct imsg_hdr hdr; + void *data; +}; + + +/* buffer.c */ +struct buf *buf_open(size_t); +struct buf *buf_dynamic(size_t, size_t); +int buf_add(struct buf *, const void *, size_t); +void *buf_reserve(struct buf *, size_t); +void *buf_seek(struct buf *, size_t, size_t); +size_t buf_size(struct buf *); +size_t buf_left(struct buf *); +void buf_close(struct msgbuf *, struct buf *); +void buf_free(struct buf *); +void msgbuf_init(struct msgbuf *); +void msgbuf_clear(struct msgbuf *); +int msgbuf_write(struct msgbuf *); + +/* imsg.c */ +void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *)); +ssize_t imsg_read(struct imsgbuf *); +ssize_t imsg_get(struct imsgbuf *, struct imsg *); +int imsg_compose(struct imsgbuf *, u_int16_t, u_int32_t, pid_t, + int, void *, u_int16_t); +int imsg_composev(struct imsgbuf *, u_int16_t, u_int32_t, pid_t, + int, const struct iovec *, int); +struct buf *imsg_create(struct imsgbuf *, u_int16_t, u_int32_t, pid_t, + u_int16_t); +int imsg_add(struct buf *, void *, u_int16_t); +void imsg_close(struct imsgbuf *, struct buf *); +void imsg_free(struct imsg *); +int imsg_get_fd(struct imsgbuf *); +int imsg_flush(struct imsgbuf *); +void imsg_clear(struct imsgbuf *); diff --git a/usr.sbin/ospfd/lsreq.c b/usr.sbin/ospfd/lsreq.c index 757e1f0ca4f..9acb48c9fde 100644 --- a/usr.sbin/ospfd/lsreq.c +++ b/usr.sbin/ospfd/lsreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsreq.c,v 1.16 2009/01/31 11:44:49 claudio Exp $ */ +/* $OpenBSD: lsreq.c,v 1.17 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -107,7 +107,8 @@ recv_ls_req(struct nbr *nbr, char *buf, u_int16_t len) case NBR_STA_XCHNG: case NBR_STA_LOAD: case NBR_STA_FULL: - imsg_compose(ibuf_rde, IMSG_LS_REQ, nbr->peerid, 0, buf, len); + imsg_compose_event(ibuf_rde, IMSG_LS_REQ, nbr->peerid, + 0, -1, buf, len); break; default: fatalx("recv_ls_req: unknown neighbor state"); diff --git a/usr.sbin/ospfd/lsupdate.c b/usr.sbin/ospfd/lsupdate.c index 80cec73580e..1b8f68e0ba2 100644 --- a/usr.sbin/ospfd/lsupdate.c +++ b/usr.sbin/ospfd/lsupdate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lsupdate.c,v 1.36 2009/03/13 03:58:26 claudio Exp $ */ +/* $OpenBSD: lsupdate.c,v 1.37 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -270,8 +270,8 @@ recv_ls_update(struct nbr *nbr, char *buf, u_int16_t len) "neighbor ID %s", inet_ntoa(nbr->id)); return; } - imsg_compose(ibuf_rde, IMSG_LS_UPD, nbr->peerid, 0, - buf, ntohs(lsa.len)); + imsg_compose_event(ibuf_rde, IMSG_LS_UPD, nbr->peerid, 0, + -1, buf, ntohs(lsa.len)); buf += ntohs(lsa.len); len -= ntohs(lsa.len); } diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c index 4f48d846c85..bbbafdbbb17 100644 --- a/usr.sbin/ospfd/ospfd.c +++ b/usr.sbin/ospfd/ospfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.c,v 1.68 2009/06/05 04:12:52 claudio Exp $ */ +/* $OpenBSD: ospfd.c,v 1.69 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -490,13 +490,13 @@ main_dispatch_rde(int fd, short event, void *bula) void main_imsg_compose_ospfe(int type, pid_t pid, void *data, u_int16_t datalen) { - imsg_compose(ibuf_ospfe, type, 0, pid, data, datalen); + imsg_compose_event(ibuf_ospfe, type, 0, pid, -1, data, datalen); } void main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) { - imsg_compose(ibuf_rde, type, 0, pid, data, datalen); + imsg_compose_event(ibuf_rde, type, 0, pid, -1, data, datalen); } /* this needs to be added here so that ospfctl can be used without libevent */ @@ -513,6 +513,18 @@ imsg_event_add(struct imsgbuf *ibuf) } int +imsg_compose_event(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid, + pid_t pid, int fd, void *data, u_int16_t datalen) +{ + int ret; + + if ((ret = imsg_compose(ibuf, type, peerid, + pid, fd, data, datalen)) != -1) + imsg_event_add(ibuf); + return (ret); +} + +int ospf_redistribute(struct kroute *kr, u_int32_t *metric) { struct redistribute *r; @@ -634,9 +646,9 @@ ospf_reload(void) int ospf_sendboth(enum imsg_type type, void *buf, u_int16_t len) { - if (imsg_compose(ibuf_ospfe, type, 0, 0, buf, len) == -1) + if (imsg_compose_event(ibuf_ospfe, type, 0, 0, -1, buf, len) == -1) return (-1); - if (imsg_compose(ibuf_rde, type, 0, 0, buf, len) == -1) + if (imsg_compose_event(ibuf_rde, type, 0, 0, -1, buf, len) == -1) return (-1); return (0); } diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 0734913ad79..05690e0a6a1 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.80 2009/06/05 04:12:52 claudio Exp $ */ +/* $OpenBSD: ospfd.h,v 1.81 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2004 Esben Norby <norby@openbsd.org> @@ -29,6 +29,7 @@ #include <netinet/in.h> #include <event.h> +#include "imsg.h" #include "ospf.h" #define CONF_FILE "/etc/ospfd.conf" @@ -59,42 +60,6 @@ #define F_BLACKHOLE 0x0080 #define F_REDISTRIBUTED 0x0100 -/* buffer */ -struct buf { - TAILQ_ENTRY(buf) entry; - u_char *buf; - size_t size; - size_t max; - size_t wpos; - size_t rpos; -}; - -struct msgbuf { - TAILQ_HEAD(, buf) bufs; - u_int32_t queued; - int fd; -}; - -#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) -#define MAX_IMSGSIZE 8192 - -struct buf_read { - u_char buf[READ_BUF_SIZE]; - u_char *rptr; - size_t wpos; -}; - -struct imsgbuf { - TAILQ_HEAD(, imsg_fd) fds; - struct buf_read r; - struct msgbuf w; - struct event ev; - void (*handler)(int, short, void *); - int fd; - pid_t pid; - short events; -}; - enum imsg_type { IMSG_NONE, IMSG_CTL_RELOAD, @@ -147,18 +112,6 @@ enum imsg_type { IMSG_DEMOTE }; -struct imsg_hdr { - enum imsg_type type; - u_int16_t len; - u_int32_t peerid; - pid_t pid; -}; - -struct imsg { - struct imsg_hdr hdr; - void *data; -}; - #define REDIST_CONNECTED 0x01 #define REDIST_STATIC 0x02 #define REDIST_LABEL 0x04 @@ -559,20 +512,6 @@ void area_track(struct area *, int); int area_border_router(struct ospfd_conf *); u_int8_t area_ospf_options(struct area *); -/* buffer.c */ -struct buf *buf_open(size_t); -struct buf *buf_dynamic(size_t, size_t); -int buf_add(struct buf *, const void *, size_t); -void *buf_reserve(struct buf *, size_t); -void *buf_seek(struct buf *, size_t, size_t); -size_t buf_size(struct buf *); -size_t buf_left(struct buf *); -void buf_close(struct msgbuf *, struct buf *); -void buf_free(struct buf *); -void msgbuf_init(struct msgbuf *); -void msgbuf_clear(struct msgbuf *); -int msgbuf_write(struct msgbuf *); - /* carp.c */ int carp_demote_init(char *, int); void carp_demote_shutdown(void); @@ -583,19 +522,6 @@ int carp_demote_set(char *, int); struct ospfd_conf *parse_config(char *, int); int cmdline_symset(char *); -/* imsg.c */ -void imsg_init(struct imsgbuf *, int, void (*)(int, short, void *)); -ssize_t imsg_read(struct imsgbuf *); -ssize_t imsg_get(struct imsgbuf *, struct imsg *); -int imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - void *, u_int16_t); -struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t, - u_int16_t); -int imsg_add(struct buf *, void *, u_int16_t); -int imsg_close(struct imsgbuf *, struct buf *); -void imsg_free(struct imsg *); -void imsg_event_add(struct imsgbuf *); /* needs to be provided externally */ - /* in_cksum.c */ u_int16_t in_cksum(void *, size_t); @@ -640,6 +566,9 @@ void main_imsg_compose_ospfe(int, pid_t, void *, u_int16_t); void main_imsg_compose_rde(int, pid_t, void *, u_int16_t); int ospf_redistribute(struct kroute *, u_int32_t *); void merge_config(struct ospfd_conf *, struct ospfd_conf *); +void imsg_event_add(struct imsgbuf *); +int imsg_compose_event(struct imsgbuf *, u_int16_t, u_int32_t, + pid_t, int, void *, u_int16_t); /* printconf.c */ void print_config(struct ospfd_conf *); diff --git a/usr.sbin/ospfd/ospfe.c b/usr.sbin/ospfd/ospfe.c index c2a756d2a17..a4f210d8c0b 100644 --- a/usr.sbin/ospfd/ospfe.c +++ b/usr.sbin/ospfd/ospfe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.c,v 1.67 2009/05/31 18:46:01 jacekm Exp $ */ +/* $OpenBSD: ospfe.c,v 1.68 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -241,14 +241,14 @@ ospfe_shutdown(void) int ospfe_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen) { - return (imsg_compose(ibuf_main, type, 0, pid, data, datalen)); + return (imsg_compose_event(ibuf_main, type, 0, pid, -1, data, datalen)); } int ospfe_imsg_compose_rde(int type, u_int32_t peerid, pid_t pid, void *data, u_int16_t datalen) { - return (imsg_compose(ibuf_rde, type, peerid, pid, data, datalen)); + return (imsg_compose_event(ibuf_rde, type, peerid, pid, -1, data, datalen)); } /* ARGSUSED */ @@ -954,8 +954,8 @@ orig_rtr_lsa(struct area *area) &chksum, sizeof(chksum)); if (self) - imsg_compose(ibuf_rde, IMSG_LS_UPD, self->peerid, 0, - buf->buf, buf_size(buf)); + imsg_compose_event(ibuf_rde, IMSG_LS_UPD, self->peerid, 0, + -1, buf->buf, buf_size(buf)); else log_warnx("orig_rtr_lsa: empty area %s", inet_ntoa(area->id)); @@ -1017,8 +1017,8 @@ orig_net_lsa(struct iface *iface) memcpy(buf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)), &chksum, sizeof(chksum)); - imsg_compose(ibuf_rde, IMSG_LS_UPD, iface->self->peerid, 0, - buf->buf, buf_size(buf)); + imsg_compose_event(ibuf_rde, IMSG_LS_UPD, iface->self->peerid, 0, + -1, buf->buf, buf_size(buf)); buf_free(buf); } @@ -1053,8 +1053,8 @@ ospfe_iface_ctl(struct ctl_conn *c, unsigned int idx) LIST_FOREACH(iface, &area->iface_list, entry) if (idx == 0 || idx == iface->ifindex) { ictl = if_to_ctl(iface); - imsg_compose(&c->ibuf, IMSG_CTL_SHOW_INTERFACE, - 0, 0, ictl, sizeof(struct ctl_iface)); + imsg_compose_event(&c->ibuf, IMSG_CTL_SHOW_INTERFACE, + 0, 0, -1, ictl, sizeof(struct ctl_iface)); } } @@ -1071,13 +1071,13 @@ ospfe_nbr_ctl(struct ctl_conn *c) LIST_FOREACH(nbr, &iface->nbr_list, entry) { if (iface->self != nbr) { nctl = nbr_to_ctl(nbr); - imsg_compose(&c->ibuf, - IMSG_CTL_SHOW_NBR, 0, 0, nctl, + imsg_compose_event(&c->ibuf, + IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, sizeof(struct ctl_nbr)); } } - imsg_compose(&c->ibuf, IMSG_CTL_END, 0, 0, NULL, 0); + imsg_compose_event(&c->ibuf, IMSG_CTL_END, 0, 0, -1, NULL, 0); } void diff --git a/usr.sbin/ospfd/rde.c b/usr.sbin/ospfd/rde.c index 7a530910255..85ead90c640 100644 --- a/usr.sbin/ospfd/rde.c +++ b/usr.sbin/ospfd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.79 2009/05/31 18:46:01 jacekm Exp $ */ +/* $OpenBSD: rde.c,v 1.80 2009/06/05 19:33:59 pyr Exp $ */ /* * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org> @@ -216,7 +216,7 @@ int rde_imsg_compose_ospfe(int type, u_int32_t peerid, pid_t pid, void *data, u_int16_t datalen) { - return (imsg_compose(ibuf_ospfe, type, peerid, pid, data, datalen)); + return (imsg_compose_event(ibuf_ospfe, type, peerid, pid, -1, data, datalen)); } /* ARGSUSED */ @@ -296,8 +296,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) lsa_snap(nbr->area, imsg.hdr.peerid); - imsg_compose(ibuf_ospfe, IMSG_DB_END, imsg.hdr.peerid, - 0, NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_DB_END, imsg.hdr.peerid, + 0, -1, NULL, 0); break; case IMSG_DD: nbr = rde_nbr_find(imsg.hdr.peerid); @@ -329,8 +329,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) * newer or missing */ rde_req_list_add(nbr, &lsa_hdr); - imsg_compose(ibuf_ospfe, IMSG_DD, - imsg.hdr.peerid, 0, &lsa_hdr, + imsg_compose_event(ibuf_ospfe, IMSG_DD, + imsg.hdr.peerid, 0, -1, &lsa_hdr, sizeof(lsa_hdr)); } } @@ -340,11 +340,11 @@ rde_dispatch_imsg(int fd, short event, void *bula) "packet", imsg.hdr.peerid); if (!error) - imsg_compose(ibuf_ospfe, IMSG_DD_END, - imsg.hdr.peerid, 0, NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_DD_END, + imsg.hdr.peerid, 0, -1, NULL, 0); else - imsg_compose(ibuf_ospfe, IMSG_DD_BADLSA, - imsg.hdr.peerid, 0, NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_DD_BADLSA, + imsg.hdr.peerid, 0, -1, NULL, 0); break; case IMSG_LS_REQ: nbr = rde_nbr_find(imsg.hdr.peerid); @@ -360,12 +360,12 @@ rde_dispatch_imsg(int fd, short event, void *bula) if ((v = lsa_find(nbr->area, ntohl(req_hdr.type), req_hdr.ls_id, req_hdr.adv_rtr)) == NULL) { - imsg_compose(ibuf_ospfe, IMSG_LS_BADREQ, - imsg.hdr.peerid, 0, NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_LS_BADREQ, + imsg.hdr.peerid, 0, -1, NULL, 0); continue; } - imsg_compose(ibuf_ospfe, IMSG_LS_UPD, - imsg.hdr.peerid, 0, v->lsa, + imsg_compose_event(ibuf_ospfe, IMSG_LS_UPD, + imsg.hdr.peerid, 0, -1, v->lsa, ntohs(v->lsa->hdr.len)); } if (l != 0) @@ -419,14 +419,14 @@ rde_dispatch_imsg(int fd, short event, void *bula) break; /* flood and perhaps ack LSA */ - imsg_compose(ibuf_ospfe, IMSG_LS_FLOOD, - imsg.hdr.peerid, 0, lsa, + imsg_compose_event(ibuf_ospfe, IMSG_LS_FLOOD, + imsg.hdr.peerid, 0, -1, lsa, ntohs(lsa->hdr.len)); /* reflood self originated LSA */ if (self && v) - imsg_compose(ibuf_ospfe, IMSG_LS_FLOOD, - v->peerid, 0, v->lsa, + imsg_compose_event(ibuf_ospfe, IMSG_LS_FLOOD, + v->peerid, 0, -1, v->lsa, ntohs(v->lsa->hdr.len)); /* lsa not added so free it */ if (self) @@ -444,8 +444,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) * in the table we should reset the session. */ if (rde_req_list_exists(nbr, &lsa->hdr)) { - imsg_compose(ibuf_ospfe, IMSG_LS_BADREQ, - imsg.hdr.peerid, 0, NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_LS_BADREQ, + imsg.hdr.peerid, 0, -1, NULL, 0); break; } @@ -459,13 +459,13 @@ rde_dispatch_imsg(int fd, short event, void *bula) break; /* directly send current LSA, no ack */ - imsg_compose(ibuf_ospfe, IMSG_LS_UPD, - imsg.hdr.peerid, 0, v->lsa, + imsg_compose_event(ibuf_ospfe, IMSG_LS_UPD, + imsg.hdr.peerid, 0, -1, v->lsa, ntohs(v->lsa->hdr.len)); } else { /* LSA equal send direct ack */ - imsg_compose(ibuf_ospfe, IMSG_LS_ACK, - imsg.hdr.peerid, 0, &lsa->hdr, + imsg_compose_event(ibuf_ospfe, IMSG_LS_ACK, + imsg.hdr.peerid, 0, -1, &lsa->hdr, sizeof(lsa->hdr)); free(lsa); } @@ -510,8 +510,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) } if (imsg.hdr.len == IMSG_HEADER_SIZE) { LIST_FOREACH(area, &rdeconf->area_list, entry) { - imsg_compose(ibuf_ospfe, IMSG_CTL_AREA, - 0, imsg.hdr.pid, area, + imsg_compose_event(ibuf_ospfe, IMSG_CTL_AREA, + 0, imsg.hdr.pid, -1, area, sizeof(*area)); lsa_dump(&area->lsa_tree, imsg.hdr.type, imsg.hdr.pid); @@ -521,8 +521,8 @@ rde_dispatch_imsg(int fd, short event, void *bula) } else { memcpy(&aid, imsg.data, sizeof(aid)); if ((area = area_find(rdeconf, aid)) != NULL) { - imsg_compose(ibuf_ospfe, IMSG_CTL_AREA, - 0, imsg.hdr.pid, area, + imsg_compose_event(ibuf_ospfe, IMSG_CTL_AREA, + 0, imsg.hdr.pid, -1, area, sizeof(*area)); lsa_dump(&area->lsa_tree, imsg.hdr.type, imsg.hdr.pid); @@ -532,13 +532,13 @@ rde_dispatch_imsg(int fd, short event, void *bula) imsg.hdr.pid); } } - imsg_compose(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, - NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, + -1, NULL, 0); break; case IMSG_CTL_SHOW_RIB: LIST_FOREACH(area, &rdeconf->area_list, entry) { - imsg_compose(ibuf_ospfe, IMSG_CTL_AREA, - 0, imsg.hdr.pid, area, sizeof(*area)); + imsg_compose_event(ibuf_ospfe, IMSG_CTL_AREA, + 0, imsg.hdr.pid, -1, area, sizeof(*area)); rt_dump(area->id, imsg.hdr.pid, RIB_RTR); rt_dump(area->id, imsg.hdr.pid, RIB_NET); @@ -546,15 +546,15 @@ rde_dispatch_imsg(int fd, short event, void *bula) aid.s_addr = 0; rt_dump(aid, imsg.hdr.pid, RIB_EXT); - imsg_compose(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, - NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, + -1, NULL, 0); break; case IMSG_CTL_SHOW_SUM: rde_send_summary(imsg.hdr.pid); LIST_FOREACH(area, &rdeconf->area_list, entry) rde_send_summary_area(area, imsg.hdr.pid); - imsg_compose(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, - NULL, 0); + imsg_compose_event(ibuf_ospfe, IMSG_CTL_END, 0, imsg.hdr.pid, + -1, NULL, 0); break; default: log_debug("rde_dispatch_imsg: unexpected imsg %d", @@ -745,6 +745,7 @@ rde_send_change_kroute(struct rt_node *r) if (krcount == 0) fatalx("rde_send_change_kroute: no valid nexthop found"); imsg_close(ibuf_main, wbuf); + imsg_event_add(ibuf_main); } void @@ -756,7 +757,7 @@ rde_send_delete_kroute(struct rt_node *r) kr.prefix.s_addr = r->prefix.s_addr; kr.prefixlen = r->prefixlen; - imsg_compose(ibuf_main, IMSG_KROUTE_DELETE, 0, 0, &kr, sizeof(kr)); + imsg_compose_event(ibuf_main, IMSG_KROUTE_DELETE, 0, 0, -1, &kr, sizeof(kr)); } void |