diff options
| author | Eric Dumazet <edumazet@google.com> | 2014-05-20 00:56:34 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-05-21 17:18:47 -0400 |
| commit | 4de462ab63e23953fd05da511aeb460ae10cc726 (patch) | |
| tree | c69385d148fb52f0f8f659f8261497ab428d820d | |
| parent | bf63ac73b3e132e6bf0c8798aba7b277c3316e19 (diff) | |
ipv6: gro: fix CHECKSUM_COMPLETE support
When GRE support was added in linux-3.14, CHECKSUM_COMPLETE handling
broke on GRE+IPv6 because we did not update/use the appropriate csum :
GRO layer is supposed to use/update NAPI_GRO_CB(skb)->csum instead of
skb->csum
Tested using a GRE tunnel and IPv6 traffic. GRO aggregation now happens
at the first level (ethernet device) instead of being done in gre
tunnel. Native IPv6+TCP is still properly aggregated.
Fixes: bf5a755f5e918 ("net-gre-gro: Add GRE support to the GRO stack")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jerry Chu <hkchu@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv6/ip6_offload.c | 6 | ||||
| -rw-r--r-- | net/ipv6/tcpv6_offload.c | 2 |
2 files changed, 2 insertions, 6 deletions
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 59f95affceb0..b2f091566f88 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
| @@ -196,7 +196,6 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
| 196 | unsigned int off; | 196 | unsigned int off; |
| 197 | u16 flush = 1; | 197 | u16 flush = 1; |
| 198 | int proto; | 198 | int proto; |
| 199 | __wsum csum; | ||
| 200 | 199 | ||
| 201 | off = skb_gro_offset(skb); | 200 | off = skb_gro_offset(skb); |
| 202 | hlen = off + sizeof(*iph); | 201 | hlen = off + sizeof(*iph); |
| @@ -264,13 +263,10 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
| 264 | 263 | ||
| 265 | NAPI_GRO_CB(skb)->flush |= flush; | 264 | NAPI_GRO_CB(skb)->flush |= flush; |
| 266 | 265 | ||
| 267 | csum = skb->csum; | 266 | skb_gro_postpull_rcsum(skb, iph, nlen); |
| 268 | skb_postpull_rcsum(skb, iph, skb_network_header_len(skb)); | ||
| 269 | 267 | ||
| 270 | pp = ops->callbacks.gro_receive(head, skb); | 268 | pp = ops->callbacks.gro_receive(head, skb); |
| 271 | 269 | ||
| 272 | skb->csum = csum; | ||
| 273 | |||
| 274 | out_unlock: | 270 | out_unlock: |
| 275 | rcu_read_unlock(); | 271 | rcu_read_unlock(); |
| 276 | 272 | ||
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index 0d78132ff18a..8517d3cd1aed 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
| @@ -42,7 +42,7 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
| 42 | if (NAPI_GRO_CB(skb)->flush) | 42 | if (NAPI_GRO_CB(skb)->flush) |
| 43 | goto skip_csum; | 43 | goto skip_csum; |
| 44 | 44 | ||
| 45 | wsum = skb->csum; | 45 | wsum = NAPI_GRO_CB(skb)->csum; |
| 46 | 46 | ||
| 47 | switch (skb->ip_summed) { | 47 | switch (skb->ip_summed) { |
| 48 | case CHECKSUM_NONE: | 48 | case CHECKSUM_NONE: |
