diff options
Diffstat (limited to 'net/ipv6/af_inet6.c')
-rw-r--r-- | net/ipv6/af_inet6.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index da944eca2ca6..57b07da1212a 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -803,24 +803,34 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
803 | int proto; | 803 | int proto; |
804 | __wsum csum; | 804 | __wsum csum; |
805 | 805 | ||
806 | if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) | 806 | iph = skb_gro_header(skb, sizeof(*iph)); |
807 | if (unlikely(!iph)) | ||
807 | goto out; | 808 | goto out; |
808 | 809 | ||
809 | iph = ipv6_hdr(skb); | 810 | skb_gro_pull(skb, sizeof(*iph)); |
810 | __skb_pull(skb, sizeof(*iph)); | 811 | skb_set_transport_header(skb, skb_gro_offset(skb)); |
811 | 812 | ||
812 | flush += ntohs(iph->payload_len) != skb->len; | 813 | flush += ntohs(iph->payload_len) != skb_gro_len(skb); |
813 | 814 | ||
814 | rcu_read_lock(); | 815 | rcu_read_lock(); |
815 | proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr); | 816 | proto = iph->nexthdr; |
816 | iph = ipv6_hdr(skb); | ||
817 | IPV6_GRO_CB(skb)->proto = proto; | ||
818 | ops = rcu_dereference(inet6_protos[proto]); | 817 | ops = rcu_dereference(inet6_protos[proto]); |
819 | if (!ops || !ops->gro_receive) | 818 | if (!ops || !ops->gro_receive) { |
820 | goto out_unlock; | 819 | __pskb_pull(skb, skb_gro_offset(skb)); |
820 | proto = ipv6_gso_pull_exthdrs(skb, proto); | ||
821 | skb_gro_pull(skb, -skb_transport_offset(skb)); | ||
822 | skb_reset_transport_header(skb); | ||
823 | __skb_push(skb, skb_gro_offset(skb)); | ||
824 | |||
825 | if (!ops || !ops->gro_receive) | ||
826 | goto out_unlock; | ||
827 | |||
828 | iph = ipv6_hdr(skb); | ||
829 | } | ||
830 | |||
831 | IPV6_GRO_CB(skb)->proto = proto; | ||
821 | 832 | ||
822 | flush--; | 833 | flush--; |
823 | skb_reset_transport_header(skb); | ||
824 | nlen = skb_network_header_len(skb); | 834 | nlen = skb_network_header_len(skb); |
825 | 835 | ||
826 | for (p = *head; p; p = p->next) { | 836 | for (p = *head; p; p = p->next) { |
@@ -884,7 +894,7 @@ out_unlock: | |||
884 | } | 894 | } |
885 | 895 | ||
886 | static struct packet_type ipv6_packet_type = { | 896 | static struct packet_type ipv6_packet_type = { |
887 | .type = __constant_htons(ETH_P_IPV6), | 897 | .type = cpu_to_be16(ETH_P_IPV6), |
888 | .func = ipv6_rcv, | 898 | .func = ipv6_rcv, |
889 | .gso_send_check = ipv6_gso_send_check, | 899 | .gso_send_check = ipv6_gso_send_check, |
890 | .gso_segment = ipv6_gso_segment, | 900 | .gso_segment = ipv6_gso_segment, |