diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5bdcb9002cf7..b843a650be71 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
270 | inet->rcv_saddr = LOOPBACK4_IPV6; | 270 | inet->rcv_saddr = LOOPBACK4_IPV6; |
271 | 271 | ||
272 | sk->sk_gso_type = SKB_GSO_TCPV6; | 272 | sk->sk_gso_type = SKB_GSO_TCPV6; |
273 | ip6_dst_store(sk, dst, NULL); | 273 | __ip6_dst_store(sk, dst, NULL); |
274 | 274 | ||
275 | icsk->icsk_ext_hdr_len = 0; | 275 | icsk->icsk_ext_hdr_len = 0; |
276 | if (np->opt) | 276 | if (np->opt) |
@@ -427,7 +427,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
427 | case TCP_SYN_RECV: /* Cannot happen. | 427 | case TCP_SYN_RECV: /* Cannot happen. |
428 | It can, it SYNs are crossed. --ANK */ | 428 | It can, it SYNs are crossed. --ANK */ |
429 | if (!sock_owned_by_user(sk)) { | 429 | if (!sock_owned_by_user(sk)) { |
430 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
431 | sk->sk_err = err; | 430 | sk->sk_err = err; |
432 | sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ | 431 | sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ |
433 | 432 | ||
@@ -552,6 +551,24 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | |||
552 | } | 551 | } |
553 | } | 552 | } |
554 | 553 | ||
554 | static int tcp_v6_gso_send_check(struct sk_buff *skb) | ||
555 | { | ||
556 | struct ipv6hdr *ipv6h; | ||
557 | struct tcphdr *th; | ||
558 | |||
559 | if (!pskb_may_pull(skb, sizeof(*th))) | ||
560 | return -EINVAL; | ||
561 | |||
562 | ipv6h = skb->nh.ipv6h; | ||
563 | th = skb->h.th; | ||
564 | |||
565 | th->check = 0; | ||
566 | th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, | ||
567 | IPPROTO_TCP, 0); | ||
568 | skb->csum = offsetof(struct tcphdr, check); | ||
569 | skb->ip_summed = CHECKSUM_HW; | ||
570 | return 0; | ||
571 | } | ||
555 | 572 | ||
556 | static void tcp_v6_send_reset(struct sk_buff *skb) | 573 | static void tcp_v6_send_reset(struct sk_buff *skb) |
557 | { | 574 | { |
@@ -813,7 +830,6 @@ drop: | |||
813 | if (req) | 830 | if (req) |
814 | reqsk_free(req); | 831 | reqsk_free(req); |
815 | 832 | ||
816 | TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); | ||
817 | return 0; /* don't send reset */ | 833 | return 0; /* don't send reset */ |
818 | } | 834 | } |
819 | 835 | ||
@@ -929,7 +945,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
929 | */ | 945 | */ |
930 | 946 | ||
931 | sk->sk_gso_type = SKB_GSO_TCPV6; | 947 | sk->sk_gso_type = SKB_GSO_TCPV6; |
932 | ip6_dst_store(newsk, dst, NULL); | 948 | __ip6_dst_store(newsk, dst, NULL); |
933 | 949 | ||
934 | newtcp6sk = (struct tcp6_sock *)newsk; | 950 | newtcp6sk = (struct tcp6_sock *)newsk; |
935 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; | 951 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; |
@@ -1603,6 +1619,7 @@ struct proto tcpv6_prot = { | |||
1603 | static struct inet6_protocol tcpv6_protocol = { | 1619 | static struct inet6_protocol tcpv6_protocol = { |
1604 | .handler = tcp_v6_rcv, | 1620 | .handler = tcp_v6_rcv, |
1605 | .err_handler = tcp_v6_err, | 1621 | .err_handler = tcp_v6_err, |
1622 | .gso_send_check = tcp_v6_gso_send_check, | ||
1606 | .gso_segment = tcp_tso_segment, | 1623 | .gso_segment = tcp_tso_segment, |
1607 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 1624 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
1608 | }; | 1625 | }; |