IPv4 checksum oddness (gcc compiler bug?)

Mike Bristow mike at urgle.com
Tue Aug 24 14:52:51 PDT 2004


I've been suffering from really horrid (~60-70%) packet loss for a while,
but only with IPv4.

I've spent some time thinking I had a hardware problem, as it started
at the same time as changed some networking bits but it doesn't
appear to be the case:  older (5.2.1) version of FreeBSD don't have
this problem.

I've just cvsuped to RELENG_5 box (cvsup'ed with tag=RELENG_5
date=2004., and with the attached patch I see
many entries like in my logs:

csum calc discrepancy: 45:10:00:64:b0:22:40:00:40:06:98:95:50:b1:28:36:50:b1:28:34
csum calc discrepancy: 45:10:00:84:b0:23:40:00:40:06:98:74:50:b1:28:36:50:b1:28:34

However, my patch is obviously wrong.  

The only thing that I can think of that might possibly be the cause
is a compiler optimization bug - but I'm not sure that that's the
case, either.  My make.conf is boring (http://www.urgle.com/~mike/make.conf
if you want to see its dullness).    I can't believe that this is
a real problem, rather than an artifact of my stupidity, because
if it was a real problem everyone with old PIIs would be screaming
the place down.   

Has anyone any ideas as to how to debug this?  

The kernel is GENERIC; possibly interesting other facts include:

hw.model: Pentium II/Pentium II Xeon/Celeron
hw.ncpu: 2
        inet netmask 0xfffffff0 broadcast
        inet6 fe80::280:c8ff:feea:8041%vr0 prefixlen 64 scopeid 0x1
        inet6 2002:50b1:2836:1:280:c8ff:feea:8041 prefixlen 64 autoconf
        ether 00:80:c8:ea:80:41
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active

--- ip_input.c.orig     Tue Aug 24 22:24:45 2004
+++ ip_input.c  Tue Aug 24 22:24:45 2004
@@ -366,6 +366,14 @@
        } else {
                if (hlen == sizeof(struct ip)) {
                        sum = in_cksum_hdr(ip);
+                       if (sum) {
+                               u_short sumchk;
+                               sumchk = in_cksum(m, hlen);
+                               if (!sumchk) {
+                                       printf("csum calc discrepancy: %20D\n", (u_char *)ip, ":");
+                                       sum = 0;
+                               }
+                       }
                } else {
                        sum = in_cksum(m, hlen);

You dont have to be illiterate to use the Internet, but it help's.

More information about the freebsd-current mailing list