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
    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)
    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.
    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,
          "r" (proto + len),
-         "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

Reply via email to