diff options
author | Tom Herbert <tom@herbertland.com> | 2015-08-17 13:42:26 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-17 21:33:06 -0700 |
commit | abc5d1ff3e8f9b4a9d274818459b123e31981dc9 (patch) | |
tree | bfe90be833065a4707499800e25c8b65bcbb25b0 /net | |
parent | 4b048d6d9d0b0b90e1e94f2393796bbf1fa8df4e (diff) |
net: Add inet_proto_csum_replace_by_diff utility function
This function updates a checksum field value and skb->csum based on
a value which is the difference between the old and new checksum.
Signed-off-by: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/utils.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/net/core/utils.c b/net/core/utils.c index cd7d202f340e..3dffce953c39 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -336,6 +336,19 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb, } EXPORT_SYMBOL(inet_proto_csum_replace16); +void inet_proto_csum_replace_by_diff(__sum16 *sum, struct sk_buff *skb, + __wsum diff, bool pseudohdr) +{ + if (skb->ip_summed != CHECKSUM_PARTIAL) { + *sum = csum_fold(csum_add(diff, ~csum_unfold(*sum))); + if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) + skb->csum = ~csum_add(diff, ~skb->csum); + } else if (pseudohdr) { + *sum = ~csum_fold(csum_add(diff, csum_unfold(*sum))); + } +} +EXPORT_SYMBOL(inet_proto_csum_replace_by_diff); + struct __net_random_once_work { struct work_struct work; struct static_key *key; |