summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2003-12-25 17:07:25 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2003-12-25 17:07:25 +0000
commit3b77229a4787e1f6c5798dfbc5ea66adc4e0b7c8 (patch)
tree48201f518865ca22afcdd2d38da06a50bf8db4aa /usr.sbin
parent3d1080c54d40c44da9c5c95919368e4a0c776889 (diff)
track routing table changes that are _not_ caused by bgpd itself
ok claudio@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/bgpd.c14
-rw-r--r--usr.sbin/bgpd/bgpd.h22
-rw-r--r--usr.sbin/bgpd/kroute.c101
3 files changed, 119 insertions, 18 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index d2a7468bdb8..f065e021238 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.28 2003/12/25 02:24:26 henning Exp $ */
+/* $OpenBSD: bgpd.c,v 1.29 2003/12/25 17:07:24 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -82,7 +82,8 @@ usage(void)
#define POLL_MAX 8
#define PFD_PIPE_SESSION 0
#define PFD_PIPE_ROUTE 1
-#define PFD_MRT_START 2
+#define PFD_SOCK_ROUTE 2
+#define PFD_MRT_START 3
int
main(int argc, char *argv[])
@@ -203,6 +204,8 @@ main(int argc, char *argv[])
pfd[PFD_PIPE_ROUTE].events = POLLIN;
if (ibuf_rde.w.queued)
pfd[PFD_PIPE_ROUTE].events |= POLLOUT;
+ pfd[PFD_SOCK_ROUTE].fd = rfd;
+ pfd[PFD_SOCK_ROUTE].events = POLLIN;
i = PFD_MRT_START;
LIST_FOREACH(mconf, &mrtconf, list)
if (mconf->msgbuf.queued > 0) {
@@ -211,7 +214,7 @@ main(int argc, char *argv[])
mrt[i++] = mconf;
}
- if ((nfds = poll(pfd, 2, INFTIM)) == -1)
+ if ((nfds = poll(pfd, i, INFTIM)) == -1)
if (errno != EINTR)
fatal("poll error", errno);
@@ -233,6 +236,11 @@ main(int argc, char *argv[])
dispatch_imsg(&ibuf_rde, PFD_PIPE_ROUTE, &mrtconf);
}
+ if (nfds > 0 && pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
+ nfds--;
+ kroute_dispatch_msg(rfd);
+ }
+
for (j = PFD_MRT_START; j < i && nfds > 0 ; j++) {
if (pfd[j].revents & POLLOUT) {
if ((n = msgbuf_write(&mrt[i]->msgbuf)) < 0)
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index d8b969c9202..e5ec3141b9c 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.24 2003/12/25 14:28:49 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.25 2003/12/25 17:07:24 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -16,7 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __BGPD_H__
-#define __BGPD_H__
+#define __BGPD_H__
#include <sys/types.h>
#include <sys/queue.h>
@@ -28,19 +28,20 @@
#define BGP_VERSION 4
#define BGP_PORT 179
-#define CONFFILE "/etc/bgpd.conf"
+#define CONFFILE "/etc/bgpd.conf"
#define BGPD_USER "_bgpd"
-#define PEER_DESCR_LEN 32
+#define PEER_DESCR_LEN 32
#define MAX_PKTSIZE 4096
#define MIN_HOLDTIME 3
#define READ_BUF_SIZE 65535
+#define RT_BUF_SIZE 16384
-#define BGPD_OPT_VERBOSE 0x0001
-#define BGPD_OPT_VERBOSE2 0x0002
-#define BGPD_OPT_NOACTION 0x0004
+#define BGPD_OPT_VERBOSE 0x0001
+#define BGPD_OPT_VERBOSE2 0x0002
+#define BGPD_OPT_NOACTION 0x0004
-#define BGPD_FLAG_NO_FIB_UPDATE 0x0001
+#define BGPD_FLAG_NO_FIB_UPDATE 0x0001
enum {
PROC_MAIN,
@@ -143,7 +144,7 @@ struct peer {
struct peer *next;
};
-#define MRT_FILE_LEN 512
+#define MRT_FILE_LEN 512
enum mrtdump_type {
MRT_NONE,
MRT_TABLE_DUMP
@@ -181,7 +182,7 @@ struct mrtdump_config {
/* ipc messages */
#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
-#define MAX_IMSGSIZE 8192
+#define MAX_IMSGSIZE 8192
struct imsg_readbuf {
u_char buf[MAX_IMSGSIZE];
@@ -301,5 +302,6 @@ int kroute_init(void);
int kroute_change(int, struct kroute *);
int kroute_delete(int, struct kroute *);
void kroute_shutdown(int);
+void kroute_dispatch_msg(int);
#endif /* __BGPD_H__ */
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index ee2ef56e7a2..890b54b70c4 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.18 2003/12/25 16:21:50 henning Exp $ */
+/* $OpenBSD: kroute.c,v 1.19 2003/12/25 17:07:24 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -52,6 +52,7 @@ RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare);
RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare);
u_int32_t rtseq = 1;
+pid_t pid;
#define F_BGPD_INSERTED 0x0001
#define F_KERNEL 0x0002
@@ -68,6 +69,8 @@ kroute_init(void)
if (setsockopt(s, SOL_SOCKET, SO_USELOOPBACK, &opt, sizeof(opt)) == -1)
fatal("route setsockopt", errno);
+ pid = getpid();
+
RB_INIT(&krt);
kroute_fetchtable();
@@ -175,11 +178,8 @@ kroute_delete(int fd, struct kroute *kroute)
s.r.prefix = kroute->prefix;
s.r.prefixlen = kroute->prefixlen;
- if ((kr = RB_FIND(kroute_tree, &krt, &s)) == NULL) {
- /* at the moment this is totally valid... */
- log_kroute(LOG_CRIT, "kroute_delete: no match for", kroute);
+ if ((kr = RB_FIND(kroute_tree, &krt, &s)) == NULL)
return (0);
- }
if (!(kr->flags & F_BGPD_INSERTED))
return (0);
@@ -323,3 +323,94 @@ kroute_fetchtable(void)
free(buf);
return (0);
}
+
+void
+kroute_dispatch_msg(int fd)
+{
+ char buf[RT_BUF_SIZE];
+ ssize_t n;
+ char *next, *lim;
+ struct rt_msghdr *rtm;
+ struct sockaddr *sa, *rti_info[RTAX_MAX];
+ struct sockaddr_in *sa_in;
+ struct kroute_node *kr, s;
+ in_addr_t nexthop;
+
+ if ((n = read(fd, &buf, sizeof(buf))) == -1)
+ fatal("read error on routing socket", errno);
+ if (n == 0)
+ fatal("routing socket closed", 0);
+
+ lim = buf + n;
+ for (next = buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr *)next;
+ sa = (struct sockaddr *)(rtm + 1);
+ get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+
+ if ((sa_in = (struct sockaddr_in *)rti_info[RTAX_DST]) == NULL)
+ continue;
+
+ if (rtm->rtm_flags & RTF_LLINFO) /* arp cache */
+ continue;
+
+ if (rtm->rtm_pid == pid) /* cause by us */
+ continue;
+
+ if (rtm->rtm_errno) /* failed attempts... */
+ continue;
+
+ s.r.prefix = sa_in->sin_addr.s_addr;
+ if ((sa_in = (struct sockaddr_in *)rti_info[RTAX_NETMASK]) !=
+ NULL) {
+ s.r.prefixlen =
+ mask2prefixlen(sa_in->sin_addr.s_addr);
+ } else if (rtm->rtm_flags & RTF_HOST)
+ s.r.prefixlen = 32;
+ else
+ s.r.prefixlen = prefixlen_classful(s.r.prefix);
+
+ if ((sa_in = (struct sockaddr_in *)rti_info[RTAX_GATEWAY]) !=
+ NULL)
+ nexthop = sa_in->sin_addr.s_addr;
+ else
+ nexthop = 0;
+
+ switch (rtm->rtm_type) {
+ case RTM_ADD:
+ case RTM_CHANGE:
+ if (nexthop == 0)
+ fatal("nexthop is 0 in kroute_dispatch!", 0);
+
+ if ((kr = RB_FIND(kroute_tree, &krt, &s)) != NULL) {
+ if (kr->flags & F_KERNEL)
+ kr->r.nexthop = nexthop;
+ } else {
+ if ((kr = calloc(1,
+ sizeof(struct kroute_node))) == NULL)
+ fatal(NULL, errno);
+ kr->r.prefix = s.r.prefix;
+ kr->r.prefixlen = s.r.prefixlen;
+ kr->r.nexthop = nexthop;
+ kr->flags = F_KERNEL;
+
+ if (RB_INSERT(kroute_tree, &krt, kr) != NULL) {
+ logit(LOG_CRIT, "RB_INSERT failed!");
+ continue;
+ }
+ }
+ break;
+ case RTM_DELETE:
+ if ((kr = RB_FIND(kroute_tree, &krt, &s)) == NULL)
+ continue;
+ if (!(kr->flags & F_KERNEL))
+ continue;
+ RB_REMOVE(kroute_tree, &krt, kr);
+ free(kr);
+ break;
+ default:
+ /* ingnore for now */
+ break;
+ }
+
+ }
+}