From 03d56daafe9d4e04a8a0d305789cd3eda250746b Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 9 Sep 2014 11:23:14 -0700 Subject: [PATCH 1/3] ipv6: Clear flush_id to make GRO work In TCP gro we check flush_id which is derived from the IP identifier. In IPv4 gro path the flush_id is set with the expectation that every matched packet increments IP identifier. In IPv6, the flush_id is never set and thus is uinitialized. What's worse is that in IPv6 over IPv4 encapsulation, the IP identifier is taken from the outer header which is currently not incremented on every packet for Linux stack, so GRO in this case never matches packets (identifier is not increasing). This patch clears flush_id for every time for a matched packet in IPv6 gro_receive. We need to do this each time to overwrite the setting that would be done in IPv4 gro_receive per the outer header in IPv6 over Ipv4 encapsulation. Signed-off-by: Tom Herbert Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/ip6_offload.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 5bcda338bcefb..929bbbcd0c8e5 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -261,6 +261,9 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, /* flush if Traffic Class fields are different */ NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); NAPI_GRO_CB(p)->flush |= flush; + + /* Clear flush_id, there's really no concept of ID in IPv6. */ + NAPI_GRO_CB(p)->flush_id = 0; } NAPI_GRO_CB(skb)->flush |= flush; From 9667e9bb3f366435dde74f22578876daae850feb Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 9 Sep 2014 11:23:15 -0700 Subject: [PATCH 2/3] ipip: Add gro callbacks to ipip offload Add inet_gro_receive and inet_gro_complete to ipip_offload to support GRO. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- net/ipv4/af_inet.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index b537bd94906c3..72011cc4c13bb 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1666,6 +1666,8 @@ static const struct net_offload ipip_offload = { .callbacks = { .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment, + .gro_receive = inet_gro_receive, + .gro_complete = inet_gro_complete, }, }; From 19424e052fb44da2f00d1a868cbb51f3e9f4bbb5 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Tue, 9 Sep 2014 11:23:16 -0700 Subject: [PATCH 3/3] sit: Add gro callbacks to sit_offload Add ipv6_gro_receive and ipv6_gro_complete to sit_offload to support GRO. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- net/ipv6/ip6_offload.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 929bbbcd0c8e5..9952f3fce30a3 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -317,6 +317,8 @@ static const struct net_offload sit_offload = { .callbacks = { .gso_send_check = ipv6_gso_send_check, .gso_segment = ipv6_gso_segment, + .gro_receive = ipv6_gro_receive, + .gro_complete = ipv6_gro_complete, }, };