summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/Makefile4
-rw-r--r--usr.sbin/bgpd/bgpd.c21
-rw-r--r--usr.sbin/bgpd/bgpd.h19
-rw-r--r--usr.sbin/bgpd/kroute.c118
4 files changed, 157 insertions, 5 deletions
diff --git a/usr.sbin/bgpd/Makefile b/usr.sbin/bgpd/Makefile
index bf03b5cb008..70045b2d75d 100644
--- a/usr.sbin/bgpd/Makefile
+++ b/usr.sbin/bgpd/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.5 2003/12/22 00:10:33 henning Exp $
+# $OpenBSD: Makefile,v 1.6 2003/12/22 15:22:13 henning Exp $
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
+ rde.c rde_rib.c rde_decide.c rde_prefix.c mrt.c kroute.c
CFLAGS+= -Wall
CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CLFAGS+= -Wmissing-declarations -Wredundant-decls
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index ef65fbb75fb..5c4660f0f48 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.17 2003/12/22 15:11:45 henning Exp $ */
+/* $OpenBSD: bgpd.c,v 1.18 2003/12/22 15:22:13 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -41,6 +41,7 @@ int reconfigure(char *, struct bgpd_config *, struct mrt_config *);
int dispatch_imsg(struct imsgbuf *, int, struct mrt_config *);
int mrtfd = -1;
+int rfd = -1;
volatile sig_atomic_t mrtdump = 0;
volatile sig_atomic_t quit = 0;
volatile sig_atomic_t reconfig = 0;
@@ -191,6 +192,7 @@ main(int argc, char *argv[])
imsg_init(&ibuf_se, pipe_m2s[0]);
imsg_init(&ibuf_rde, pipe_m2r[0]);
+ rfd = kroute_init();
while (quit == 0) {
pfd[PFD_PIPE_SESSION].fd = ibuf_se.sock;
@@ -331,6 +333,23 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx, struct mrt_config *conf)
break;
}
break;
+ case IMSG_KROUTE_ADD:
+ if (idx != PFD_PIPE_ROUTE)
+ fatal("route request not from RDE", 0);
+ if (kroute_add(rfd, imsg.data))
+ fatal("kroute bytes left", 0);
+ break;
+ case IMSG_KROUTE_CHANGE:
+ if (idx != PFD_PIPE_ROUTE)
+ fatal("route request not from RDE", 0);
+ if (kroute_change(rfd, imsg.data))
+ fatal("kroute bytes left", 0);
+ case IMSG_KROUTE_DELETE:
+ if (idx != PFD_PIPE_ROUTE)
+ fatal("route request not from RDE", 0);
+ if (kroute_delete(rfd, imsg.data))
+ fatal("kroute bytes left", 0);
+ break;
default:
break;
}
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 486928421f8..bc3d22f26c7 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.12 2003/12/22 15:07:05 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.13 2003/12/22 15:22:13 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -207,7 +207,10 @@ enum imsg_type {
IMSG_SESSION_DOWN,
IMSG_MRT_REQ,
IMSG_MRT_MSG,
- IMSG_MRT_END
+ IMSG_MRT_END,
+ IMSG_KROUTE_ADD,
+ IMSG_KROUTE_CHANGE,
+ IMSG_KROUTE_DELETE
};
struct imsg_hdr {
@@ -236,6 +239,12 @@ enum suberr_update {
ERR_UPD_ASPATH
};
+struct kroute {
+ in_addr_t prefix;
+ u_int8_t prefixlen;
+ in_addr_t nexthop;
+};
+
/* prototypes */
/* session.c */
int session_main(struct bgpd_config *, int[2], int[2]);
@@ -284,4 +293,10 @@ int rde_main(struct bgpd_config *, int[2], int[2]);
/* mrt.c */
int mrt_mergeconfig(struct mrt_config *, struct mrt_config *);
+/* kroute.c */
+int kroute_init(void);
+int kroute_add(int, struct kroute *);
+int kroute_change(int, struct kroute *);
+int kroute_delete(int, struct kroute *);
+
#endif /* __BGPD_H__ */
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
new file mode 100644
index 00000000000..1c8ba683e0b
--- /dev/null
+++ b/usr.sbin/bgpd/kroute.c
@@ -0,0 +1,118 @@
+/* $OpenBSD: kroute.c,v 1.1 2003/12/22 15:22:13 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 <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/route.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "bgpd.h"
+
+int kroute_msg(int, int, struct kroute *);
+
+u_int32_t rtseq = 1;
+
+int
+kroute_init(void)
+{
+ int s, opt;
+
+ if ((s = socket(AF_ROUTE, SOCK_RAW, 0)) < 0)
+ fatal("route socket", errno);
+
+ if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
+ fatal(NULL, errno);
+
+ /* not intrested in my own messages */
+ if (setsockopt(s, SOL_SOCKET, SO_USELOOPBACK, &opt, sizeof(opt)) == -1)
+ fatal("route setsockopt", errno);
+
+ return (s);
+}
+
+int
+kroute_msg(int fd, int action, struct kroute *kroute)
+{
+ struct {
+ struct rt_msghdr hdr;
+ struct sockaddr_in prefix;
+ struct sockaddr_in nexthop;
+ struct sockaddr_in mask;
+ } r;
+ ssize_t n;
+
+ r.hdr.rtm_msglen = sizeof(r);
+ r.hdr.rtm_version = RTM_VERSION;
+ r.hdr.rtm_type = action;
+ r.hdr.rtm_flags = RTF_GATEWAY|RTF_MASK; /* XXX */
+ r.hdr.rtm_seq = rtseq++; /* overflow doesn't matter */
+ r.hdr.rtm_addrs = RTA_DST|RTA_GATEWAY|RTA_NETMASK;
+ r.prefix.sin_family = AF_INET;
+ r.prefix.sin_addr.s_addr = kroute->prefix;
+ r.nexthop.sin_family = AF_INET;
+ r.nexthop.sin_addr.s_addr = kroute->nexthop;
+ r.mask.sin_family = AF_INET;
+ r.mask.sin_addr.s_addr = htonl(0xffffffff << (32 - kroute->prefixlen));
+
+retry:
+ if ((n = write(fd, &r, sizeof(r))) == -1) {
+ if (errno == ESRCH) {
+ if (r.hdr.rtm_type == RTM_CHANGE) {
+ r.hdr.rtm_type = RTM_ADD;
+ goto retry;
+ } else if (r.hdr.rtm_type == RTM_DELETE) {
+ logit(LOG_INFO, "route vanished before delete");
+ return (0);
+ }
+ } else {
+ logit(LOG_INFO, "kroute_msg", strerror(errno));
+ return (-1);
+ }
+ }
+ if (n == sizeof(r))
+ return (0);
+
+ /* XXX we could not write everything... bad bad bad. cope. */
+ return (n);
+}
+
+int
+kroute_add(int fd, struct kroute *kroute)
+{
+ return (kroute_msg(fd, RTM_ADD, kroute));
+}
+
+int
+kroute_change(int fd, struct kroute *kroute)
+{
+ return (kroute_msg(fd, RTM_CHANGE, kroute));
+}
+
+int
+kroute_delete(int fd, struct kroute *kroute)
+{
+ return (kroute_msg(fd, RTM_DELETE, kroute));
+}