diff options
author | Paul Moore <pmoore@redhat.com> | 2014-08-05 15:44:22 -0400 |
---|---|---|
committer | Paul Moore <pmoore@redhat.com> | 2014-08-05 15:44:22 -0400 |
commit | aa9e0de81b5b257f6dae48efe2ed5f255f066497 (patch) | |
tree | 9b0b791d5912368006115427e74105cfe26750bd /net/core/datagram.c | |
parent | netlabel: shorter names for the NetLabel catmap funcs/structs (diff) | |
parent | Linux 3.16 (diff) | |
download | linux-dev-aa9e0de81b5b257f6dae48efe2ed5f255f066497.tar.xz linux-dev-aa9e0de81b5b257f6dae48efe2ed5f255f066497.zip |
Merge tag 'v3.16' into next
Linux 3.16
Diffstat (limited to 'net/core/datagram.c')
-rw-r--r-- | net/core/datagram.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index a16ed7bbe376..488dd1a825c0 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -740,17 +740,37 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len) sum = csum_fold(skb_checksum(skb, 0, len, skb->csum)); if (likely(!sum)) { - if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) + if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && + !skb->csum_complete_sw) netdev_rx_csum_fault(skb->dev); - skb->ip_summed = CHECKSUM_UNNECESSARY; } + skb->csum_valid = !sum; return sum; } EXPORT_SYMBOL(__skb_checksum_complete_head); __sum16 __skb_checksum_complete(struct sk_buff *skb) { - return __skb_checksum_complete_head(skb, skb->len); + __wsum csum; + __sum16 sum; + + csum = skb_checksum(skb, 0, skb->len, 0); + + /* skb->csum holds pseudo checksum */ + sum = csum_fold(csum_add(skb->csum, csum)); + if (likely(!sum)) { + if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && + !skb->csum_complete_sw) + netdev_rx_csum_fault(skb->dev); + } + + /* Save full packet checksum */ + skb->csum = csum; + skb->ip_summed = CHECKSUM_COMPLETE; + skb->csum_complete_sw = 1; + skb->csum_valid = !sum; + + return sum; } EXPORT_SYMBOL(__skb_checksum_complete); |