diff options
| author | Eric Dumazet <edumazet@google.com> | 2012-10-05 20:43:30 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-10-07 14:44:36 -0400 | 
| commit | 51ec04038c113a811b177baa85d293feff9ce995 (patch) | |
| tree | 0b501332fe30a45bbe5d9adb6a93372f27857bd0 | |
| parent | e1f165032c8bade3a6bdf546f8faf61fda4dd01c (diff) | |
ipv6: GRO should be ECN friendly
IPv4 side of the problem was addressed in commit a9e050f4e7f9d
(net: tcp: GRO should be ECN friendly)
This patch does the same, but for IPv6 : A Traffic Class mismatch
doesnt mean flows are different, but instead should force a flush
of previous packets.
This patch removes artificial packet reordering problem.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv6/af_inet6.c | 11 | 
1 files changed, 7 insertions, 4 deletions
| diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e22e6d88bac6..f757e3b7cfbf 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -880,22 +880,25 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,  	nlen = skb_network_header_len(skb);  	for (p = *head; p; p = p->next) { -		struct ipv6hdr *iph2; +		const struct ipv6hdr *iph2; +		__be32 first_word; /* <Version:4><Traffic_Class:8><Flow_Label:20> */  		if (!NAPI_GRO_CB(p)->same_flow)  			continue;  		iph2 = ipv6_hdr(p); +		first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ; -		/* All fields must match except length. */ +		/* All fields must match except length and Traffic Class. */  		if (nlen != skb_network_header_len(p) || -		    memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) || +		    (first_word & htonl(0xF00FFFFF)) ||  		    memcmp(&iph->nexthdr, &iph2->nexthdr,  			   nlen - offsetof(struct ipv6hdr, nexthdr))) {  			NAPI_GRO_CB(p)->same_flow = 0;  			continue;  		} - +		/* flush if Traffic Class fields are different */ +		NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));  		NAPI_GRO_CB(p)->flush |= flush;  	} | 
