aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netdevice.h
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2017-01-10 15:24:15 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-10 21:30:33 -0500
commit57ea52a865144aedbcd619ee0081155e658b6f7d (patch)
treeb1a308499831346c7e39072c41c4e503c9113530 /include/linux/netdevice.h
parent1272ce87fa017ca4cf32920764d879656b7a005a (diff)
gro: Disable frag0 optimization on IPv6 ext headers
The GRO fast path caches the frag0 address. This address becomes invalid if frag0 is modified by pskb_may_pull or its variants. So whenever that happens we must disable the frag0 optimization. This is usually done through the combination of gro_header_hard and gro_header_slow, however, the IPv6 extension header path did the pulling directly and would continue to use the GRO fast path incorrectly. This patch fixes it by disabling the fast path when we enter the IPv6 extension header path. Fixes: 78a478d0efd9 ("gro: Inline skb_gro_header and cache frag0 virtual address") Reported-by: Slava Shwartsman <slavash@mellanox.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r--include/linux/netdevice.h9
1 files changed, 7 insertions, 2 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 994f7423a74b..9bde9558b596 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2477,14 +2477,19 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
2477 return NAPI_GRO_CB(skb)->frag0_len < hlen; 2477 return NAPI_GRO_CB(skb)->frag0_len < hlen;
2478} 2478}
2479 2479
2480static inline void skb_gro_frag0_invalidate(struct sk_buff *skb)
2481{
2482 NAPI_GRO_CB(skb)->frag0 = NULL;
2483 NAPI_GRO_CB(skb)->frag0_len = 0;
2484}
2485
2480static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen, 2486static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
2481 unsigned int offset) 2487 unsigned int offset)
2482{ 2488{
2483 if (!pskb_may_pull(skb, hlen)) 2489 if (!pskb_may_pull(skb, hlen))
2484 return NULL; 2490 return NULL;
2485 2491
2486 NAPI_GRO_CB(skb)->frag0 = NULL; 2492 skb_gro_frag0_invalidate(skb);
2487 NAPI_GRO_CB(skb)->frag0_len = 0;
2488 return skb->data + offset; 2493 return skb->data + offset;
2489} 2494}
2490 2495