aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/af_inet6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/af_inet6.c')
-rw-r--r--net/ipv6/af_inet6.c32
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
886static struct packet_type ipv6_packet_type = { 896static 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,