aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-10-05 16:43:30 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-07 14:44:36 -0400
commit51ec04038c113a811b177baa85d293feff9ce995 (patch)
tree0b501332fe30a45bbe5d9adb6a93372f27857bd0 /net/ipv6
parente1f165032c8bade3a6bdf546f8faf61fda4dd01c (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>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/af_inet6.c11
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,
880 nlen = skb_network_header_len(skb); 880 nlen = skb_network_header_len(skb);
881 881
882 for (p = *head; p; p = p->next) { 882 for (p = *head; p; p = p->next) {
883 struct ipv6hdr *iph2; 883 const struct ipv6hdr *iph2;
884 __be32 first_word; /* <Version:4><Traffic_Class:8><Flow_Label:20> */
884 885
885 if (!NAPI_GRO_CB(p)->same_flow) 886 if (!NAPI_GRO_CB(p)->same_flow)
886 continue; 887 continue;
887 888
888 iph2 = ipv6_hdr(p); 889 iph2 = ipv6_hdr(p);
890 first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ;
889 891
890 /* All fields must match except length. */ 892 /* All fields must match except length and Traffic Class. */
891 if (nlen != skb_network_header_len(p) || 893 if (nlen != skb_network_header_len(p) ||
892 memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) || 894 (first_word & htonl(0xF00FFFFF)) ||
893 memcmp(&iph->nexthdr, &iph2->nexthdr, 895 memcmp(&iph->nexthdr, &iph2->nexthdr,
894 nlen - offsetof(struct ipv6hdr, nexthdr))) { 896 nlen - offsetof(struct ipv6hdr, nexthdr))) {
895 NAPI_GRO_CB(p)->same_flow = 0; 897 NAPI_GRO_CB(p)->same_flow = 0;
896 continue; 898 continue;
897 } 899 }
898 900 /* flush if Traffic Class fields are different */
901 NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
899 NAPI_GRO_CB(p)->flush |= flush; 902 NAPI_GRO_CB(p)->flush |= flush;
900 } 903 }
901 904