aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/datagram.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-08-05 15:44:22 -0400
committerPaul Moore <pmoore@redhat.com>2014-08-05 15:44:22 -0400
commitaa9e0de81b5b257f6dae48efe2ed5f255f066497 (patch)
tree9b0b791d5912368006115427e74105cfe26750bd /net/core/datagram.c
parentnetlabel: shorter names for the NetLabel catmap funcs/structs (diff)
parentLinux 3.16 (diff)
downloadlinux-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.c26
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);