Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/mips/mips Fix wrong checksum calculations of 32 bit...



details:   https://anonhg.NetBSD.org/src/rev/e1338249014b
branches:  trunk
changeset: 757716:e1338249014b
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sat Sep 18 16:43:50 2010 +0000

description:
Fix wrong checksum calculations of 32 bit unaligned two byte payloads.
Analyzed in PR port-mips/43882, but applied slightly different patch.
Also put some changes for readability.

Note netbsd-5 doesn't use this MD version but netbsd-4 needs a pullup.
(though it's unclear if it's really faster even on modern aggressive gcc4)

diffstat:

 sys/arch/mips/mips/in_cksum.c |  34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)

diffs (91 lines):

diff -r bc1b2f88510e -r e1338249014b sys/arch/mips/mips/in_cksum.c
--- a/sys/arch/mips/mips/in_cksum.c     Sat Sep 18 15:49:25 2010 +0000
+++ b/sys/arch/mips/mips/in_cksum.c     Sat Sep 18 16:43:50 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in_cksum.c,v 1.13 2007/01/24 13:08:11 hubertf Exp $ */
+/* $NetBSD: in_cksum.c,v 1.14 2010/09/18 16:43:50 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1993 Regents of the University of California.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.13 2007/01/24 13:08:11 hubertf Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.14 2010/09/18 16:43:50 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -56,11 +56,10 @@
 #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 @@
 
        /* 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 @@
                        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 @@
 
  notmuchleft:
        high = hilo = 0;
-       while (n >= 4) {
+       while (n >= sizeof(uint32_t)) {
                w0 = *(buf.l++);
                hilo += w0;
                high += w0 >> 16;
@@ -208,19 +206,21 @@
        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;
        }
 
        /*



Home | Main Index | Thread Index | Old Index