summaryrefslogtreecommitdiff
path: root/usr.sbin/ospfd
diff options
context:
space:
mode:
authorPierre-Yves Ritschard <pyr@cvs.openbsd.org>2009-06-05 19:34:00 +0000
committerPierre-Yves Ritschard <pyr@cvs.openbsd.org>2009-06-05 19:34:00 +0000
commit1602fb21c249be1b31193fdce7680df0b641b4a8 (patch)
tree4dbe76394c9a5b14ff01caa07a6bfc979407a243 /usr.sbin/ospfd
parentafb1c16a00506939d346089ba9c0e151425809da (diff)
make ospfd's imsg lib ready as well.
ok claudio@
Diffstat (limited to 'usr.sbin/ospfd')
-rw-r--r--usr.sbin/ospfd/auth.c4
-rw-r--r--usr.sbin/ospfd/buffer.c41
-rw-r--r--usr.sbin/ospfd/control.c10
-rw-r--r--usr.sbin/ospfd/imsg.c141
-rw-r--r--usr.sbin/ospfd/imsg.h108
-rw-r--r--usr.sbin/ospfd/lsreq.c5
-rw-r--r--usr.sbin/ospfd/lsupdate.c6
-rw-r--r--usr.sbin/ospfd/ospfd.c22
-rw-r--r--usr.sbin/ospfd/ospfd.h81
-rw-r--r--usr.sbin/ospfd/ospfe.c24
-rw-r--r--usr.sbin/ospfd/rde.c75
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