diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d6212d6bc8d8..49c890386ce9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -763,6 +763,8 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
763 | struct sk_buff *skb) | 763 | struct sk_buff *skb) |
764 | { | 764 | { |
765 | const struct ipv6hdr *iph = skb_gro_network_header(skb); | 765 | const struct ipv6hdr *iph = skb_gro_network_header(skb); |
766 | __wsum wsum; | ||
767 | __sum16 sum; | ||
766 | 768 | ||
767 | switch (skb->ip_summed) { | 769 | switch (skb->ip_summed) { |
768 | case CHECKSUM_COMPLETE: | 770 | case CHECKSUM_COMPLETE: |
@@ -771,11 +773,23 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | |||
771 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 773 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
772 | break; | 774 | break; |
773 | } | 775 | } |
774 | 776 | flush: | |
775 | /* fall through */ | ||
776 | case CHECKSUM_NONE: | ||
777 | NAPI_GRO_CB(skb)->flush = 1; | 777 | NAPI_GRO_CB(skb)->flush = 1; |
778 | return NULL; | 778 | return NULL; |
779 | |||
780 | case CHECKSUM_NONE: | ||
781 | wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr, | ||
782 | skb_gro_len(skb), | ||
783 | IPPROTO_TCP, 0)); | ||
784 | sum = csum_fold(skb_checksum(skb, | ||
785 | skb_gro_offset(skb), | ||
786 | skb_gro_len(skb), | ||
787 | wsum)); | ||
788 | if (sum) | ||
789 | goto flush; | ||
790 | |||
791 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
792 | break; | ||
779 | } | 793 | } |
780 | 794 | ||
781 | return tcp_gro_receive(head, skb); | 795 | return tcp_gro_receive(head, skb); |