Fri Dec 16 00:58:00 2011 UTC ()
Take softnet_lock and kernel lock in frag6_slowtimo and frag6_fasttimo,
similar to how it's done with other protocols.

If we don't do this sending ICMPv6 messages in this path can cause races
in network interface drivers.


(jakllsch)
diff -r1.50 -r1.51 src/sys/netinet6/frag6.c

cvs diff -r1.50 -r1.51 src/sys/netinet6/frag6.c (expand / switch to context diff)
--- src/sys/netinet6/frag6.c 2011/11/04 00:22:33 1.50
+++ src/sys/netinet6/frag6.c 2011/12/16 00:57:59 1.51
@@ -1,4 +1,4 @@
-/*	$NetBSD: frag6.c,v 1.50 2011/11/04 00:22:33 zoltan Exp $	*/
+/*	$NetBSD: frag6.c,v 1.51 2011/12/16 00:57:59 jakllsch Exp $	*/
 /*	$KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.50 2011/11/04 00:22:33 zoltan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.51 2011/12/16 00:57:59 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -644,10 +644,16 @@
 void
 frag6_fasttimo(void)
 {
+	mutex_enter(softnet_lock);
+	KERNEL_LOCK(1, NULL);
+
 	if (frag6_drainwanted) {
 		frag6_drain();
 		frag6_drainwanted = 0;
 	}
+
+	KERNEL_UNLOCK_ONE(NULL);
+	mutex_exit(softnet_lock);
 }
 
 /*
@@ -660,6 +666,9 @@
 {
 	struct ip6q *q6;
 
+	mutex_enter(softnet_lock);
+	KERNEL_LOCK(1, NULL);
+
 	mutex_enter(&frag6_lock);
 	q6 = ip6q.ip6q_next;
 	if (q6)
@@ -684,6 +693,9 @@
 		frag6_freef(ip6q.ip6q_prev);
 	}
 	mutex_exit(&frag6_lock);
+
+	KERNEL_UNLOCK_ONE(NULL);
+	mutex_exit(softnet_lock);
 
 #if 0
 	/*