summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDave Johnson <djohnson+linux-mips@sw.starentnetworks.com>2007-04-18 10:39:41 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-04-20 14:58:37 +0100
commit1d464c26b5625215c4b35fb336c8f3c57d248c2e (patch)
tree88316e8149c4125dbdb55ff90a4e8d45a024940b /arch
parentba755f8ec80fdbf2b5212622eabf7355464c6327 (diff)
downloadlwn-1d464c26b5625215c4b35fb336c8f3c57d248c2e.tar.gz
lwn-1d464c26b5625215c4b35fb336c8f3c57d248c2e.zip
[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 <djohnson+linux-mips@sw.starentnetworks.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
0 files changed, 0 insertions, 0 deletions