NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-mips/43882: On special condition,you get incorrect TCP checksum.



> Apply following patch to sys/arch/mips/mips/in_cksum.c

BTW, human readable unified diff (by diff -u) is better in PRs.

> <               if (n < 3){
> <               /*
> <                * This code is for following condition.
> <                * (1)mbufs size is 2byte.
> <                * (2)align is not 32-bit-align.

Your analysis looks correct, but I don't think we have to
handle unaligned two byte payload as a special case.
It's enough to fix handlings for leading/trailing unaligned words/bytes.

How about this one? (untested)

Index: in_cksum.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/in_cksum.c,v
retrieving revision 1.13
diff -u -p -r1.13 in_cksum.c
--- in_cksum.c  24 Jan 2007 13:08:11 -0000      1.13
+++ in_cksum.c  15 Sep 2010 10:02:18 -0000
@@ -56,11 +56,10 @@ __KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v
 #include <machine/endian.h>
 
 union memptr {
-       unsigned int *i;
-       unsigned long *l;
-       unsigned long u;
-       unsigned short *s;
-       unsigned char *c;
+       uint32_t *l;
+       uintptr_t u;
+       uint16_t *s;
+       uint8_t *c;
 };
 
 static inline uint32_t fastsum(union memptr, int, unsigned int, int);
@@ -83,10 +82,6 @@ fastsum(union memptr buf, int n, unsigne
 
        /* Align to 32 bits. */
        if (buf.u & 0x3) {
-               /* Skip to the end for very small mbufs */
-               if (n < 3)
-                       goto verylittleleft;
-
                /*
                 * 16-bit-align.
                 * If buf is odd-byte-aligned, add the byte and toggle
@@ -107,6 +102,9 @@ fastsum(union memptr buf, int n, unsigne
                        n -= 1;
                        odd_aligned = !odd_aligned;
                }
+               /* Skip to the end for very small mbufs */
+               if (n <= 2)
+                       goto postunaligned;
 
                /* 32-bit-align */
                if (buf.u & 0x2) {
@@ -198,7 +196,7 @@ fastsum(union memptr buf, int n, unsigne
 
  notmuchleft:
        high = hilo = 0;
-       while (n >= 4) {
+       while (n >= sizeof(uint32_t)) {
                w0 = *(buf.l++);
                hilo += w0;
                high += w0 >> 16;
@@ -208,19 +206,21 @@ fastsum(union memptr buf, int n, unsigne
        sum += hilo;
        sum += high;
 
-       while (n > 1) {
-               n -= sizeof(*buf.s);
+ postunaligned:
+       /* handle post 32bit unaligned payloads */
+       if (n >= sizeof(uint16_t)) {
                sum += *(buf.s++);
+               n -= sizeof(uint16_t);
        }
 
- verylittleleft:
-       /* handle trailing byte and short (possibly) unaligned payloads */
-       while (n-- > 0) {
+       /* handle a trailing odd byte */
+       if (n > 0) {
 #if BYTE_ORDER == BIG_ENDIAN
                sum += *(buf.c++) << 8;
 #else
                sum += *(buf.c++);
 #endif
+               n = 0;
        }
 
        /*

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index