diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2003-12-25 17:07:25 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2003-12-25 17:07:25 +0000 |
commit | 3b77229a4787e1f6c5798dfbc5ea66adc4e0b7c8 (patch) | |
tree | 48201f518865ca22afcdd2d38da06a50bf8db4aa /usr.sbin | |
parent | 3d1080c54d40c44da9c5c95919368e4a0c776889 (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.c | 14 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 22 | ||||
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 101 |
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; + } + + } +} |