Skip to content

Commit 67b2197

Browse files
herbertxgregkh
authored andcommitted
gro: Disable frag0 optimization on IPv6 ext headers
[ Upstream commit 57ea52a865144aedbcd619ee0081155e658b6f7d ] 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: 78a478d ("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent db7119e commit 67b2197

2 files changed

Lines changed: 8 additions & 2 deletions

File tree

include/linux/netdevice.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,14 +2325,19 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
23252325
return NAPI_GRO_CB(skb)->frag0_len < hlen;
23262326
}
23272327

2328+
static inline void skb_gro_frag0_invalidate(struct sk_buff *skb)
2329+
{
2330+
NAPI_GRO_CB(skb)->frag0 = NULL;
2331+
NAPI_GRO_CB(skb)->frag0_len = 0;
2332+
}
2333+
23282334
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
23292335
unsigned int offset)
23302336
{
23312337
if (!pskb_may_pull(skb, hlen))
23322338
return NULL;
23332339

2334-
NAPI_GRO_CB(skb)->frag0 = NULL;
2335-
NAPI_GRO_CB(skb)->frag0_len = 0;
2340+
skb_gro_frag0_invalidate(skb);
23362341
return skb->data + offset;
23372342
}
23382343

net/ipv6/ip6_offload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
196196
ops = rcu_dereference(inet6_offloads[proto]);
197197
if (!ops || !ops->callbacks.gro_receive) {
198198
__pskb_pull(skb, skb_gro_offset(skb));
199+
skb_gro_frag0_invalidate(skb);
199200
proto = ipv6_gso_pull_exthdrs(skb, proto);
200201
skb_gro_pull(skb, -skb_transport_offset(skb));
201202
skb_reset_transport_header(skb);

0 commit comments

Comments
 (0)