Module Name:    src
Committed By:   ozaki-r
Date:           Wed Aug  9 08:30:54 UTC 2017

Modified Files:
        src/sys/netipsec: key.c

Log Message:
Limit the number of mbufs queued for deferred key_sendup_mbuf

It's easy to be queued hundreds of mbufs on the list under heavy
network load.


To generate a diff of this commit:
cvs rdiff -u -r1.221 -r1.222 src/sys/netipsec/key.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netipsec/key.c
diff -u src/sys/netipsec/key.c:1.221 src/sys/netipsec/key.c:1.222
--- src/sys/netipsec/key.c:1.221	Wed Aug  9 06:04:41 2017
+++ src/sys/netipsec/key.c	Wed Aug  9 08:30:54 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.c,v 1.221 2017/08/09 06:04:41 ozaki-r Exp $	*/
+/*	$NetBSD: key.c,v 1.222 2017/08/09 08:30:54 ozaki-r Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.221 2017/08/09 06:04:41 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.222 2017/08/09 08:30:54 ozaki-r Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -735,7 +735,7 @@ static struct mbuf *key_getcomb_ipcomp (
 static struct mbuf *key_getprop (const struct secasindex *);
 
 static int key_acquire (const struct secasindex *, struct secpolicy *);
-static void key_acquire_sendup_mbuf_later(struct mbuf *);
+static int key_acquire_sendup_mbuf_later(struct mbuf *);
 static void key_acquire_sendup_pending_mbuf(void);
 #ifndef IPSEC_NONBLOCK_ACQUIRE
 static struct secacq *key_newacq (const struct secasindex *);
@@ -6656,8 +6656,7 @@ key_acquire(const struct secasindex *sai
 	 *
 	 * So defer key_sendup_mbuf to the timer.
 	 */
-	key_acquire_sendup_mbuf_later(result);
-	return 0;
+	return key_acquire_sendup_mbuf_later(result);
 
  fail:
 	if (result)
@@ -6666,6 +6665,8 @@ key_acquire(const struct secasindex *sai
 }
 
 static struct mbuf *key_acquire_mbuf_head = NULL;
+static unsigned key_acquire_mbuf_count = 0;
+#define KEY_ACQUIRE_MBUF_MAX	10
 
 static void
 key_acquire_sendup_pending_mbuf(void)
@@ -6684,6 +6685,7 @@ again:
 				prev->m_nextpkt = NULL;
 			if (m == key_acquire_mbuf_head)
 				key_acquire_mbuf_head = NULL;
+			key_acquire_mbuf_count--;
 			break;
 		}
 		prev = m;
@@ -6694,6 +6696,7 @@ again:
 	if (m == NULL)
 		return;
 
+	m->m_nextpkt = NULL;
 	error = key_sendup_mbuf(NULL, m, KEY_SENDUP_REGISTERED);
 	if (error != 0)
 		IPSECLOG(LOG_WARNING, "key_sendup_mbuf failed (error=%d)\n",
@@ -6703,18 +6706,27 @@ again:
 		goto again;
 }
 
-static void
+static int
 key_acquire_sendup_mbuf_later(struct mbuf *m)
 {
 
 	mutex_enter(&key_misc.lock);
+	/* Avoid queuing too much mbufs */
+	if (key_acquire_mbuf_count >= KEY_ACQUIRE_MBUF_MAX) {
+		mutex_exit(&key_misc.lock);
+		m_freem(m);
+		return ENOBUFS; /* XXX */
+	}
 	/* Enqueue mbuf at the head of the list */
 	m->m_nextpkt = key_acquire_mbuf_head;
 	key_acquire_mbuf_head = m;
+	key_acquire_mbuf_count++;
 	mutex_exit(&key_misc.lock);
 
 	/* Kick the timer */
 	key_timehandler(NULL);
+
+	return 0;
 }
 
 #ifndef IPSEC_NONBLOCK_ACQUIRE

Reply via email to