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. */ |