Commit 20db778e authored by David S. Miller's avatar David S. Miller

Merge branch 'ipv4-ipv6-csums'

Alexander Duyck says:

====================
Fix differences between IPv4 and IPv6 TCP/UDP checksum calculation

This patch series is meant to address the differences that exist between
IPv4 and IPv6 in terms of checksum calculation.  Specifically the IPv6
function csum_ipv6_magic treated length as a value that could be greater
than 64K, while csum_tcpudp_magic was truncating the length at 16 bits.
After looking over the code and giving it some thought I decided it would
be best to update the IPv4 function so that it worked the same way the IPv6
one did.  This allows us to get the same results given the same inputs for
both functions.  As a result we can use the same processes to reverse the
calculation in the event we need to do something like remove the length of
the pseudo-header checksum.

I also took the opportunity to standardize things so that the parameters
for these functions all use the correct types.  IPv4 addresses are __be32,
length should always be __u32, and protocol is a __u8.

With this change in place it corrects an issue with UDP tunnels in which we
were getting a checksum that was off by 1 when performing fragmentation on
inner UDP packets.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fbd40ea0 08334824
......@@ -13,14 +13,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum);
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum);
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len, unsigned short proto,
__wsum sum);
__u32 len, __u8 proto, __wsum sum);
/*
* computes the checksum of a memory block at buff, length len,
......@@ -70,6 +67,5 @@ static inline __sum16 csum_fold(__wsum csum)
#define _HAVE_ARCH_IPV6_CSUM
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum);
__u32 len, __u8 proto, __wsum sum);
#endif
......@@ -42,9 +42,7 @@ static inline unsigned short from64to16(unsigned long x)
* returns a 16-bit checksum, already complemented.
*/
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
......@@ -52,9 +50,7 @@ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
}
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
unsigned long result;
......
......@@ -70,8 +70,8 @@ ip_fast_csum(const void *iph, unsigned int ihl)
* SA [4], DA [4], zeroes [1], Proto[1], TCP Seg(hdr+data) Len [2]
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
__asm__ __volatile__(
" add.f %0, %0, %1 \n"
......
......@@ -84,10 +84,10 @@ ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
u32 lenprot = len | proto << 16;
u32 lenprot = len + proto;
if (__builtin_constant_p(sum) && sum == 0) {
__asm__(
"adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t"
......@@ -121,8 +121,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......@@ -144,8 +144,8 @@ __csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __
__be32 proto, __wsum sum);
static inline __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len,
unsigned short proto, __wsum sum)
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum)
{
return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
htonl(proto), sum));
......
......@@ -111,8 +111,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
asm(" add %0, %1\n"
......@@ -132,8 +131,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......
......@@ -14,8 +14,8 @@
*/
static inline __wsum
__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
unsigned int carry;
......
......@@ -10,8 +10,8 @@
#define _ASM_C6X_CHECKSUM_H
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
unsigned long long tmp;
......
......@@ -9,8 +9,8 @@
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
__wsum res;
__asm__ ("add.d %2, %0\n\t"
......
......@@ -11,7 +11,7 @@
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len, unsigned short proto, __wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
__wsum res;
......
......@@ -63,8 +63,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......
......@@ -105,8 +105,8 @@ static inline __sum16 csum_fold(__wsum sum)
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
asm(" addcc %1,%0,%0,icc0 \n"
" addxcc %2,%0,%0,icc0 \n"
......@@ -120,8 +120,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
......@@ -135,7 +135,7 @@ extern __sum16 ip_compute_csum(const void *buff, int len);
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
unsigned long tmp, tmp2;
......
......@@ -38,12 +38,12 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst,
* returns a 16-bit checksum, already complemented
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
unsigned short len, unsigned short proto, __wsum sum);
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum);
#define csum_tcpudp_magic csum_tcpudp_magic
__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
unsigned short len, unsigned short proto, __wsum sum);
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum);
#include <asm-generic/checksum.h>
......
......@@ -60,18 +60,16 @@ static inline unsigned short from64to16(u64 x)
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented.
*/
__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
unsigned short len, unsigned short proto,
__wsum sum)
__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
(__force u64)sum + ((len + proto) << 8));
}
__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
unsigned short len, unsigned short proto,
__wsum sum)
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum)
{
u64 result;
......
......@@ -16,15 +16,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* Computes the checksum of the TCP/UDP pseudo-header returns a 16-bit
* checksum, already complemented
*/
extern __sum16 csum_tcpudp_magic (__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum);
extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum);
extern __wsum csum_tcpudp_nofold (__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum);
extern __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto, __wsum sum);
/*
* Computes the checksum of a memory block at buff, length len,
......@@ -73,7 +69,7 @@ static inline __sum16 csum_fold(__wsum csum)
#define _HAVE_ARCH_IPV6_CSUM 1
struct in6_addr;
extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr, __u32 len, unsigned short proto,
__wsum csum);
const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum csum);
#endif /* _ASM_IA64_CHECKSUM_H */
......@@ -34,8 +34,8 @@ from64to16 (unsigned long x)
* returns a 16-bit checksum, already complemented.
*/
__sum16
csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return (__force __sum16)~from64to16(
(__force u64)saddr + (__force u64)daddr +
......@@ -45,8 +45,8 @@ csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len,
EXPORT_SYMBOL(csum_tcpudp_magic);
__wsum
csum_tcpudp_nofold (__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
unsigned long result;
......
......@@ -114,8 +114,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
#if defined(__LITTLE_ENDIAN)
......@@ -145,8 +144,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......
......@@ -117,7 +117,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
......
......@@ -59,8 +59,7 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
* returns a 16-bit checksum, already complemented
*/
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
unsigned long len_proto = (proto + len) << 8;
......@@ -78,8 +77,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......
......@@ -16,8 +16,8 @@
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
__asm__("add %0, %0, %1\n\t"
"addc %0, %0, %2\n\t"
......
......@@ -160,8 +160,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
#define ip_fast_csum ip_fast_csum
static inline __wsum csum_tcpudp_nofold(__be32 saddr,
__be32 daddr, unsigned short len, unsigned short proto,
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__(
......@@ -215,7 +215,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__wsum tmp;
......
......@@ -37,16 +37,11 @@ static inline __sum16 csum_fold(__wsum sum)
return (~sum) >> 16;
}
static inline __wsum csum_tcpudp_nofold(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto,
__wsum sum)
{
__wsum tmp;
tmp = (__wsum) ntohs(len) << 16;
tmp += (__wsum) proto << 8;
__wsum tmp = (__wsum)((len + proto) << 8);
asm(
" add %1,%0 \n"
......@@ -64,10 +59,8 @@ static inline __wsum csum_tcpudp_nofold(unsigned long saddr,
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(unsigned long saddr,
unsigned long daddr,
unsigned short len,
unsigned short proto,
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
......
......@@ -45,8 +45,7 @@ static inline __sum16 csum_fold(__wsum sum)
*/
#define csum_tcpudp_nofold csum_tcpudp_nofold
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__(
......@@ -60,7 +59,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
"cmpltu r8, %0, %3\n"
"add %0, %0, r8\n" /* add carry */
: "=r" (sum), "=r" (saddr)
: "r" (daddr), "r" ((ntohs(len) << 16) + (proto * 256)),
: "r" (daddr), "r" ((len + proto) << 8),
"0" (sum),
"1" (saddr)
: "r8");
......@@ -69,8 +68,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
}
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto, __wsum sum)
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......
......@@ -85,8 +85,7 @@ static inline __sum16 csum_fold(__wsum csum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__(
......@@ -104,8 +103,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......@@ -124,7 +122,7 @@ static inline __sum16 ip_compute_csum(const void *buf, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__ (
......
......@@ -91,8 +91,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
* returns a 32-bit checksum
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len, unsigned short proto,
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
__wsum sum)
{
__u32 csum = (__force __u32)sum;
......@@ -118,8 +117,7 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len, unsigned short proto,
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......
......@@ -127,10 +127,10 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
unsigned long tmp = (ntohs(len) << 16) + proto * 256;
unsigned long tmp = (len + proto) << 8;
__asm__ __volatile__(
".set volatile\n\t"
"add\t%0, %0, %2\n\t"
......@@ -161,8 +161,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......@@ -180,8 +180,7 @@ static inline unsigned short ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__(
".set\tvolatile\t\t\t# csum_ipv6_magic\n\t"
......
......@@ -115,8 +115,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
#ifdef __LITTLE_ENDIAN__
......@@ -142,8 +141,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
......@@ -161,8 +159,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
unsigned int __dummy;
__asm__("clrt\n\t"
......
......@@ -170,8 +170,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__("addcc\t%1, %0, %0\n\t"
......@@ -190,8 +189,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......@@ -201,8 +199,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__ (
"addcc %3, %4, %%g4\n\t"
......
......@@ -96,8 +96,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned int len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__ __volatile__(
......@@ -116,8 +115,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......@@ -127,8 +125,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
__asm__ __volatile__ (
" addcc %3, %4, %%g7\n"
......
......@@ -20,8 +20,8 @@
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
__asm__(
"add.a %0, %1, %2\n"
......
......@@ -112,8 +112,7 @@ static inline __sum16 csum_fold(__wsum sum)
}
static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
asm("addl %1, %0 ;\n"
......@@ -131,8 +130,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
......@@ -151,8 +149,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
asm("addl 0(%1), %0 ;\n"
"adcl 4(%1), %0 ;\n"
......
......@@ -84,8 +84,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
* 32bit unfolded.
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
asm(" addl %1, %0\n"
" adcl %2, %0\n"
......@@ -110,8 +110,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* complemented and ready to be filled in.
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto, __wsum sum)
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......@@ -177,7 +177,7 @@ struct in6_addr;
#define _HAVE_ARCH_IPV6_CSUM 1
extern __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum);
__u32 len, __u8 proto, __wsum sum);
static inline unsigned add32_with_carry(unsigned a, unsigned b)
{
......
......@@ -135,7 +135,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
__u64 rest, sum64;
......
......@@ -87,8 +87,8 @@ static inline __sum16 csum_fold(__wsum sum)
* 32bit unfolded.
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
asm(" addl %1, %0\n"
" adcl %2, %0\n"
......@@ -104,8 +104,7 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
* returns a 16-bit checksum, already complemented
*/
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......
......@@ -13,7 +13,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
__asm__(
......
......@@ -123,8 +123,7 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
}
static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
......@@ -157,8 +156,7 @@ static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
* returns a 16-bit checksum, already complemented
*/
static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
......@@ -177,7 +175,7 @@ static __inline__ __sum16 ip_compute_csum(const void *buff, int len)
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__u32 len, __u8 proto,
__wsum sum)
{
unsigned int __dummy;
......
......@@ -65,14 +65,14 @@ static inline __sum16 csum_fold(__wsum csum)
* returns a 16-bit checksum, already complemented
*/
extern __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum);
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum);
#endif
#ifndef csum_tcpudp_magic
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
......
......@@ -37,8 +37,7 @@
#ifndef _HAVE_ARCH_IPV6_CSUM
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum csum);
__u32 len, __u8 proto, __wsum csum);
#endif
static inline __wsum ip6_compute_pseudo(struct sk_buff *skb, int proto)
......
......@@ -191,9 +191,7 @@ static inline u32 from64to32(u64 x)
}
__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
unsigned short len,
unsigned short proto,
__wsum sum)
__u32 len, __u8 proto, __wsum sum)
{
unsigned long long s = (__force u32)sum;
......
......@@ -40,13 +40,19 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
__be16 protocol = skb->protocol;
u16 mac_len = skb->mac_len;
int udp_offset, outer_hlen;
u32 partial;
__wsum partial;
if (unlikely(!pskb_may_pull(skb, tnl_hlen)))
goto out;
/* adjust partial header checksum to negate old length */
partial = (__force u32)uh->check + (__force u16)~uh->len;
/* Adjust partial header checksum to negate old length.
* We cannot rely on the value contained in uh->len as it is
* possible that the actual value exceeds the boundaries of the
* 16 bit length field due to the header being added outside of an
* IP or IPv6 frame that was already limited to 64K - 1.
*/
partial = csum_sub(csum_unfold(uh->check),
(__force __wsum)htonl(skb->len));
/* setup inner skb. */
skb->encapsulation = 0;
......@@ -119,8 +125,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb,
if (!need_csum)
continue;
uh->check = ~csum_fold((__force __wsum)
((__force u32)len + partial));
uh->check = ~csum_fold(csum_add(partial, (__force __wsum)len));
if (skb->encapsulation || !offload_csum) {
uh->check = gso_make_checksum(skb, ~uh->check);
......
......@@ -6,8 +6,7 @@
#ifndef _HAVE_ARCH_IPV6_CSUM
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, unsigned short proto,
__wsum csum)
__u32 len, __u8 proto, __wsum csum)
{
int carry;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment