From a87cb3e48ee86d29868d3f59cfb9ce1a8fa63314 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Wed, 24 Feb 2016 10:02:52 -0800 Subject: net: Facility to report route quality of connected sockets This patch add the SO_CNX_ADVICE socket option (setsockopt only). The purpose is to allow an application to give feedback to the kernel about the quality of the network path for a connected socket. The value argument indicates the type of quality report. For this initial patch the only supported advice is a value of 1 which indicates "bad path, please reroute"-- the action taken by the kernel is to call dst_negative_advice which will attempt to choose a different ECMP route, reset the TX hash for flow label and UDP source port in encapsulation, etc. This facility should be useful for connected UDP sockets where only the application can provide any feedback about path quality. It could also be useful for TCP applications that have additional knowledge about the path outside of the normal TCP control loop. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- arch/sparc/include/uapi/asm/socket.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sparc') diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index d270ee91968e..31aede3af088 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -84,6 +84,8 @@ #define SO_ATTACH_REUSEPORT_CBPF 0x0035 #define SO_ATTACH_REUSEPORT_EBPF 0x0036 +#define SO_CNX_ADVICE 0x0037 + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 -- cgit v1.2.3 From 01cfbad79a5e2b835abf6a8154a341d75a6fc8cd Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 11 Mar 2016 14:05:34 -0800 Subject: ipv4: Update parameters for csum_tcpudp_magic to their original types This patch updates all instances of csum_tcpudp_magic and csum_tcpudp_nofold to reflect the types that are usually used as the source inputs. For example the protocol field is populated based on nexthdr which is actually an unsigned 8 bit value. The length is usually populated based on skb->len which is an unsigned integer. This addresses an issue in which the IPv6 function csum_ipv6_magic was generating a checksum using the full 32b of skb->len while csum_tcpudp_magic was only using the lower 16 bits. As a result we could run into issues when attempting to adjust the checksum as there was no protocol agnostic way to update it. With this change the value is still truncated as many architectures use "(len + proto) << 8", however this truncation only occurs for values greater than 16776960 in length and as such is unlikely to occur as we stop the inner headers at ~64K in size. I did have to make a few minor changes in the arm, mn10300, nios2, and score versions of the function in order to support these changes as they were either using things such as an OR to combine the protocol and length, or were using ntohs to convert the length which would have truncated the value. I also updated a few spots in terms of whitespace and type differences for the addresses. Most of this was just to make sure all of the definitions were in sync going forward. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- arch/alpha/include/asm/checksum.h | 9 +++------ arch/alpha/lib/checksum.c | 8 ++------ arch/arc/include/asm/checksum.h | 4 ++-- arch/arm/include/asm/checksum.h | 10 +++++----- arch/avr32/include/asm/checksum.h | 10 ++++------ arch/blackfin/include/asm/checksum.h | 4 ++-- arch/c6x/include/asm/checksum.h | 4 ++-- arch/cris/include/arch-v10/arch/checksum.h | 4 ++-- arch/cris/include/arch-v32/arch/checksum.h | 2 +- arch/cris/include/asm/checksum.h | 5 ++--- arch/frv/include/asm/checksum.h | 8 ++++---- arch/hexagon/include/asm/checksum.h | 8 ++++---- arch/hexagon/lib/checksum.c | 10 ++++------ arch/ia64/include/asm/checksum.h | 12 ++++-------- arch/ia64/lib/checksum.c | 8 ++++---- arch/m32r/include/asm/checksum.h | 10 ++++------ arch/metag/include/asm/checksum.h | 7 +++---- arch/microblaze/include/asm/checksum.h | 4 ++-- arch/mips/include/asm/checksum.h | 6 +++--- arch/mn10300/include/asm/checksum.h | 17 +++++------------ arch/nios2/include/asm/checksum.h | 9 ++++----- arch/parisc/include/asm/checksum.h | 10 ++++------ arch/s390/include/asm/checksum.h | 6 ++---- arch/score/include/asm/checksum.h | 10 +++++----- arch/sh/include/asm/checksum_32.h | 6 ++---- arch/sparc/include/asm/checksum_32.h | 10 ++++------ arch/sparc/include/asm/checksum_64.h | 6 ++---- arch/unicore32/include/asm/checksum.h | 4 ++-- arch/x86/include/asm/checksum_32.h | 6 ++---- arch/x86/include/asm/checksum_64.h | 8 ++++---- arch/x86/um/asm/checksum.h | 9 ++++----- arch/xtensa/include/asm/checksum.h | 10 ++++------ include/asm-generic/checksum.h | 8 ++++---- lib/checksum.c | 4 +--- 34 files changed, 106 insertions(+), 150 deletions(-) (limited to 'arch/sparc') diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h index d3854bbf0a9e..cba34b1c738c 100644 --- a/arch/alpha/include/asm/checksum.h +++ b/arch/alpha/include/asm/checksum.h @@ -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, diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c index 199f6efa83fa..377f9e34eb97 100644 --- a/arch/alpha/lib/checksum.c +++ b/arch/alpha/lib/checksum.c @@ -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; diff --git a/arch/arc/include/asm/checksum.h b/arch/arc/include/asm/checksum.h index 10957298b7a3..913eb4aab05b 100644 --- a/arch/arc/include/asm/checksum.h +++ b/arch/arc/include/asm/checksum.h @@ -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" diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 523315115478..42d020b7dfba 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -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)); } diff --git a/arch/avr32/include/asm/checksum.h b/arch/avr32/include/asm/checksum.h index 4ddbfd2486af..4ab7d5bdaf53 100644 --- a/arch/avr32/include/asm/checksum.h +++ b/arch/avr32/include/asm/checksum.h @@ -111,9 +111,8 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { asm(" add %0, %1\n" " adc %0, %0, %2\n" @@ -132,9 +131,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h index 623cc7fb00bc..e7134bf94e3c 100644 --- a/arch/blackfin/include/asm/checksum.h +++ b/arch/blackfin/include/asm/checksum.h @@ -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; diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h index 7246816d6e4d..249b0e421ddc 100644 --- a/arch/c6x/include/asm/checksum.h +++ b/arch/c6x/include/asm/checksum.h @@ -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; diff --git a/arch/cris/include/arch-v10/arch/checksum.h b/arch/cris/include/arch-v10/arch/checksum.h index b8000c5d7fe1..d1d1bd9e1090 100644 --- a/arch/cris/include/arch-v10/arch/checksum.h +++ b/arch/cris/include/arch-v10/arch/checksum.h @@ -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" diff --git a/arch/cris/include/arch-v32/arch/checksum.h b/arch/cris/include/arch-v32/arch/checksum.h index e5dcfce6e0dc..65cf205b1329 100644 --- a/arch/cris/include/arch-v32/arch/checksum.h +++ b/arch/cris/include/arch-v32/arch/checksum.h @@ -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; diff --git a/arch/cris/include/asm/checksum.h b/arch/cris/include/asm/checksum.h index 75dcb77d6cb0..ea949c60b190 100644 --- a/arch/cris/include/asm/checksum.h +++ b/arch/cris/include/asm/checksum.h @@ -63,9 +63,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h index 269da09ff637..cd59cd4fd2d9 100644 --- a/arch/frv/include/asm/checksum.h +++ b/arch/frv/include/asm/checksum.h @@ -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)); } diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h index 46ec8a7fd65f..d9f58d696238 100644 --- a/arch/hexagon/include/asm/checksum.h +++ b/arch/hexagon/include/asm/checksum.h @@ -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 diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c index 8169f78a46a7..617506d1a559 100644 --- a/arch/hexagon/lib/checksum.c +++ b/arch/hexagon/lib/checksum.c @@ -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; diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h index 97af155057e4..ac9c687e8384 100644 --- a/arch/ia64/include/asm/checksum.h +++ b/arch/ia64/include/asm/checksum.h @@ -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, diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c index 9fc955026f86..2cb23cb0c2e1 100644 --- a/arch/ia64/lib/checksum.c +++ b/arch/ia64/lib/checksum.c @@ -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; diff --git a/arch/m32r/include/asm/checksum.h b/arch/m32r/include/asm/checksum.h index a7a7c4f44abe..d68e93c9bd62 100644 --- a/arch/m32r/include/asm/checksum.h +++ b/arch/m32r/include/asm/checksum.h @@ -114,9 +114,8 @@ 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) + __u32 len, __u8 proto, + __wsum sum) { #if defined(__LITTLE_ENDIAN) unsigned long len_proto = (proto + len) << 8; @@ -145,9 +144,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/metag/include/asm/checksum.h b/arch/metag/include/asm/checksum.h index 08dd1cc65799..f65fe83b1730 100644 --- a/arch/metag/include/asm/checksum.h +++ b/arch/metag/include/asm/checksum.h @@ -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)); } diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h index 0185cbefdda4..adeecebbb0d1 100644 --- a/arch/microblaze/include/asm/checksum.h +++ b/arch/microblaze/include/asm/checksum.h @@ -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" diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index 3ceacde5eb6e..c635541d40b8 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -160,9 +160,9 @@ 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, - __wsum sum) +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, + __wsum sum) { __asm__( " .set push # csum_tcpudp_nofold\n" diff --git a/arch/mn10300/include/asm/checksum.h b/arch/mn10300/include/asm/checksum.h index 9fb2a8d8826a..c80df5b504ac 100644 --- a/arch/mn10300/include/asm/checksum.h +++ b/arch/mn10300/include/asm/checksum.h @@ -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)); diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h index 6bc1f0d5df7b..703c5ee63421 100644 --- a/arch/nios2/include/asm/checksum.h +++ b/arch/nios2/include/asm/checksum.h @@ -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)); } diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index c84b2fcb18a9..9815ab1fc8aa 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -85,9 +85,8 @@ static inline __sum16 csum_fold(__wsum csum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { __asm__( " add %1, %0, %0\n" @@ -104,9 +103,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index 740364856355..d7f100c53f07 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -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)); diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h index 961bd64015a8..a375bc2700be 100644 --- a/arch/score/include/asm/checksum.h +++ b/arch/score/include/asm/checksum.h @@ -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)); } diff --git a/arch/sh/include/asm/checksum_32.h b/arch/sh/include/asm/checksum_32.h index 14b7ac2f0a07..fd730f140c06 100644 --- a/arch/sh/include/asm/checksum_32.h +++ b/arch/sh/include/asm/checksum_32.h @@ -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)); diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h index 426b2389a1c2..86ae655a3c0f 100644 --- a/arch/sparc/include/asm/checksum_32.h +++ b/arch/sparc/include/asm/checksum_32.h @@ -170,9 +170,8 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { __asm__ __volatile__("addcc\t%1, %0, %0\n\t" "addxcc\t%2, %0, %0\n\t" @@ -190,9 +189,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h index b8779a6a5911..ef0c6f48189a 100644 --- a/arch/sparc/include/asm/checksum_64.h +++ b/arch/sparc/include/asm/checksum_64.h @@ -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)); diff --git a/arch/unicore32/include/asm/checksum.h b/arch/unicore32/include/asm/checksum.h index f55c3f937c3e..23ceb9e3a89b 100644 --- a/arch/unicore32/include/asm/checksum.h +++ b/arch/unicore32/include/asm/checksum.h @@ -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" diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index f50de6951738..6f380605403d 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h @@ -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)); diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index cd00e1774491..97b98e2039bc 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h @@ -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)); } diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h index ee940185e89f..54d96f1e3594 100644 --- a/arch/x86/um/asm/checksum.h +++ b/arch/x86/um/asm/checksum.h @@ -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,9 +104,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) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index 0593de689b56..62254e6688f5 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -123,9 +123,8 @@ 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) + __u32 len, __u8 proto, + __wsum sum) { #ifdef __XTENSA_EL__ @@ -157,9 +156,8 @@ 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, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/include/asm-generic/checksum.h b/include/asm-generic/checksum.h index 59811df58c5b..3150cbd8eb21 100644 --- a/include/asm-generic/checksum.h +++ b/include/asm-generic/checksum.h @@ -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)); } diff --git a/lib/checksum.c b/lib/checksum.c index 8b39e86dbab5..d3ec93f9e5f3 100644 --- a/lib/checksum.c +++ b/lib/checksum.c @@ -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; -- cgit v1.2.3 From 1e94082963747b551b129528714827f76a090e93 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 11 Mar 2016 14:05:41 -0800 Subject: ipv6: Pass proto to csum_ipv6_magic as __u8 instead of unsigned short This patch updates csum_ipv6_magic so that it correctly recognizes that protocol is a unsigned 8 bit value. This will allow us to better understand what limitations may or may not be present in how we handle the data. For example there are a number of places that call htonl on the protocol value. This is likely not necessary and can be replaced with a multiplication by ntohl(1) which will be converted to a shift by the compiler. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- arch/alpha/include/asm/checksum.h | 3 +-- arch/arm/include/asm/checksum.h | 4 ++-- arch/frv/include/asm/checksum.h | 2 +- arch/ia64/include/asm/checksum.h | 4 ++-- arch/m68k/include/asm/checksum.h | 2 +- arch/mips/include/asm/checksum.h | 2 +- arch/parisc/include/asm/checksum.h | 2 +- arch/score/include/asm/checksum.h | 5 ++--- arch/sh/include/asm/checksum_32.h | 3 +-- arch/sparc/include/asm/checksum_32.h | 3 +-- arch/sparc/include/asm/checksum_64.h | 3 +-- arch/x86/include/asm/checksum_32.h | 3 +-- arch/x86/include/asm/checksum_64.h | 2 +- arch/x86/lib/csum-wrappers_64.c | 2 +- arch/x86/um/asm/checksum_32.h | 2 +- arch/xtensa/include/asm/checksum.h | 2 +- include/net/ip6_checksum.h | 3 +-- net/ipv6/ip6_checksum.c | 3 +-- 18 files changed, 21 insertions(+), 29 deletions(-) (limited to 'arch/sparc') diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h index cba34b1c738c..f2bbdd2ace51 100644 --- a/arch/alpha/include/asm/checksum.h +++ b/arch/alpha/include/asm/checksum.h @@ -67,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 diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 42d020b7dfba..524692f4acab 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -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)); diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h index cd59cd4fd2d9..b77388c5901d 100644 --- a/arch/frv/include/asm/checksum.h +++ b/arch/frv/include/asm/checksum.h @@ -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; diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h index ac9c687e8384..7accf54162b2 100644 --- a/arch/ia64/include/asm/checksum.h +++ b/arch/ia64/include/asm/checksum.h @@ -69,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 */ diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 2f88d867c711..75e91f03b178 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -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" diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index c635541d40b8..bce1ce53149a 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -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; diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index 9815ab1fc8aa..60c2c42619c9 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -122,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__ ( diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h index a375bc2700be..539d9fd45d21 100644 --- a/arch/score/include/asm/checksum.h +++ b/arch/score/include/asm/checksum.h @@ -179,9 +179,8 @@ 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) + const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__( ".set\tvolatile\t\t\t# csum_ipv6_magic\n\t" diff --git a/arch/sh/include/asm/checksum_32.h b/arch/sh/include/asm/checksum_32.h index fd730f140c06..9c84386d35cb 100644 --- a/arch/sh/include/asm/checksum_32.h +++ b/arch/sh/include/asm/checksum_32.h @@ -159,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" diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h index 86ae655a3c0f..eff748c871ec 100644 --- a/arch/sparc/include/asm/checksum_32.h +++ b/arch/sparc/include/asm/checksum_32.h @@ -199,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" diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h index ef0c6f48189a..0395d75322e9 100644 --- a/arch/sparc/include/asm/checksum_64.h +++ b/arch/sparc/include/asm/checksum_64.h @@ -125,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" diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index 6f380605403d..532f85e6651f 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h @@ -149,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" diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index 97b98e2039bc..c020ee75dce7 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h @@ -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) { diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 1318f75d56e4..28a6654f0d08 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -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; diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h index ab77b6f9a4bf..83a75f8a1233 100644 --- a/arch/x86/um/asm/checksum_32.h +++ b/arch/x86/um/asm/checksum_32.h @@ -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__( diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index 62254e6688f5..ec35074fcb03 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -175,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; diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h index 1a49b73f7f6e..cca840584c88 100644 --- a/include/net/ip6_checksum.h +++ b/include/net/ip6_checksum.h @@ -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) diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c index 8f920580976f..b2025bf3da4a 100644 --- a/net/ipv6/ip6_checksum.c +++ b/net/ipv6/ip6_checksum.c @@ -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; -- cgit v1.2.3 From 5d01fa0c6bd84ddf1339a3fadfefecd2c28d472e Mon Sep 17 00:00:00 2001 From: Aaron Young Date: Tue, 15 Mar 2016 11:35:39 -0700 Subject: ldmvsw: Add ldmvsw.c driver code Add ldmvsw.c driver Details: The ldmvsw driver very closely follows the sunvnet.c code and makes use of the sunvnet_common.c code for core functionality. A significant difference between sunvnet and ldmvsw driver is sunvnet creates a network interface for each vnet-port *parent* node in the MD while the ldmvsw driver creates a network interface for every vsw-port node in the Machine Description (MD). Therefore the netdev_priv() for sunvnet is a vnet structure while the netdev_priv() for ldmvsw is a vnet_port structure. Vnet_port structures allocated by ldmvsw have the vsw bit set. When finding the net_device associated with a port, the common code keys off this bit to use either the net_device found in the vnet_port or the net_device in the vnet structure (see the VNET_PORT_TO_NET_DEVICE() macro in sunvnet_common.h). This scheme allows the common code to work with both drivers with minimal changes. Similar to Xen, network interfaces created by the ldmvsw driver will always have a HW Addr (i.e. mac address) of FE:FF:FF:FF:FF:FF and each will be assigned the devname "vif." - where and are a unique handle/port pair assigned to the associated vsw-port node in the MD. Signed-off-by: Aaron Young Signed-off-by: Rashmi Narasimhan Reviewed-by: Sowmini Varadhan Reviewed-by: Alexandre Chartre Signed-off-by: David S. Miller --- arch/sparc/configs/sparc64_defconfig | 1 + drivers/net/ethernet/sun/Kconfig | 11 + drivers/net/ethernet/sun/Makefile | 1 + drivers/net/ethernet/sun/ldmvsw.c | 468 +++++++++++++++++++++++++++++++++++ 4 files changed, 481 insertions(+) create mode 100644 drivers/net/ethernet/sun/ldmvsw.c (limited to 'arch/sparc') diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 6b68f12f29db..04920ab8e292 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -102,6 +102,7 @@ CONFIG_SUNLANCE=m CONFIG_HAPPYMEAL=m CONFIG_SUNGEM=m CONFIG_SUNVNET=m +CONFIG_LDMVSW=m CONFIG_NET_PCI=y CONFIG_E1000=m CONFIG_E1000E=m diff --git a/drivers/net/ethernet/sun/Kconfig b/drivers/net/ethernet/sun/Kconfig index aa58c11ea6db..a4b40e3015e5 100644 --- a/drivers/net/ethernet/sun/Kconfig +++ b/drivers/net/ethernet/sun/Kconfig @@ -80,6 +80,17 @@ config SUNVNET ---help--- Support for virtual network devices under Sun Logical Domains. +config LDMVSW + tristate "Sun4v LDoms Virtual Switch support" + depends on SUN_LDOMS + ---help--- + Support for virtual switch devices under Sun4v Logical Domains. + This driver adds a network interface for every vsw-port node + found in the machine description of a service domain. + Linux bridge/switch software can use these interfaces for + guest domain network interconnectivity or guest domain + connection to a physical network on a service domain. + config NIU tristate "Sun Neptune 10Gbit Ethernet support" depends on PCI diff --git a/drivers/net/ethernet/sun/Makefile b/drivers/net/ethernet/sun/Makefile index 7b622aa14c5b..37855438b3cb 100644 --- a/drivers/net/ethernet/sun/Makefile +++ b/drivers/net/ethernet/sun/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_SUNGEM) += sungem.o obj-$(CONFIG_CASSINI) += cassini.o obj-$(CONFIG_SUNVNET_COMMON) += sunvnet_common.o obj-$(CONFIG_SUNVNET) += sunvnet.o +obj-$(CONFIG_LDMVSW) += ldmvsw.o obj-$(CONFIG_NIU) += niu.o diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c new file mode 100644 index 000000000000..e15bf84fc6b2 --- /dev/null +++ b/drivers/net/ethernet/sun/ldmvsw.c @@ -0,0 +1,468 @@ +/* ldmvsw.c: Sun4v LDOM Virtual Switch Driver. + * + * Copyright (C) 2016 Oracle. All rights reserved. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_IPV6) +#include +#endif + +#include +#include +#include + +#include +#include + +/* This driver makes use of the common code in sunvnet_common.c */ +#include "sunvnet_common.h" + +/* Length of time before we decide the hardware is hung, + * and dev->tx_timeout() should be called to fix the problem. + */ +#define VSW_TX_TIMEOUT (10 * HZ) + +/* Static HW Addr used for the network interfaces representing vsw ports */ +static u8 vsw_port_hwaddr[ETH_ALEN] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +#define DRV_MODULE_NAME "ldmvsw" +#define DRV_MODULE_VERSION "1.0" +#define DRV_MODULE_RELDATE "Jan 15, 2016" + +static char version[] = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; +MODULE_AUTHOR("Oracle"); +MODULE_DESCRIPTION("Sun4v LDOM Virtual Switch Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +/* Ordered from largest major to lowest */ +static struct vio_version vsw_versions[] = { + { .major = 1, .minor = 8 }, + { .major = 1, .minor = 7 }, + { .major = 1, .minor = 6 }, + { .major = 1, .minor = 0 }, +}; + +static void vsw_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); + strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); +} + +static u32 vsw_get_msglevel(struct net_device *dev) +{ + struct vnet_port *port = netdev_priv(dev); + + return port->vp->msg_enable; +} + +static void vsw_set_msglevel(struct net_device *dev, u32 value) +{ + struct vnet_port *port = netdev_priv(dev); + + port->vp->msg_enable = value; +} + +static const struct ethtool_ops vsw_ethtool_ops = { + .get_drvinfo = vsw_get_drvinfo, + .get_msglevel = vsw_get_msglevel, + .set_msglevel = vsw_set_msglevel, + .get_link = ethtool_op_get_link, +}; + +static LIST_HEAD(vnet_list); +static DEFINE_MUTEX(vnet_list_mutex); + +/* func arg to vnet_start_xmit_common() to get the proper tx port */ +static struct vnet_port *vsw_tx_port_find(struct sk_buff *skb, + struct net_device *dev) +{ + struct vnet_port *port = netdev_priv(dev); + + return port; +} + +static u16 vsw_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct vnet_port *port = netdev_priv(dev); + + if (!port) + return 0; + + return port->q_index; +} + +/* Wrappers to common functions */ +static int vsw_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + return sunvnet_start_xmit_common(skb, dev, vsw_tx_port_find); +} + +static void vsw_set_rx_mode(struct net_device *dev) +{ + struct vnet_port *port = netdev_priv(dev); + + return sunvnet_set_rx_mode_common(dev, port->vp); +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void vsw_poll_controller(struct net_device *dev) +{ + struct vnet_port *port = netdev_priv(dev); + + return sunvnet_poll_controller_common(dev, port->vp); +} +#endif + +static const struct net_device_ops vsw_ops = { + .ndo_open = sunvnet_open_common, + .ndo_stop = sunvnet_close_common, + .ndo_set_rx_mode = vsw_set_rx_mode, + .ndo_set_mac_address = sunvnet_set_mac_addr_common, + .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = sunvnet_tx_timeout_common, + .ndo_change_mtu = sunvnet_change_mtu_common, + .ndo_start_xmit = vsw_start_xmit, + .ndo_select_queue = vsw_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = vsw_poll_controller, +#endif +}; + +static const char *local_mac_prop = "local-mac-address"; +static const char *cfg_handle_prop = "cfg-handle"; + +static struct vnet *vsw_get_vnet(struct mdesc_handle *hp, + u64 port_node, + u64 *handle) +{ + struct vnet *vp; + struct vnet *iter; + const u64 *local_mac = NULL; + const u64 *cfghandle = NULL; + u64 a; + + /* Get the parent virtual-network-switch macaddr and cfghandle */ + mdesc_for_each_arc(a, hp, port_node, MDESC_ARC_TYPE_BACK) { + u64 target = mdesc_arc_target(hp, a); + const char *name; + + name = mdesc_get_property(hp, target, "name", NULL); + if (!name || strcmp(name, "virtual-network-switch")) + continue; + + local_mac = mdesc_get_property(hp, target, + local_mac_prop, NULL); + cfghandle = mdesc_get_property(hp, target, + cfg_handle_prop, NULL); + break; + } + if (!local_mac || !cfghandle) + return ERR_PTR(-ENODEV); + + /* find or create associated vnet */ + vp = NULL; + mutex_lock(&vnet_list_mutex); + list_for_each_entry(iter, &vnet_list, list) { + if (iter->local_mac == *local_mac) { + vp = iter; + break; + } + } + + if (!vp) { + vp = kzalloc(sizeof(*vp), GFP_KERNEL); + if (unlikely(!vp)) { + mutex_unlock(&vnet_list_mutex); + return ERR_PTR(-ENOMEM); + } + + spin_lock_init(&vp->lock); + INIT_LIST_HEAD(&vp->port_list); + INIT_LIST_HEAD(&vp->list); + vp->local_mac = *local_mac; + list_add(&vp->list, &vnet_list); + } + + mutex_unlock(&vnet_list_mutex); + + *handle = (u64)*cfghandle; + + return vp; +} + +static struct net_device *vsw_alloc_netdev(u8 hwaddr[], + struct vio_dev *vdev, + u64 handle, + u64 port_id) +{ + struct net_device *dev; + struct vnet_port *port; + int i; + + dev = alloc_etherdev_mqs(sizeof(*port), VNET_MAX_TXQS, 1); + if (!dev) + return ERR_PTR(-ENOMEM); + dev->needed_headroom = VNET_PACKET_SKIP + 8; + dev->needed_tailroom = 8; + + for (i = 0; i < ETH_ALEN; i++) { + dev->dev_addr[i] = hwaddr[i]; + dev->perm_addr[i] = dev->dev_addr[i]; + } + + sprintf(dev->name, "vif%d.%d", (int)handle, (int)port_id); + + dev->netdev_ops = &vsw_ops; + dev->ethtool_ops = &vsw_ethtool_ops; + dev->watchdog_timeo = VSW_TX_TIMEOUT; + + dev->hw_features = NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GSO_SOFTWARE | + NETIF_F_HW_CSUM | NETIF_F_SG; + dev->features = dev->hw_features; + + SET_NETDEV_DEV(dev, &vdev->dev); + + return dev; +} + +static struct ldc_channel_config vsw_ldc_cfg = { + .event = sunvnet_event_common, + .mtu = 64, + .mode = LDC_MODE_UNRELIABLE, +}; + +static struct vio_driver_ops vsw_vio_ops = { + .send_attr = sunvnet_send_attr_common, + .handle_attr = sunvnet_handle_attr_common, + .handshake_complete = sunvnet_handshake_complete_common, +}; + +static void print_version(void) +{ + printk_once(KERN_INFO "%s", version); +} + +static const char *remote_macaddr_prop = "remote-mac-address"; +static const char *id_prop = "id"; + +static int vsw_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + struct mdesc_handle *hp; + struct vnet_port *port; + unsigned long flags; + struct vnet *vp; + struct net_device *dev; + const u64 *rmac; + int len, i, err; + const u64 *port_id; + u64 handle; + + print_version(); + + hp = mdesc_grab(); + + rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); + err = -ENODEV; + if (!rmac) { + pr_err("Port lacks %s property\n", remote_macaddr_prop); + mdesc_release(hp); + return err; + } + + port_id = mdesc_get_property(hp, vdev->mp, id_prop, NULL); + err = -ENODEV; + if (!port_id) { + pr_err("Port lacks %s property\n", id_prop); + mdesc_release(hp); + return err; + } + + /* Get (or create) the vnet associated with this port */ + vp = vsw_get_vnet(hp, vdev->mp, &handle); + if (unlikely(IS_ERR(vp))) { + err = PTR_ERR(vp); + pr_err("Failed to get vnet for vsw-port\n"); + mdesc_release(hp); + return err; + } + + mdesc_release(hp); + + dev = vsw_alloc_netdev(vsw_port_hwaddr, vdev, handle, *port_id); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + pr_err("Failed to alloc netdev for vsw-port\n"); + return err; + } + + port = netdev_priv(dev); + + INIT_LIST_HEAD(&port->list); + + for (i = 0; i < ETH_ALEN; i++) + port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff; + + port->vp = vp; + port->dev = dev; + port->switch_port = 1; + port->tso = true; + port->tsolen = 0; + + /* Mark the port as belonging to ldmvsw which directs the + * the common code to use the net_device in the vnet_port + * rather than the net_device in the vnet (which is used + * by sunvnet). This bit is used by the VNET_PORT_TO_NET_DEVICE + * macro. + */ + port->vsw = 1; + + err = vio_driver_init(&port->vio, vdev, VDEV_NETWORK, + vsw_versions, ARRAY_SIZE(vsw_versions), + &vsw_vio_ops, dev->name); + if (err) + goto err_out_free_dev; + + err = vio_ldc_alloc(&port->vio, &vsw_ldc_cfg, port); + if (err) + goto err_out_free_dev; + + dev_set_drvdata(&vdev->dev, port); + + netif_napi_add(dev, &port->napi, sunvnet_poll_common, + NAPI_POLL_WEIGHT); + + spin_lock_irqsave(&vp->lock, flags); + list_add_rcu(&port->list, &vp->port_list); + spin_unlock_irqrestore(&vp->lock, flags); + + setup_timer(&port->clean_timer, sunvnet_clean_timer_expire_common, + (unsigned long)port); + + err = register_netdev(dev); + if (err) { + pr_err("Cannot register net device, aborting\n"); + goto err_out_del_timer; + } + + spin_lock_irqsave(&vp->lock, flags); + sunvnet_port_add_txq_common(port); + spin_unlock_irqrestore(&vp->lock, flags); + + napi_enable(&port->napi); + vio_port_up(&port->vio); + + netdev_info(dev, "LDOM vsw-port %pM\n", dev->dev_addr); + + pr_info("%s: PORT ( remote-mac %pM%s )\n", dev->name, + port->raddr, " switch-port"); + + return 0; + +err_out_del_timer: + del_timer_sync(&port->clean_timer); + list_del_rcu(&port->list); + synchronize_rcu(); + netif_napi_del(&port->napi); + dev_set_drvdata(&vdev->dev, NULL); + vio_ldc_free(&port->vio); + +err_out_free_dev: + free_netdev(dev); + return err; +} + +static int vsw_port_remove(struct vio_dev *vdev) +{ + struct vnet_port *port = dev_get_drvdata(&vdev->dev); + unsigned long flags; + + if (port) { + del_timer_sync(&port->vio.timer); + + napi_disable(&port->napi); + + list_del_rcu(&port->list); + + synchronize_rcu(); + del_timer_sync(&port->clean_timer); + spin_lock_irqsave(&port->vp->lock, flags); + sunvnet_port_rm_txq_common(port); + spin_unlock_irqrestore(&port->vp->lock, flags); + netif_napi_del(&port->napi); + sunvnet_port_free_tx_bufs_common(port); + vio_ldc_free(&port->vio); + + dev_set_drvdata(&vdev->dev, NULL); + + unregister_netdev(port->dev); + free_netdev(port->dev); + } + + return 0; +} + +static void vsw_cleanup(void) +{ + struct vnet *vp; + + /* just need to free up the vnet list */ + mutex_lock(&vnet_list_mutex); + while (!list_empty(&vnet_list)) { + vp = list_first_entry(&vnet_list, struct vnet, list); + list_del(&vp->list); + /* vio_unregister_driver() should have cleaned up port_list */ + if (!list_empty(&vp->port_list)) + pr_err("Ports not removed by VIO subsystem!\n"); + kfree(vp); + } + mutex_unlock(&vnet_list_mutex); +} + +static const struct vio_device_id vsw_port_match[] = { + { + .type = "vsw-port", + }, + {}, +}; +MODULE_DEVICE_TABLE(vio, vsw_port_match); + +static struct vio_driver vsw_port_driver = { + .id_table = vsw_port_match, + .probe = vsw_port_probe, + .remove = vsw_port_remove, + .name = "vsw_port", +}; + +static int __init vsw_init(void) +{ + return vio_register_driver(&vsw_port_driver); +} + +static void __exit vsw_exit(void) +{ + vio_unregister_driver(&vsw_port_driver); + vsw_cleanup(); +} + +module_init(vsw_init); +module_exit(vsw_exit); -- cgit v1.2.3