Date: Fri, 10 Jul 2009 22:54:35 -0500 From: kevin brintnall <kbrint@rufus.net> To: freebsd-net@freebsd.org Subject: panic on ip_input, ip_len byte ordering problem? Message-ID: <20090711035435.GA18298@rufus.net>
next in thread | raw e-mail | index | archive | help
Hi, Here is my system: FreeBSD fw.rufus.net 7.2-RELEASE-p1 FreeBSD 7.2-RELEASE-p1 #1: Wed Jun 10 11:32:28 CDT 2009 root@hamachi.rufus.net:/usr/obj/usr/src/sys/SOEKRIS i386 I am seeing occasional panics in ip_input when forwarding IP traffic at low rates (<100pkt/sec). Fatal trap 12: page fault while in kernel mode cpuid = 0; apic id = 00 fault virtual address = 0xc fault code = supervisor read, page not present instruction pointer = 0x20:0xc0872228 stack pointer = 0x28:0xc17f2b20 frame pointer = 0x28:0xc17f2b3c code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, def32 1, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 20 (irq10: sis0 sis1+) trap number = 12 panic: page fault cpuid = 0 Uptime: 12d10h48m45s Physical memory: 115 MB Dumping 49 MB: 34 18 2 Dump complete The stack trace is as follows: #5 0xc0b502cc in trap (frame=0xc17f2ae0) at /usr/src/sys/i386/i386/trap.c:530 #6 0xc0b342bb in calltrap () at /usr/src/sys/i386/i386/exception.s:159 #7 0xc0872228 in m_copydata (m=0x0, off=0, len=88, cp=0xc1aeb6a8 "some garbage") at /usr/src/sys/kern/uipc_mbuf.c:815 #8 0xc090a728 in ip_forward (m=0xc19f0700, srcrt=0) at /usr/src/sys/netinet/ip_input.c:1307 #9 0xc090bf0c in ip_input (m=0xc19f0700) at /usr/src/sys/netinet/ip_input.c:609 #10 0xc08c9fa5 in netisr_dispatch (num=2, m=0xc19f0700) at /usr/src/sys/net/netisr.c:185 m_copydata is walking off the end of the mbuf chain.. It turns out that the IP header length is incorrect. Here is the code from frame 8: 1304 if (mcopy != NULL) { 1305 mcopy->m_len = min(ip->ip_len, M_TRAILINGSPACE(mcopy)); 1306 mcopy->m_pkthdr.len = mcopy->m_len; 1307 m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t)); 1308 } The packet is 116 bytes, which is correctly reflected in the mbuf header. However, the IP packet length appears to be in network byte order rather than host byte order. Note that 29696=ntohs(116). (kgdb) p m->m_hdr->mh_len $55 = 116 (kgdb) p mcopy->m_hdr->mh_len $56 = 204 (kgdb) p ip->ip_len $57 = 29696 <<-- should be 116! The rest of the IP header looks correct: $58 = {ip_hl = 5, ip_v = 4, ip_tos = 16 '\020', ip_len = 29696, ip_id = 38700, ip_off = 64, ip_ttl = 58 ':', ip_p = 6 '\006', ip_sum = 5172, ip_src = { s_addr = X}, ip_dst = {s_addr = 1139586513}} When ip_input is initially called, I think the ip_len must be right.. Otherwise, the "tooshort" block around ip_input.c:383 would stop processing. if (m->m_pkthdr.len < ip->ip_len) { tooshort: ipstat.ips_tooshort++; goto bad; } Any ideas? My best guess is that there exists a code path in PF somewhere that is doing an uneven number of ntohs() and htons(). Thanks in advance! -- kevin brintnall =~ /kbrint@rufus.net/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090711035435.GA18298>