kern/143621: [patch] dummynet and vnet use results in panic

Gleb Kurtsou gleb.kurtsou at gmail.com
Sun Feb 7 00:10:02 UTC 2010


>Number:         143621
>Category:       kern
>Synopsis:       [patch] dummynet and vnet use results in panic
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Feb 07 00:10:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Gleb Kurtsou
>Release:        
>Organization:
>Environment:
FreeBSD sandbox9.vbox 8.0-STABLE FreeBSD 8.0-STABLE #0 r203554+7d4ae6d: Sun Feb  7 01:16:51 UTC 2010     root at sandbox9.vbox:/usr/obj/usr/src/sys/L2FILTER  amd64
>Description:
dummynet doesn't set current vnet in its taskqueue thread (dummynet_send).

Patch is against recent 8-STABLE, but the same problem appears in CURRENT (although patch needs to be applied by hand). Fix is also tested on layer2 traffic.

Bactrace:

#0  doadump () at pcpu.h:223
223	pcpu.h: No such file or directory.
	in pcpu.h
(kgdb) #0  doadump () at pcpu.h:223
#1  0xffffffff802cef25 in boot (howto=260)
    at /usr/src/sys/kern/kern_shutdown.c:416
#2  0xffffffff802cf3c9 in panic (fmt=Variable "fmt" is not available.
)
    at /usr/src/sys/kern/kern_shutdown.c:579
#3  0xffffffff804b7e73 in trap_fatal (frame=0xc, eva=Variable "eva" is not available.
)
    at /usr/src/sys/amd64/amd64/trap.c:857
#4  0xffffffff804b81d5 in trap_pfault (frame=0xffffff80001778a0, usermode=0)
    at /usr/src/sys/amd64/amd64/trap.c:773
#5  0xffffffff804b8a49 in trap (frame=0xffffff80001778a0)
    at /usr/src/sys/amd64/amd64/trap.c:499
#6  0xffffffff8049f943 in calltrap ()
    at /usr/src/sys/amd64/amd64/exception.S:224
#7  0xffffffff803885b6 in rt_tables_get_rnh (table=0, fam=2)
    at /usr/src/sys/net/route.c:151
#8  0xffffffff803889ff in rtalloc1_fib (dst=0xffffff8000177ad0, report=1, 
    ignflags=0, fibnum=Variable "fibnum" is not available.
) at /usr/src/sys/net/route.c:342
#9  0xffffffff8038a440 in rtalloc_ign_fib (ro=0xffffff8000177ac0, ignore=0, 
    fibnum=0) at /usr/src/sys/net/route.c:310
#10 0xffffffff803aec09 in ip_output (m=0xffffff0001305100, opt=Variable "opt" is not available.
)
    at /usr/src/sys/netinet/ip_output.c:269
#11 0xffffffff80c2324f in dummynet_send (m=0xffffff0001305100)
    at /usr/src/sys/modules/dummynet/../../netinet/ipfw/ip_dummynet.c:948
#12 0xffffffff80c2365f in dummynet_task (context=Variable "context" is not available.
)
    at /usr/src/sys/modules/dummynet/../../netinet/ipfw/ip_dummynet.c:930
#13 0xffffffff8030b01a in taskqueue_run (queue=0xffffff00017ba200)
    at /usr/src/sys/kern/subr_taskqueue.c:239
#14 0xffffffff8030b18c in taskqueue_thread_loop (arg=Variable "arg" is not available.
)
    at /usr/src/sys/kern/subr_taskqueue.c:360
#15 0xffffffff802a87aa in fork_exit (
    callout=0xffffffff8030b14d <taskqueue_thread_loop>, 
    arg=0xffffffff80c26e10, frame=0xffffff8000177c80)
    at /usr/src/sys/kern/kern_fork.c:843
#16 0xffffffff8049fd9e in fork_trampoline ()
    at /usr/src/sys/amd64/amd64/exception.S:561


