kernel/3319: hardware datagram checksumming vs. IP fragmentation >Number: 3319
>Category: kernel
>Synopsis: hardware checksum can cause good IP fragments to be dropped
>Confidential: no
Geoff Steckel, Owner gwes@oat.com
Omnivore Technology +1 617 332 9252
127 Cornell St.
Newton, MA 02462
>Environment:
i386/3.2 or i386/3.3 with DGE (possibly other interfaces)
System : OpenBSD 3.2
Architecture: OpenBSD.i386
Machine : i386
>Description:
The dge interface can perform hardware checksumming of incoming TCP
and UDP over IP packets. The higher level protocol's checksum is by
definition unknown until all fragments have been received. The
dge doesn't check ip_off. This causes essentially all
fragmented UDP datagrams to be dropped. Since many versions of TCP
attempt to avoid fragmentation, the problem is not as obvious.
The most obvious usage affected is NFS. It uses up to 8K or 32K
datagrams, which are always fragmented by ethernet-like physical
layers.
>How-To-Repeat:
On a client machine connected via a DGE interface,
NFS mount a file system containing a large directory.
Attempt to ls that directory.
The ls will never succeed, and the counters for IP hardware checksum
errors will increase for every NFS retransmit.
>Fix:
Since fragmentation is often a source of subtle bugs, the fix is
applied at the IP level, not in the driver. By definition the
driver cannot know the TCP or UDP checksum, so clear the bits
in m_pkthdr.csum for all incoming fragmented IP datagrams.
in 3.2 code base, at ip_input.c line 535, ipv4_input(m), just
after the label "ours:"
- Otherwise, nothing need be done.
- (We could look in the reassembly queue to see
- if the packet was previously fragmented,
- but it's not worth the time; just let them time out.)
*/
if (ip->ip_off &~ (IP_DF | IP_RF)) {
+ /* Don't believe hardware higher protocol checksum on fragments */
+ m->m_pkthdr.csum &=
+ ~ (M_TCP_CSUM_IN_OK | M_TCP_CSUM_IN_BAD
+ | M_UDP_CSUM_IN_OK | M_UDP_CSUM_IN_BAD);
if (m->m_flags & M_EXT) { /* XXX */
if ((m = m_pullup(m, hlen)) == NULL) {
ipstat.ips_toosmall++;
>Release-Note:
Received on Mon Jun 16 20:45:27 2003
This archive was generated by hypermail 2.1.8
: Wed Aug 23 2006 - 13:29:58 EDT
|