提交 ebad18e9 编写于 作者: H Herbert Xu 提交者: David S. Miller

gro: Fix handling of complete checksums in IPv6

We need to perform skb_postpull_rcsum after pulling the IPv6
header in order to maintain the correctness of the complete
checksum.

This patch also adds a missing iph reload after pulling.
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0d1cfd20
...@@ -797,6 +797,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, ...@@ -797,6 +797,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
unsigned int nlen; unsigned int nlen;
int flush = 1; int flush = 1;
int proto; int proto;
__wsum csum;
if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
goto out; goto out;
...@@ -808,6 +809,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, ...@@ -808,6 +809,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
rcu_read_lock(); rcu_read_lock();
proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr); proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr);
iph = ipv6_hdr(skb);
IPV6_GRO_CB(skb)->proto = proto; IPV6_GRO_CB(skb)->proto = proto;
ops = rcu_dereference(inet6_protos[proto]); ops = rcu_dereference(inet6_protos[proto]);
if (!ops || !ops->gro_receive) if (!ops || !ops->gro_receive)
...@@ -839,8 +841,13 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, ...@@ -839,8 +841,13 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
NAPI_GRO_CB(skb)->flush |= flush; NAPI_GRO_CB(skb)->flush |= flush;
csum = skb->csum;
skb_postpull_rcsum(skb, iph, skb_network_header_len(skb));
pp = ops->gro_receive(head, skb); pp = ops->gro_receive(head, skb);
skb->csum = csum;
out_unlock: out_unlock:
rcu_read_unlock(); rcu_read_unlock();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册