summaryrefslogtreecommitdiff
path: root/net/ipv4/gre_offload.c
diff options
context:
space:
mode:
authorNeal Cardwell <ncardwell@google.com>2014-01-09 20:47:17 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-13 11:53:49 -0800
commitb884b1a46f205d56e33c0391c1d04644d846f41e (patch)
treef444f75b77d4954e8cd0fda24a208fa6ebc377aa /net/ipv4/gre_offload.c
parent7eb8896df03d0f4a8b301cb177d7f31c0d70e112 (diff)
downloadlinux-stable-b884b1a46f205d56e33c0391c1d04644d846f41e.tar.gz
linux-stable-b884b1a46f205d56e33c0391c1d04644d846f41e.tar.bz2
linux-stable-b884b1a46f205d56e33c0391c1d04644d846f41e.zip
gre_offload: simplify GRE header length calculation in gre_gso_segment()
Simplify the GRE header length calculation in gre_gso_segment(). Switch to an approach that is simpler, faster, and more general. The new approach will continue to be correct even if we add support for the optional variable-length routing info that may be present in a GRE header. Signed-off-by: Neal Cardwell <ncardwell@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: H.K. Jerry Chu <hkchu@google.com> Cc: Pravin B Shelar <pshelar@nicira.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/gre_offload.c')
-rw-r--r--net/ipv4/gre_offload.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index 31da9f512583..29512e3e7e7c 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -26,7 +26,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
{
struct sk_buff *segs = ERR_PTR(-EINVAL);
netdev_features_t enc_features;
- int ghl = GRE_HEADER_SECTION;
+ int ghl;
struct gre_base_hdr *greh;
u16 mac_offset = skb->mac_header;
int mac_len = skb->mac_len;
@@ -49,15 +49,11 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
greh = (struct gre_base_hdr *)skb_transport_header(skb);
- if (greh->flags & GRE_KEY)
- ghl += GRE_HEADER_SECTION;
- if (greh->flags & GRE_SEQ)
- ghl += GRE_HEADER_SECTION;
- if (greh->flags & GRE_CSUM) {
- ghl += GRE_HEADER_SECTION;
- csum = true;
- } else
- csum = false;
+ ghl = skb_inner_network_header(skb) - skb_transport_header(skb);
+ if (unlikely(ghl < sizeof(*greh)))
+ goto out;
+
+ csum = !!(greh->flags & GRE_CSUM);
if (unlikely(!pskb_may_pull(skb, ghl)))
goto out;