From mandrews@bit0.com  Sun Dec  5 21:22:13 2010
Return-Path: <mandrews@bit0.com>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 5E0F9106566B
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 Dec 2010 21:22:13 +0000 (UTC)
	(envelope-from mandrews@bit0.com)
Received: from magnum.bit0.com (magnum.bit0.com [207.246.88.226])
	by mx1.freebsd.org (Postfix) with ESMTP id 34F0F8FC1C
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 Dec 2010 21:22:13 +0000 (UTC)
Received: from magnum.int.bit0.com (localhost [127.0.0.1])
	by magnum.bit0.com (Postfix) with ESMTP id D1BC28222
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 Dec 2010 16:05:23 -0500 (EST)
Received: from magnum.bit0.com ([127.0.0.1])
	by magnum.int.bit0.com (magnum.int.bit0.com [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id V4gp2qtO5D2n for <FreeBSD-gnats-submit@freebsd.org>;
	Sun,  5 Dec 2010 16:05:21 -0500 (EST)
Received: from bat.int.bit0.com (bat.int.bit0.com [172.27.0.5])
	by magnum.bit0.com (Postfix) with ESMTP
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  5 Dec 2010 16:05:21 -0500 (EST)
Received: by bat.int.bit0.com (Postfix, from userid 502)
	id BF3A914B27; Sun,  5 Dec 2010 16:05:21 -0500 (EST)
Message-Id: <20101205210521.BF3A914B27@bat.int.bit0.com>
Date: Sun,  5 Dec 2010 16:05:21 -0500 (EST)
From: Mike Andrews <mandrews@bit0.com>
Reply-To: Mike Andrews <mandrews@bit0.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: tftpd (and likely other udp traffic) fails over em(4) unless rxcsum/txcsum disabled
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         152853
>Category:       kern
>Synopsis:       [em] tftpd (and likely other udp traffic) fails over em(4) unless rxcsum/txcsum disabled [regression]
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 05 21:30:08 UTC 2010
>Closed-Date:    
>Last-Modified:  Wed Oct 05 15:05:19 UTC 2011
>Originator:     Mike Andrews
>Release:        FreeBSD 8.2-PRERELEASE amd64
>Organization:
Fark, Inc
>Environment:
System: FreeBSD bat.int.bit0.com 8.2-PRERELEASE FreeBSD 8.2-PRERELEASE #20: Sat Nov 27 23:00:34 EST 2010 mandrews@bat.int.bit0.com:/usr/obj/usr/src/sys/BIT0 amd64


>Description:
	The tftp server in FreeBSD fails to send any packets -- when a write
	request comes in (in this example, from a Cisco IOS router), tcpdump
	shows that FreeBSD receives the write reqeust but then its tftp server
	never sends a single packet out in response, and the transfer never
	starts:

	Dec  5 14:22:29 <ftp.info> bat tftpd[453]: Filename: 'moat-confg'
	Dec  5 14:22:29 <ftp.info> bat tftpd[453]: Mode: 'octet'
	Dec  5 14:22:29 <ftp.info> bat tftpd[453]: 172.27.0.1: write request for //moat-confg: success
	Dec  5 14:22:34 <ftp.warn> bat tftpd[453]: Timeout #0 on DATA block 1
	Dec  5 14:22:39 <ftp.warn> bat tftpd[453]: Timeout #1 on DATA block 1
	Dec  5 14:22:44 <ftp.warn> bat tftpd[453]: Timeout #2 on DATA block 1
	Dec  5 14:22:49 <ftp.warn> bat tftpd[453]: Timeout #3 on DATA block 1
	Dec  5 14:22:54 <ftp.warn> bat tftpd[453]: Timeout #4 on DATA block 1
	Dec  5 14:22:59 <ftp.err> bat tftpd[453]: Timeout #5 on DATA block 1, giving up

	On a complete whim, I tried disabling TSO4, TXCSUM, and RXCSUM on the
	NIC, and to my surprise I found that disabling the latter two made the
	problem disappear.  TSO had no effect -- as you'd expect since tftp is
	UDP based :)

	I have not checked to see if this is em(4) specific or what other UDP
	based services it might affect.  It appears that DNS on the same system
	works fine...

>How-To-Repeat:
	On a system with an Intel gigabit NIC, start a tftp server (via inetd)
	and try to write a file to it.

>Fix:
	ifconfig em0 -rxcsum -txcsum

	(It doesn't appear you can turn just one or the other off.)


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon Dec 6 10:57:32 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=152853 

From: Petr Lampa <lampa@fit.vutbr.cz>
To: bug-followup@FreeBSD.org, mandrews@bit0.com
Cc: jfv@FreeBSD.org
Subject: Re: kern/152853: [em] tftpd (and likely other udp traffic) fails
 over em(4) unless rxcsum/txcsum disabled
Date: Tue, 18 Jan 2011 16:15:12 +0100

 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 
 Some folowup for kern/152853 with a patch.
 
 It seems that the current version of if_em.c (both CURRENT and STABLE8)
 with txcsum/rxcsum cannot send any UDP packet shorter then TCP header size. 
 The reason is suspicious m_pullup(m_head, poff + sizeof(struct tcphdr)) in 
 common packet em_xmit handling. I've moved this m_pullupi() call to required 
 branches further down and this fixed the issue (UDP ack from tftpd daemon 
 now ok). The code however needs some audit, repeated m_pullups are strange.
 
 Sincerely,
 Petr Lampa
 
 *** if_em.c.old	2011-01-18 15:52:21.000000000 +0100
 --- if_em.c	2011-01-18 15:58:11.000000000 +0100
 ***************
 *** 1820,1831 ****
   		}
   		ip = (struct ip *)(mtod(m_head, char *) + ip_off);
   		poff = ip_off + (ip->ip_hl << 2);
 - 		m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 - 		if (m_head == NULL) {
 - 			*m_headp = NULL;
 - 			return (ENOBUFS);
 - 		}
   		if (do_tso) {
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			/*
   			 * TSO workaround:
 --- 1820,1831 ----
   		}
   		ip = (struct ip *)(mtod(m_head, char *) + ip_off);
   		poff = ip_off + (ip->ip_hl << 2);
   		if (do_tso) {
 + 			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 + 			if (m_head == NULL) {
 + 				*m_headp = NULL;
 + 				return (ENOBUFS);
 + 			}
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			/*
   			 * TSO workaround:
 ***************
 *** 1849,1854 ****
 --- 1849,1859 ----
   			tp->th_sum = in_pseudo(ip->ip_src.s_addr,
   			    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
   		} else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
 + 			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 + 			if (m_head == NULL) {
 + 				*m_headp = NULL;
 + 				return (ENOBUFS);
 + 			}
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			m_head = m_pullup(m_head, poff + (tp->th_off << 2));
   			if (m_head == NULL) {
 
 -- 
 Computer Centre                             E-mail: lampa@fit.vutbr.cz
 Faculty of Information Technology           Web: http://www.fit.vutbr.cz/
 Brno University of Technology               Fax:  +420 54114-1270
 Bozetechova 2, 612 66 Brno, Czech Republic  Phone: +420 54114-1225
 
 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="if_em.patch"
 
 *** if_em.c.old	2011-01-18 15:52:21.000000000 +0100
 --- if_em.c	2011-01-18 15:58:11.000000000 +0100
 ***************
 *** 1820,1831 ****
   		}
   		ip = (struct ip *)(mtod(m_head, char *) + ip_off);
   		poff = ip_off + (ip->ip_hl << 2);
 - 		m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 - 		if (m_head == NULL) {
 - 			*m_headp = NULL;
 - 			return (ENOBUFS);
 - 		}
   		if (do_tso) {
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			/*
   			 * TSO workaround:
 --- 1820,1831 ----
   		}
   		ip = (struct ip *)(mtod(m_head, char *) + ip_off);
   		poff = ip_off + (ip->ip_hl << 2);
   		if (do_tso) {
 + 			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 + 			if (m_head == NULL) {
 + 				*m_headp = NULL;
 + 				return (ENOBUFS);
 + 			}
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			/*
   			 * TSO workaround:
 ***************
 *** 1849,1854 ****
 --- 1849,1859 ----
   			tp->th_sum = in_pseudo(ip->ip_src.s_addr,
   			    ip->ip_dst.s_addr, htons(IPPROTO_TCP));
   		} else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
 + 			m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 + 			if (m_head == NULL) {
 + 				*m_headp = NULL;
 + 				return (ENOBUFS);
 + 			}
   			tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
   			m_head = m_pullup(m_head, poff + (tp->th_off << 2));
   			if (m_head == NULL) {
 
 --y0ulUmNC+osPPQO6--

From: Eugene Grosbein <egrosbein@rdtc.ru>
To: bug-followup@FreeBSD.ORG
Cc: Jack F Vogel <jfv@FreeBSD.ORG>, net@FreeBSD.ORG
Subject: Re: kern/152853: [em] tftpd (and likely other udp traffic) fails
 over em(4) unless rxcsum/txcsum disabled
Date: Tue, 18 Jan 2011 22:00:54 +0600

 Hi!
 
 7.4-PRERELEASE is affected too. In short, tftp is broken in recent em(4) driver in all branches due to this bug. 8.1-RELEASE is not affected, 7.3 is fine too.
 
 Eugene Grosbein
>Unformatted:
