]>
Commit | Line | Data |
---|---|---|
9ad5c5a3 GKH |
1 | From 150ae0e94634714b23919f0c333fee28a5b199d5 Mon Sep 17 00:00:00 2001 |
2 | From: karl beldan <karl.beldan@gmail.com> | |
3 | Date: Wed, 28 Jan 2015 10:58:11 +0100 | |
4 | Subject: lib/checksum.c: fix carry in csum_tcpudp_nofold | |
5 | ||
6 | From: karl beldan <karl.beldan@gmail.com> | |
7 | ||
8 | commit 150ae0e94634714b23919f0c333fee28a5b199d5 upstream. | |
9 | ||
10 | The carry from the 64->32bits folding was dropped, e.g with: | |
11 | saddr=0xFFFFFFFF daddr=0xFF0000FF len=0xFFFF proto=0 sum=1, | |
12 | csum_tcpudp_nofold returned 0 instead of 1. | |
13 | ||
14 | Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com> | |
15 | Cc: Al Viro <viro@ZenIV.linux.org.uk> | |
16 | Cc: Eric Dumazet <eric.dumazet@gmail.com> | |
17 | Cc: Arnd Bergmann <arnd@arndb.de> | |
18 | Cc: Mike Frysinger <vapier@gentoo.org> | |
19 | Cc: netdev@vger.kernel.org | |
20 | Cc: linux-kernel@vger.kernel.org | |
21 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
22 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
24 | ||
25 | --- | |
26 | lib/checksum.c | 12 ++++++++++-- | |
27 | 1 file changed, 10 insertions(+), 2 deletions(-) | |
28 | ||
29 | --- a/lib/checksum.c | |
30 | +++ b/lib/checksum.c | |
31 | @@ -47,6 +47,15 @@ static inline unsigned short from32to16( | |
32 | return x; | |
33 | } | |
34 | ||
35 | +static inline u32 from64to32(u64 x) | |
36 | +{ | |
37 | + /* add up 32-bit and 32-bit for 32+c bit */ | |
38 | + x = (x & 0xffffffff) + (x >> 32); | |
39 | + /* add up carry.. */ | |
40 | + x = (x & 0xffffffff) + (x >> 32); | |
41 | + return (u32)x; | |
42 | +} | |
43 | + | |
44 | static unsigned int do_csum(const unsigned char *buff, int len) | |
45 | { | |
46 | int odd; | |
47 | @@ -195,8 +204,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, | |
48 | #else | |
49 | s += (proto + len) << 8; | |
50 | #endif | |
51 | - s += (s >> 32); | |
52 | - return (__force __wsum)s; | |
53 | + return (__force __wsum)from64to32(s); | |
54 | } | |
55 | EXPORT_SYMBOL(csum_tcpudp_nofold); | |
56 | #endif |