summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2011-09-16 18:24:58 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2011-09-16 18:24:58 +0000
commit577dc55bdf02a64a975a3e7a71b935f10ce33582 (patch)
treeb05f3d4859a3c522b9f160e25f69590669a1e4f6
parent5796a75b450b4a28b6a11a884f84ccba72511770 (diff)
Rather than reloading kernel routes immediately when an RTM_DESYNC is seen,
set (or extend) a timer and only reload when this expires. Avoids repeatedly dumping full kernel routes (thus generating more load) when the machine has problems keeping up with messages on the route socket. (if you see lots of repeated "reloading interface list and routing table" in ospfd logs, this will help). Suggestions/ok claudio@.
-rw-r--r--usr.sbin/ospfd/kroute.c58
-rw-r--r--usr.sbin/ospfd/ospf.h6
2 files changed, 56 insertions, 8 deletions
diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c
index 67c4414f140..dd6f8f03c82 100644
--- a/usr.sbin/ospfd/kroute.c
+++ b/usr.sbin/ospfd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.90 2011/07/04 04:34:14 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.91 2011/09/16 18:24:57 sthen Exp $ */
/*
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
@@ -47,7 +47,12 @@ struct {
int fib_serial;
int fd;
struct event ev;
+ struct event reload;
u_int rdomain;
+#define KR_RELOAD_IDLE 0
+#define KR_RELOAD_FETCH 1
+#define KR_RELOAD_HOLD 2
+ int reload_state;
} kr_state;
struct kroute_node {
@@ -102,6 +107,8 @@ int dispatch_rtmsg(void);
int fetchtable(void);
int fetchifs(u_short);
int rtmsg_process(char *, int);
+void kr_fib_reload_timer(int, short, void *);
+void kr_fib_reload_arm_timer(int);
RB_HEAD(kroute_tree, kroute_node) krt;
RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
@@ -170,6 +177,9 @@ kr_init(int fs, u_int rdomain)
kr_dispatch_msg, NULL);
event_add(&kr_state.ev, NULL);
+ kr_state.reload_state = KR_RELOAD_IDLE;
+ evtimer_set(&kr_state.reload, kr_fib_reload_timer, NULL);
+
return (0);
}
@@ -357,7 +367,32 @@ kr_fib_decouple(void)
}
void
-kr_fib_reload(void)
+kr_fib_reload_timer(int fd, short event, void *bula)
+{
+ if (kr_state.reload_state == KR_RELOAD_FETCH) {
+ kr_fib_reload();
+ kr_state.reload_state = KR_RELOAD_HOLD;
+ kr_fib_reload_arm_timer(KR_RELOAD_HOLD_TIMER);
+ } else {
+ kr_state.reload_state = KR_RELOAD_IDLE;
+ }
+}
+
+void
+kr_fib_reload_arm_timer(int delay)
+{
+ struct timeval tv;
+
+ timerclear(&tv);
+ tv.tv_sec = delay / 1000;
+ tv.tv_usec = (delay % 1000) * 1000;
+
+ if (evtimer_add(&kr_state.reload, &tv) == -1)
+ fatal("add_reload_timer");
+}
+
+void
+kr_fib_reload()
{
struct kroute_node *krn, *kr, *kn;
@@ -1172,7 +1207,6 @@ send_rtmsg(int fd, int action, struct kroute *kroute)
iov[iovcnt++].iov_len = sizeof(sa_rl);
}
-
retry:
if (writev(fd, iov, iovcnt) == -1) {
if (errno == ESRCH) {
@@ -1298,7 +1332,7 @@ rtmsg_process(char *buf, int len)
u_int8_t prefixlen, prio;
int flags, mpath;
u_short ifindex = 0;
- int rv;
+ int rv, delay;
int offset;
char *next;
@@ -1524,10 +1558,20 @@ add:
break;
case RTM_DESYNC:
/*
- * We lost some routing packets. Force a reload of
- * the kernel route/interface information.
+ * We lost some routing packets. Schedule a reload
+ * of the kernel route/interface information.
*/
- kr_fib_reload();
+ if (kr_state.reload_state == KR_RELOAD_IDLE) {
+ delay = KR_RELOAD_TIMER;
+ log_info("desync; scheduling fib reload");
+ } else {
+ delay = KR_RELOAD_HOLD_TIMER;
+ log_debug("desync during KR_RELOAD_%s",
+ kr_state.reload_state ==
+ KR_RELOAD_FETCH ? "FETCH" : "HOLD");
+ }
+ kr_state.reload_state = KR_RELOAD_FETCH;
+ kr_fib_reload_arm_timer(delay);
break;
default:
/* ignore for now */
diff --git a/usr.sbin/ospfd/ospf.h b/usr.sbin/ospfd/ospf.h
index fe0a8998ffc..f4077a1f9ef 100644
--- a/usr.sbin/ospfd/ospf.h
+++ b/usr.sbin/ospfd/ospf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf.h,v 1.21 2011/05/09 12:24:41 claudio Exp $ */
+/* $OpenBSD: ospf.h,v 1.22 2011/09/16 18:24:57 sthen Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -75,6 +75,10 @@
#define MIN_SPF_HOLDTIME 10
#define MAX_SPF_HOLDTIME 5000
+/* msec */
+#define KR_RELOAD_TIMER 250
+#define KR_RELOAD_HOLD_TIMER 5000
+
#define MIN_MD_ID 0
#define MAX_MD_ID 255