>How-To-Repeat:

ipfw pipe config 100  bw 10kb
ipfw add 100 pipe 100 ip from any to any

Generate some traffic. Panics instantly

>Fix:


Patch attached with submission follows:

diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c
index e961a55..4c169f3 100644
--- a/sys/netinet/ipfw/ip_dummynet.c
+++ b/sys/netinet/ipfw/ip_dummynet.c
@@ -944,28 +944,49 @@ dummynet_send(struct mbuf *m)
 		m->m_nextpkt = NULL;
 		pkt = dn_tag_get(m);
 		switch (pkt->dn_dir) {
-		case DN_TO_IP_OUT:
-			ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
+		case DN_TO_IP_OUT: {
+				VNET_ASSERT(pkt->ifp != NULL);
+				CURVNET_SET(pkt->ifp->if_vnet);
+				ip_output(m, NULL, NULL, IP_FORWARDING,
+				    NULL, NULL);
+				CURVNET_RESTORE();
+			}
 			break ;
-		case DN_TO_IP_IN :
-			ip = mtod(m, struct ip *);
-			ip->ip_len = htons(ip->ip_len);
-			ip->ip_off = htons(ip->ip_off);
-			netisr_dispatch(NETISR_IP, m);
+		case DN_TO_IP_IN : {
+				VNET_ASSERT(m->m_pkthdr.rcvif != NULL);
+				CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
+				ip = mtod(m, struct ip *);
+				ip->ip_len = htons(ip->ip_len);
+				ip->ip_off = htons(ip->ip_off);
+				netisr_dispatch(NETISR_IP, m);
+				CURVNET_RESTORE();
+			}
 			break;
 #ifdef INET6
-		case DN_TO_IP6_IN:
-			netisr_dispatch(NETISR_IPV6, m);
+		case DN_TO_IP6_IN: {
+				VNET_ASSERT(m->m_pkthdr.rcvif != NULL);
+				CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
+				netisr_dispatch(NETISR_IPV6, m);
+				CURVNET_RESTORE();
+			}
 			break;
 
-		case DN_TO_IP6_OUT:
-			ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
+		case DN_TO_IP6_OUT: {
+				VNET_ASSERT(pkt->ifp != NULL);
+				CURVNET_SET(pkt->ifp->if_vnet);
+				ip6_output(m, NULL, NULL, IPV6_FORWARDING,
+				    NULL, NULL, NULL);
+				CURVNET_RESTORE();
+			}
 			break;
 #endif
 		case DN_TO_IFB_FWD:
-			if (bridge_dn_p != NULL)
+			if (bridge_dn_p != NULL) {
+				VNET_ASSERT(pkt->ifp != NULL);
+				CURVNET_SET(pkt->ifp->if_vnet);
 				((*bridge_dn_p)(m, pkt->ifp));
-			else
+				CURVNET_RESTORE();
+			} else
 				printf("dummynet: if_bridge not loaded\n");
 
 			break;
@@ -981,10 +1002,19 @@ dummynet_send(struct mbuf *m)
 				    "dropping packet\n");
 				break;
 			}
-			ether_demux(m->m_pkthdr.rcvif, m);
+			{
+				VNET_ASSERT(m->m_pkthdr.rcvif != NULL);
+				CURVNET_SET(m->m_pkthdr.rcvif->if_vnet);
+				ether_demux(m->m_pkthdr.rcvif, m);
+				CURVNET_RESTORE();
+			}
 			break;
-		case DN_TO_ETH_OUT:
-			ether_output_frame(pkt->ifp, m);
+		case DN_TO_ETH_OUT: {
+				VNET_ASSERT(pkt->ifp != NULL);
+				CURVNET_SET(pkt->ifp->if_vnet);
+				ether_output_frame(pkt->ifp, m);
+				CURVNET_RESTORE();
+			}
 			break;
 
 		case DN_TO_DROP:


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list