summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2018-10-10 22:30:11 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-02-08 13:25:32 +0300
commit7fab8b2f0c994decf580027286b97533c8b7f6fd (patch)
tree73ddbf378159434a9e9dc34c6eaebc848c0532c3 /net/core
parent5f2d68b6b5a439c3223d8fa6ba20736f91fc58d8 (diff)
downloadlinux-7fab8b2f0c994decf580027286b97533c8b7f6fd.tar.xz
net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends
commit 88078d98d1bb085d72af8437707279e203524fa5 upstream. After working on IP defragmentation lately, I found that some large packets defeat CHECKSUM_COMPLETE optimization because of NIC adding zero paddings on the last (small) fragment. While removing the padding with pskb_trim_rcsum(), we set skb->ip_summed to CHECKSUM_NONE, forcing a full csum validation, even if all prior fragments had CHECKSUM_COMPLETE set. We can instead compute the checksum of the part we are trimming, usually smaller than the part we keep. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/skbuff.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 49f73fb0840b..3d7c92d38a78 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1502,6 +1502,20 @@ done:
}
EXPORT_SYMBOL(___pskb_trim);
+/* Note : use pskb_trim_rcsum() instead of calling this directly
+ */
+int pskb_trim_rcsum_slow(struct sk_buff *skb, unsigned int len)
+{
+ if (skb->ip_summed == CHECKSUM_COMPLETE) {
+ int delta = skb->len - len;
+
+ skb->csum = csum_sub(skb->csum,
+ skb_checksum(skb, len, delta, 0));
+ }
+ return __pskb_trim(skb, len);
+}
+EXPORT_SYMBOL(pskb_trim_rcsum_slow);
+
/**
* __pskb_pull_tail - advance tail of skb header
* @skb: buffer to reallocate