diff options
author | Alexander Duyck <aduyck@mirantis.com> | 2016-05-02 09:38:18 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-04 13:32:27 -0400 |
commit | 36c983824b6f17b93258153ff5b05c33c34e44ba (patch) | |
tree | 4f18f854521d5ada2852b8832e58cb6898e54df5 /net/core | |
parent | d7fb5a80492169cd737d51042f4ee03b09be0ef6 (diff) | |
download | blackbird-obmc-linux-36c983824b6f17b93258153ff5b05c33c34e44ba.tar.gz blackbird-obmc-linux-36c983824b6f17b93258153ff5b05c33c34e44ba.zip |
gso: Only allow GSO_PARTIAL if we can checksum the inner protocol
This patch addresses a possible issue that can occur if we get into any odd
corner cases where we support TSO for a given protocol but not the checksum
or scatter-gather offload. There are few drivers floating around that
setup their tunnels this way and by enforcing the checksum piece we can
avoid mangling any frames.
Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/skbuff.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b8dd2d2e2256..5586be93632f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3080,8 +3080,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, unsigned int headroom; unsigned int len = head_skb->len; __be16 proto; - bool csum; - int sg = !!(features & NETIF_F_SG); + bool csum, sg; int nfrags = skb_shinfo(head_skb)->nr_frags; int err = -ENOMEM; int i = 0; @@ -3093,13 +3092,14 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, if (unlikely(!proto)) return ERR_PTR(-EINVAL); + sg = !!(features & NETIF_F_SG); csum = !!can_checksum_protocol(features, proto); /* GSO partial only requires that we trim off any excess that * doesn't fit into an MSS sized block, so take care of that * now. */ - if (features & NETIF_F_GSO_PARTIAL) { + if (sg && csum && (features & NETIF_F_GSO_PARTIAL)) { partial_segs = len / mss; if (partial_segs > 1) mss *= partial_segs; |