Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jan 2011 15:20:12 GMT
From:      Petr Lampa <lampa@fit.vutbr.cz>
To:        freebsd-net@FreeBSD.org
Subject:   Re: kern/152853: [em] tftpd (and likely other udp traffic) fails over em(4) unless rxcsum/txcsum disabled
Message-ID:  <201101181520.p0IFKC6P001961@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/152853; it has been noted by GNATS.

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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101181520.p0IFKC6P001961>