aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c25
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
554static 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
556static void tcp_v6_send_reset(struct sk_buff *skb) 573static 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 = {
1603static struct inet6_protocol tcpv6_protocol = { 1619static 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};