Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1d464c26b5625215c4b35fb336c8f3c57d248c2e
Commit:     1d464c26b5625215c4b35fb336c8f3c57d248c2e
Parent:     ba755f8ec80fdbf2b5212622eabf7355464c6327
Author:     Dave Johnson <[EMAIL PROTECTED]>
AuthorDate: Wed Apr 18 10:39:41 2007 -0400
Committer:  Ralf Baechle <[EMAIL PROTECTED]>
CommitDate: Fri Apr 20 14:58:37 2007 +0100

    [MIPS] Fix wrong checksum for split TCP packets on 64-bit MIPS
    
    I've traced down an off-by-one TCP checksum calculation error under
    the following conditions:
    
    1) The TCP code needs to split a full-sized packet due to a reduced
       MSS (typically due to the addition of TCP options mid-stream like
       SACK).
       _AND_
    2) The checksum of the 2nd fragment is larger than the checksum of the
       original packet.  After subtraction this results in a checksum for
       the 1st fragment with bits 16..31 set to 1. (this is ok)
       _AND_
    3) The checksum of the 1st fragment's TCP header plus the previously
       32bit checksum of the 1st fragment DOES NOT cause a 32bit overflow
       when added together.  This results in a checksum of the TCP header
       plus TCP data that still has the upper 16 bits as 1's.
       _THEN_
    4) The TCP+data checksum is added to the checksum of the pseudo IP
       header with csum_tcpudp_nofold() incorrectly (the bug).
    
    The problem is the checksum of the TCP+data is passed to
    csum_tcpudp_nofold() as an 32bit unsigned value, however the assembly
    code acts on it as if it is a 64bit unsigned value.
    
    This causes an incorrect 32->64bit extension if the sum has bit 31
    set.  The resulting checksum is off by one.
    
    This problems is data and TCP header dependent due to #2 and #3
    above so it doesn't occur on every TCP packet split.
    
    Signed-off-by: Dave Johnson <[EMAIL PROTECTED]>
    Signed-off-by: Ralf Baechle <[EMAIL PROTECTED]>
---
 include/asm-mips/checksum.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
index 20a81e1..290485a 100644
--- a/include/asm-mips/checksum.h
+++ b/include/asm-mips/checksum.h
@@ -166,7 +166,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr,
 #else
          "r" (proto + len),
 #endif
-         "r" (sum));
+         "r" ((__force unsigned long)sum));
 
        return sum;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to