Date: Wed, 13 Jan 2016 20:10:29 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-net@FreeBSD.org Subject: [Bug 203524] TCP checksum failed on igb network adapter Message-ID: <bug-203524-2472-l3194MTNbK@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-203524-2472@https.bugs.freebsd.org/bugzilla/> References: <bug-203524-2472@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D203524 fodillemlinkarim@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |fodillemlinkarim@gmail.com --- Comment #2 from fodillemlinkarim@gmail.com --- Hi, I believe I have fixed something like this recently please see a post I just made: Hi, I've hit a very interesting problem with ipfw-nat and local TCP traffic that has enough TCP options to hit a special case in m_megapullup(). Here is the story: I am using the following NIC: igb0@pci0:4:0:0: class=3D0x020000 card=3D0x00008086 chip=3D0x150e808= 6 rev=3D0x01 hdr=3D0x00 And when I do ipfw nat to locally emitted packets I see packets not being processed in the igb driver for HW checksum. Now a quick search for m_pullu= p in the igb driver code will show that our igb driver expects a contiguous ethe= rnet + ip header in igb_tx_ctx_setup(). Now the friendly m_megapullup() in alias= .c doesn't reserve any space before the ip header for the ethernet header after its call to m_getcl like tcp_output.c (see m->m_data +=3D max_linkhdr in tcp_output.c). So the call to M_PREPEND() in ether_output() is forced to prepend a new mbuf for the ethernet header, leading to a non contiguous ether + ip. This in tu= rn leads to a failure to properly read the IP protocol in the igb driver and a= pply the proper HW checksum function. Particularly this call in igb_tcp_ctx_setu= p(): ip =3D (struct ip *)(mp->m_data + ehdrlen); To reproduce the issue I simply create a NAT rule for an igb interface and initiate a TCP connection locally going out through that interface (it shou= ld go through NAT obviously) something like: ipfw nat 1 config igb0 reset ipfw add 10 nat 1 via igb0 Although you need to make sure you fill enough of the SYN packet to trigger the allocation of new memory in m_megapullup. You can do this by using enou= gh TCP options so its filling up almost all of the 256 mbuf or make RESERVE something like 300 bytes in alias.c. The fix I propose is very simple and faster for all drivers, including the = ones that do perform a check for ether + ip to be contiguous upon accessing the = IP header. If the leading space is available it doesn't allocate any extra spa= ce (as it should for most cases) but if for some reason the mbuf used doesn't = have 100 bytes (RESERVE in megapullup) of free space it will reserve some at the front too. If the leading space isn't necessary then it won't cause any har= m. -Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c +Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c-dirty diff --git a/freebsd/sys/netinet/libalias/alias.c b/freebsd/sys/netinet/libalias/alias.c index 876e958..dc424a6 100644 --- a/freebsd/sys/netinet/libalias/alias.c +++ b/freebsd/sys/netinet/libalias/alias.c @@ -1757,7 +1757,8 @@ m_megapullup(struct mbuf *m, int len) { * writable and has some extra space for expansion. * XXX: Constant 100bytes is completely empirical. */ #define RESERVE 100 - if (m->m_next =3D=3D NULL && M_WRITABLE(m) && M_TRAILINGSPACE(m) >=3D R= ESERVE) + if (m->m_next =3D=3D NULL && M_WRITABLE(m) && + M_TRAILINGSPACE(m) >=3D RESERVE && M_LEADINGSPACE(m) >=3D max_linkhdr) return (m); if (len <=3D MCLBYTES - RESERVE) { @@ -1779,6 +1780,7 @@ m_megapullup(struct mbuf *m, int len) { goto bad; m_move_pkthdr(mcl, m); + mcl->m_data +=3D max_linkhdr; m_copydata(m, 0, len, mtod(mcl, caddr_t)); mcl->m_len =3D mcl->m_pkthdr.len =3D len; m_freem(m); It would be nice if some FBSD comitter could review and hopefully add this patch to FBSD. Thank you, Karim. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-203524-2472-l3194MTNbK>