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.



The following reply was made to PR port-mips/43882; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: port-mips-maintainer%NetBSD.org@localhost, gnats-admin%NetBSD.org@localhost,
        netbsd-bugs%NetBSD.org@localhost, tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-mips/43882: On special condition,you get incorrect TCP 
checksum.
Date: Wed, 15 Sep 2010 19:14:43 +0900

 > 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