diff options
| -rw-r--r-- | include/linux/skbuff.h | 13 | ||||
| -rw-r--r-- | include/net/checksum.h | 6 | ||||
| -rw-r--r-- | net/core/skbuff.c | 31 |
3 files changed, 37 insertions, 13 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 2c154976394b..44727b5d4981 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -2360,8 +2360,6 @@ int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset, | |||
| 2360 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); | 2360 | void skb_free_datagram(struct sock *sk, struct sk_buff *skb); |
| 2361 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); | 2361 | void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb); |
| 2362 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); | 2362 | int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); |
| 2363 | __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, | ||
| 2364 | __wsum csum); | ||
| 2365 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); | 2363 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); |
| 2366 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); | 2364 | int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); |
| 2367 | __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, | 2365 | __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, |
| @@ -2373,9 +2371,18 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to); | |||
| 2373 | void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); | 2371 | void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); |
| 2374 | int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); | 2372 | int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); |
| 2375 | void skb_scrub_packet(struct sk_buff *skb, bool xnet); | 2373 | void skb_scrub_packet(struct sk_buff *skb, bool xnet); |
| 2376 | |||
| 2377 | struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); | 2374 | struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); |
| 2378 | 2375 | ||
| 2376 | struct skb_checksum_ops { | ||
| 2377 | __wsum (*update)(const void *mem, int len, __wsum wsum); | ||
| 2378 | __wsum (*combine)(__wsum csum, __wsum csum2, int offset, int len); | ||
| 2379 | }; | ||
| 2380 | |||
| 2381 | __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, | ||
| 2382 | __wsum csum, const struct skb_checksum_ops *ops); | ||
| 2383 | __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, | ||
| 2384 | __wsum csum); | ||
| 2385 | |||
| 2379 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, | 2386 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, |
| 2380 | int len, void *buffer) | 2387 | int len, void *buffer) |
| 2381 | { | 2388 | { |
diff --git a/include/net/checksum.h b/include/net/checksum.h index 8f59ca50477c..15f33fde826e 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h | |||
| @@ -79,6 +79,12 @@ csum_block_add(__wsum csum, __wsum csum2, int offset) | |||
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static inline __wsum | 81 | static inline __wsum |
| 82 | csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len) | ||
| 83 | { | ||
| 84 | return csum_block_add(csum, csum2, offset); | ||
| 85 | } | ||
| 86 | |||
| 87 | static inline __wsum | ||
| 82 | csum_block_sub(__wsum csum, __wsum csum2, int offset) | 88 | csum_block_sub(__wsum csum, __wsum csum2, int offset) |
| 83 | { | 89 | { |
| 84 | u32 sum = (__force u32)csum2; | 90 | u32 sum = (__force u32)csum2; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0ab32faa520f..31aab5376cb4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -1928,9 +1928,8 @@ fault: | |||
| 1928 | EXPORT_SYMBOL(skb_store_bits); | 1928 | EXPORT_SYMBOL(skb_store_bits); |
| 1929 | 1929 | ||
| 1930 | /* Checksum skb data. */ | 1930 | /* Checksum skb data. */ |
| 1931 | 1931 | __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, | |
| 1932 | __wsum skb_checksum(const struct sk_buff *skb, int offset, | 1932 | __wsum csum, const struct skb_checksum_ops *ops) |
| 1933 | int len, __wsum csum) | ||
| 1934 | { | 1933 | { |
| 1935 | int start = skb_headlen(skb); | 1934 | int start = skb_headlen(skb); |
| 1936 | int i, copy = start - offset; | 1935 | int i, copy = start - offset; |
| @@ -1941,7 +1940,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
| 1941 | if (copy > 0) { | 1940 | if (copy > 0) { |
| 1942 | if (copy > len) | 1941 | if (copy > len) |
| 1943 | copy = len; | 1942 | copy = len; |
| 1944 | csum = csum_partial(skb->data + offset, copy, csum); | 1943 | csum = ops->update(skb->data + offset, copy, csum); |
| 1945 | if ((len -= copy) == 0) | 1944 | if ((len -= copy) == 0) |
| 1946 | return csum; | 1945 | return csum; |
| 1947 | offset += copy; | 1946 | offset += copy; |
| @@ -1962,10 +1961,10 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
| 1962 | if (copy > len) | 1961 | if (copy > len) |
| 1963 | copy = len; | 1962 | copy = len; |
| 1964 | vaddr = kmap_atomic(skb_frag_page(frag)); | 1963 | vaddr = kmap_atomic(skb_frag_page(frag)); |
| 1965 | csum2 = csum_partial(vaddr + frag->page_offset + | 1964 | csum2 = ops->update(vaddr + frag->page_offset + |
| 1966 | offset - start, copy, 0); | 1965 | offset - start, copy, 0); |
| 1967 | kunmap_atomic(vaddr); | 1966 | kunmap_atomic(vaddr); |
| 1968 | csum = csum_block_add(csum, csum2, pos); | 1967 | csum = ops->combine(csum, csum2, pos, copy); |
| 1969 | if (!(len -= copy)) | 1968 | if (!(len -= copy)) |
| 1970 | return csum; | 1969 | return csum; |
| 1971 | offset += copy; | 1970 | offset += copy; |
| @@ -1984,9 +1983,9 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
| 1984 | __wsum csum2; | 1983 | __wsum csum2; |
| 1985 | if (copy > len) | 1984 | if (copy > len) |
| 1986 | copy = len; | 1985 | copy = len; |
| 1987 | csum2 = skb_checksum(frag_iter, offset - start, | 1986 | csum2 = __skb_checksum(frag_iter, offset - start, |
| 1988 | copy, 0); | 1987 | copy, 0, ops); |
| 1989 | csum = csum_block_add(csum, csum2, pos); | 1988 | csum = ops->combine(csum, csum2, pos, copy); |
| 1990 | if ((len -= copy) == 0) | 1989 | if ((len -= copy) == 0) |
| 1991 | return csum; | 1990 | return csum; |
| 1992 | offset += copy; | 1991 | offset += copy; |
| @@ -1998,6 +1997,18 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, | |||
| 1998 | 1997 | ||
| 1999 | return csum; | 1998 | return csum; |
| 2000 | } | 1999 | } |
| 2000 | EXPORT_SYMBOL(__skb_checksum); | ||
| 2001 | |||
| 2002 | __wsum skb_checksum(const struct sk_buff *skb, int offset, | ||
| 2003 | int len, __wsum csum) | ||
| 2004 | { | ||
| 2005 | const struct skb_checksum_ops ops = { | ||
| 2006 | .update = csum_partial, | ||
| 2007 | .combine = csum_block_add_ext, | ||
| 2008 | }; | ||
| 2009 | |||
| 2010 | return __skb_checksum(skb, offset, len, csum, &ops); | ||
| 2011 | } | ||
| 2001 | EXPORT_SYMBOL(skb_checksum); | 2012 | EXPORT_SYMBOL(skb_checksum); |
| 2002 | 2013 | ||
| 2003 | /* Both of above in one bottle. */ | 2014 | /* Both of above in one bottle. */ |
