diff options
| author | Daniel Borkmann <dborkman@redhat.com> | 2013-10-30 06:50:51 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-11-03 23:04:57 -0500 |
| commit | 2817a336d4d533fb8b68719723cd60ea7dd7c09e (patch) | |
| tree | 71aac3aa2a48588fd0b5372cca9499bd1cbe2a5f /include | |
| parent | efba721f636ee016859d86d15748650119402b10 (diff) | |
net: skb_checksum: allow custom update/combine for walking skb
Currently, skb_checksum walks over 1) linearized, 2) frags[], and
3) frag_list data and calculats the one's complement, a 32 bit
result suitable for feeding into itself or csum_tcpudp_magic(),
but unsuitable for SCTP as we're calculating CRC32c there.
Hence, in order to not re-implement the very same function in
SCTP (and maybe other protocols) over and over again, use an
update() + combine() callback internally to allow for walking
over the skb with different algorithms.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/skbuff.h | 13 | ||||
| -rw-r--r-- | include/net/checksum.h | 6 |
2 files changed, 16 insertions, 3 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; |
