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