Date: Sun, 7 Feb 2010 00:05:33 GMT From: Gleb Kurtsou <gleb.kurtsou@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/143621: [patch] dummynet and vnet use results in panic Message-ID: <201002070005.o1705Xe6081021@www.freebsd.org> Resent-Message-ID: <201002070010.o170A1tu034748@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002070005.o1705Xe6081021>