.. | .. |
---|
13 | 13 | #define _S390_CHECKSUM_H |
---|
14 | 14 | |
---|
15 | 15 | #include <linux/uaccess.h> |
---|
| 16 | +#include <linux/in6.h> |
---|
16 | 17 | |
---|
17 | 18 | /* |
---|
18 | | - * computes the checksum of a memory block at buff, length len, |
---|
19 | | - * and adds in "sum" (32-bit) |
---|
| 19 | + * Computes the checksum of a memory block at buff, length len, |
---|
| 20 | + * and adds in "sum" (32-bit). |
---|
20 | 21 | * |
---|
21 | | - * returns a 32-bit number suitable for feeding into itself |
---|
22 | | - * or csum_tcpudp_magic |
---|
| 22 | + * Returns a 32-bit number suitable for feeding into itself |
---|
| 23 | + * or csum_tcpudp_magic. |
---|
23 | 24 | * |
---|
24 | | - * this function must be called with even lengths, except |
---|
25 | | - * for the last fragment, which may be odd |
---|
| 25 | + * This function must be called with even lengths, except |
---|
| 26 | + * for the last fragment, which may be odd. |
---|
26 | 27 | * |
---|
27 | | - * it's best to have buff aligned on a 32-bit boundary |
---|
| 28 | + * It's best to have buff aligned on a 32-bit boundary. |
---|
28 | 29 | */ |
---|
29 | | -static inline __wsum |
---|
30 | | -csum_partial(const void *buff, int len, __wsum sum) |
---|
| 30 | +static inline __wsum csum_partial(const void *buff, int len, __wsum sum) |
---|
31 | 31 | { |
---|
32 | 32 | register unsigned long reg2 asm("2") = (unsigned long) buff; |
---|
33 | 33 | register unsigned long reg3 asm("3") = (unsigned long) len; |
---|
.. | .. |
---|
40 | 40 | } |
---|
41 | 41 | |
---|
42 | 42 | /* |
---|
43 | | - * the same as csum_partial_copy, but copies from user space. |
---|
44 | | - * |
---|
45 | | - * here even more important to align src and dst on a 32-bit (or even |
---|
46 | | - * better 64-bit) boundary |
---|
47 | | - * |
---|
48 | | - * Copy from userspace and compute checksum. |
---|
49 | | - */ |
---|
50 | | -static inline __wsum |
---|
51 | | -csum_partial_copy_from_user(const void __user *src, void *dst, |
---|
52 | | - int len, __wsum sum, |
---|
53 | | - int *err_ptr) |
---|
54 | | -{ |
---|
55 | | - if (unlikely(copy_from_user(dst, src, len))) |
---|
56 | | - *err_ptr = -EFAULT; |
---|
57 | | - return csum_partial(dst, len, sum); |
---|
58 | | -} |
---|
59 | | - |
---|
60 | | - |
---|
61 | | -static inline __wsum |
---|
62 | | -csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) |
---|
63 | | -{ |
---|
64 | | - memcpy(dst,src,len); |
---|
65 | | - return csum_partial(dst, len, sum); |
---|
66 | | -} |
---|
67 | | - |
---|
68 | | -/* |
---|
69 | | - * Fold a partial checksum without adding pseudo headers |
---|
| 43 | + * Fold a partial checksum without adding pseudo headers. |
---|
70 | 44 | */ |
---|
71 | 45 | static inline __sum16 csum_fold(__wsum sum) |
---|
72 | 46 | { |
---|
73 | 47 | u32 csum = (__force u32) sum; |
---|
74 | 48 | |
---|
75 | | - csum += (csum >> 16) + (csum << 16); |
---|
| 49 | + csum += (csum >> 16) | (csum << 16); |
---|
76 | 50 | csum >>= 16; |
---|
77 | 51 | return (__force __sum16) ~csum; |
---|
78 | 52 | } |
---|
79 | 53 | |
---|
80 | 54 | /* |
---|
81 | | - * This is a version of ip_compute_csum() optimized for IP headers, |
---|
82 | | - * which always checksum on 4 octet boundaries. |
---|
83 | | - * |
---|
| 55 | + * This is a version of ip_compute_csum() optimized for IP headers, |
---|
| 56 | + * which always checksums on 4 octet boundaries. |
---|
84 | 57 | */ |
---|
85 | 58 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) |
---|
86 | 59 | { |
---|
87 | | - return csum_fold(csum_partial(iph, ihl*4, 0)); |
---|
| 60 | + __u64 csum = 0; |
---|
| 61 | + __u32 *ptr = (u32 *)iph; |
---|
| 62 | + |
---|
| 63 | + csum += *ptr++; |
---|
| 64 | + csum += *ptr++; |
---|
| 65 | + csum += *ptr++; |
---|
| 66 | + csum += *ptr++; |
---|
| 67 | + ihl -= 4; |
---|
| 68 | + while (ihl--) |
---|
| 69 | + csum += *ptr++; |
---|
| 70 | + csum += (csum >> 32) | (csum << 32); |
---|
| 71 | + return csum_fold((__force __wsum)(csum >> 32)); |
---|
88 | 72 | } |
---|
89 | 73 | |
---|
90 | 74 | /* |
---|
91 | | - * computes the checksum of the TCP/UDP pseudo-header |
---|
92 | | - * returns a 32-bit checksum |
---|
| 75 | + * Computes the checksum of the TCP/UDP pseudo-header. |
---|
| 76 | + * Returns a 32-bit checksum. |
---|
93 | 77 | */ |
---|
94 | | -static inline __wsum |
---|
95 | | -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, |
---|
96 | | - __wsum sum) |
---|
| 78 | +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, |
---|
| 79 | + __u8 proto, __wsum sum) |
---|
97 | 80 | { |
---|
98 | | - __u32 csum = (__force __u32)sum; |
---|
| 81 | + __u64 csum = (__force __u64)sum; |
---|
99 | 82 | |
---|
100 | 83 | csum += (__force __u32)saddr; |
---|
101 | | - if (csum < (__force __u32)saddr) |
---|
102 | | - csum++; |
---|
103 | | - |
---|
104 | 84 | csum += (__force __u32)daddr; |
---|
105 | | - if (csum < (__force __u32)daddr) |
---|
106 | | - csum++; |
---|
107 | | - |
---|
108 | | - csum += len + proto; |
---|
109 | | - if (csum < len + proto) |
---|
110 | | - csum++; |
---|
111 | | - |
---|
112 | | - return (__force __wsum)csum; |
---|
| 85 | + csum += len; |
---|
| 86 | + csum += proto; |
---|
| 87 | + csum += (csum >> 32) | (csum << 32); |
---|
| 88 | + return (__force __wsum)(csum >> 32); |
---|
113 | 89 | } |
---|
114 | 90 | |
---|
115 | 91 | /* |
---|
116 | | - * computes the checksum of the TCP/UDP pseudo-header |
---|
117 | | - * returns a 16-bit checksum, already complemented |
---|
| 92 | + * Computes the checksum of the TCP/UDP pseudo-header. |
---|
| 93 | + * Returns a 16-bit checksum, already complemented. |
---|
118 | 94 | */ |
---|
119 | | - |
---|
120 | | -static inline __sum16 |
---|
121 | | -csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, |
---|
122 | | - __wsum sum) |
---|
| 95 | +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, |
---|
| 96 | + __u8 proto, __wsum sum) |
---|
123 | 97 | { |
---|
124 | | - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); |
---|
| 98 | + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); |
---|
125 | 99 | } |
---|
126 | 100 | |
---|
127 | 101 | /* |
---|
128 | | - * this routine is used for miscellaneous IP-like checksums, mainly |
---|
129 | | - * in icmp.c |
---|
| 102 | + * Used for miscellaneous IP-like checksums, mainly icmp. |
---|
130 | 103 | */ |
---|
131 | | - |
---|
132 | 104 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
---|
133 | 105 | { |
---|
134 | 106 | return csum_fold(csum_partial(buff, len, 0)); |
---|
135 | 107 | } |
---|
136 | 108 | |
---|
| 109 | +#define _HAVE_ARCH_IPV6_CSUM |
---|
| 110 | +static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, |
---|
| 111 | + const struct in6_addr *daddr, |
---|
| 112 | + __u32 len, __u8 proto, __wsum csum) |
---|
| 113 | +{ |
---|
| 114 | + __u64 sum = (__force __u64)csum; |
---|
| 115 | + |
---|
| 116 | + sum += (__force __u32)saddr->s6_addr32[0]; |
---|
| 117 | + sum += (__force __u32)saddr->s6_addr32[1]; |
---|
| 118 | + sum += (__force __u32)saddr->s6_addr32[2]; |
---|
| 119 | + sum += (__force __u32)saddr->s6_addr32[3]; |
---|
| 120 | + sum += (__force __u32)daddr->s6_addr32[0]; |
---|
| 121 | + sum += (__force __u32)daddr->s6_addr32[1]; |
---|
| 122 | + sum += (__force __u32)daddr->s6_addr32[2]; |
---|
| 123 | + sum += (__force __u32)daddr->s6_addr32[3]; |
---|
| 124 | + sum += len; |
---|
| 125 | + sum += proto; |
---|
| 126 | + sum += (sum >> 32) | (sum << 32); |
---|
| 127 | + return csum_fold((__force __wsum)(sum >> 32)); |
---|
| 128 | +} |
---|
| 129 | + |
---|
137 | 130 | #endif /* _S390_CHECKSUM_H */ |
---|
138 | | - |
---|
139 | | - |
---|