Skip to content

Commit

Permalink
lib/checksum.c: fix carry in csum_tcpudp_nofold
Browse files Browse the repository at this point in the history
The carry from the 64->32bits folding was dropped, e.g with:
saddr=0xFFFFFFFF daddr=0xFF0000FF len=0xFFFF proto=0 sum=1,
csum_tcpudp_nofold returned 0 instead of 1.

Signed-off-by: Karl Beldan <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Mike Frysinger <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
kbeldan authored and davem330 committed Jan 29, 2015
1 parent 59ccaaa commit 150ae0e
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions lib/checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ static inline unsigned short from32to16(unsigned int x)
return x;
}

static inline u32 from64to32(u64 x)
{
/* add up 32-bit and 32-bit for 32+c bit */
x = (x & 0xffffffff) + (x >> 32);
/* add up carry.. */
x = (x & 0xffffffff) + (x >> 32);
return (u32)x;
}

static unsigned int do_csum(const unsigned char *buff, int len)
{
int odd;
Expand Down Expand Up @@ -195,8 +204,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
#else
s += (proto + len) << 8;
#endif
s += (s >> 32);
return (__force __wsum)s;
return (__force __wsum)from64to32(s);
}
EXPORT_SYMBOL(csum_tcpudp_nofold);
#endif

0 comments on commit 150ae0e

Please sign in to comment.