diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
commit | befddb21c845f8fb49e637997891ef97c6a869dc (patch) | |
tree | 0e7629123184f2dd50291ad6d477b894175f0f26 /net/ipv6/tcp_ipv6.c | |
parent | e716efde75267eab919cdb2bef5b2cb77f305326 (diff) | |
parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) |
Merge tag 'v3.8-rc4' into irq/core
Merge Linux 3.8-rc4 before pulling in new commits - we were on an old v3.7 base.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 127 |
1 files changed, 14 insertions, 113 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 26175bffbaa0..93825dd3a7c0 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -77,9 +77,6 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | |||
77 | struct request_sock *req); | 77 | struct request_sock *req); |
78 | 78 | ||
79 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 79 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
80 | static void __tcp_v6_send_check(struct sk_buff *skb, | ||
81 | const struct in6_addr *saddr, | ||
82 | const struct in6_addr *daddr); | ||
83 | 80 | ||
84 | static const struct inet_connection_sock_af_ops ipv6_mapped; | 81 | static const struct inet_connection_sock_af_ops ipv6_mapped; |
85 | static const struct inet_connection_sock_af_ops ipv6_specific; | 82 | static const struct inet_connection_sock_af_ops ipv6_specific; |
@@ -119,14 +116,6 @@ static void tcp_v6_hash(struct sock *sk) | |||
119 | } | 116 | } |
120 | } | 117 | } |
121 | 118 | ||
122 | static __inline__ __sum16 tcp_v6_check(int len, | ||
123 | const struct in6_addr *saddr, | ||
124 | const struct in6_addr *daddr, | ||
125 | __wsum base) | ||
126 | { | ||
127 | return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); | ||
128 | } | ||
129 | |||
130 | static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) | 119 | static __u32 tcp_v6_init_sequence(const struct sk_buff *skb) |
131 | { | 120 | { |
132 | return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 121 | return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
@@ -306,7 +295,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
306 | if (err) | 295 | if (err) |
307 | goto late_failure; | 296 | goto late_failure; |
308 | 297 | ||
309 | if (!tp->write_seq) | 298 | if (!tp->write_seq && likely(!tp->repair)) |
310 | tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, | 299 | tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, |
311 | np->daddr.s6_addr32, | 300 | np->daddr.s6_addr32, |
312 | inet->inet_sport, | 301 | inet->inet_sport, |
@@ -495,9 +484,12 @@ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req, | |||
495 | struct request_values *rvp) | 484 | struct request_values *rvp) |
496 | { | 485 | { |
497 | struct flowi6 fl6; | 486 | struct flowi6 fl6; |
487 | int res; | ||
498 | 488 | ||
499 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | 489 | res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); |
500 | return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0); | 490 | if (!res) |
491 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
492 | return res; | ||
501 | } | 493 | } |
502 | 494 | ||
503 | static void tcp_v6_reqsk_destructor(struct request_sock *req) | 495 | static void tcp_v6_reqsk_destructor(struct request_sock *req) |
@@ -719,94 +711,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { | |||
719 | }; | 711 | }; |
720 | #endif | 712 | #endif |
721 | 713 | ||
722 | static void __tcp_v6_send_check(struct sk_buff *skb, | ||
723 | const struct in6_addr *saddr, const struct in6_addr *daddr) | ||
724 | { | ||
725 | struct tcphdr *th = tcp_hdr(skb); | ||
726 | |||
727 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
728 | th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0); | ||
729 | skb->csum_start = skb_transport_header(skb) - skb->head; | ||
730 | skb->csum_offset = offsetof(struct tcphdr, check); | ||
731 | } else { | ||
732 | th->check = tcp_v6_check(skb->len, saddr, daddr, | ||
733 | csum_partial(th, th->doff << 2, | ||
734 | skb->csum)); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) | ||
739 | { | ||
740 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
741 | |||
742 | __tcp_v6_send_check(skb, &np->saddr, &np->daddr); | ||
743 | } | ||
744 | |||
745 | static int tcp_v6_gso_send_check(struct sk_buff *skb) | ||
746 | { | ||
747 | const struct ipv6hdr *ipv6h; | ||
748 | struct tcphdr *th; | ||
749 | |||
750 | if (!pskb_may_pull(skb, sizeof(*th))) | ||
751 | return -EINVAL; | ||
752 | |||
753 | ipv6h = ipv6_hdr(skb); | ||
754 | th = tcp_hdr(skb); | ||
755 | |||
756 | th->check = 0; | ||
757 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
758 | __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr); | ||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, | ||
763 | struct sk_buff *skb) | ||
764 | { | ||
765 | const struct ipv6hdr *iph = skb_gro_network_header(skb); | ||
766 | __wsum wsum; | ||
767 | __sum16 sum; | ||
768 | |||
769 | switch (skb->ip_summed) { | ||
770 | case CHECKSUM_COMPLETE: | ||
771 | if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr, | ||
772 | skb->csum)) { | ||
773 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
774 | break; | ||
775 | } | ||
776 | flush: | ||
777 | NAPI_GRO_CB(skb)->flush = 1; | ||
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; | ||
793 | } | ||
794 | |||
795 | return tcp_gro_receive(head, skb); | ||
796 | } | ||
797 | |||
798 | static int tcp6_gro_complete(struct sk_buff *skb) | ||
799 | { | ||
800 | const struct ipv6hdr *iph = ipv6_hdr(skb); | ||
801 | struct tcphdr *th = tcp_hdr(skb); | ||
802 | |||
803 | th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb), | ||
804 | &iph->saddr, &iph->daddr, 0); | ||
805 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | ||
806 | |||
807 | return tcp_gro_complete(skb); | ||
808 | } | ||
809 | |||
810 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | 714 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, |
811 | u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) | 715 | u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass) |
812 | { | 716 | { |
@@ -1364,7 +1268,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1364 | 1268 | ||
1365 | tcp_initialize_rcv_mss(newsk); | 1269 | tcp_initialize_rcv_mss(newsk); |
1366 | tcp_synack_rtt_meas(newsk, req); | 1270 | tcp_synack_rtt_meas(newsk, req); |
1367 | newtp->total_retrans = req->retrans; | 1271 | newtp->total_retrans = req->num_retrans; |
1368 | 1272 | ||
1369 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; | 1273 | newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; |
1370 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; | 1274 | newinet->inet_rcv_saddr = LOOPBACK4_IPV6; |
@@ -1384,7 +1288,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1384 | #endif | 1288 | #endif |
1385 | 1289 | ||
1386 | if (__inet_inherit_port(sk, newsk) < 0) { | 1290 | if (__inet_inherit_port(sk, newsk) < 0) { |
1387 | sock_put(newsk); | 1291 | inet_csk_prepare_forced_close(newsk); |
1292 | tcp_done(newsk); | ||
1388 | goto out; | 1293 | goto out; |
1389 | } | 1294 | } |
1390 | __inet6_hash(newsk, NULL); | 1295 | __inet6_hash(newsk, NULL); |
@@ -1741,11 +1646,11 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1741 | skb->destructor = sock_edemux; | 1646 | skb->destructor = sock_edemux; |
1742 | if (sk->sk_state != TCP_TIME_WAIT) { | 1647 | if (sk->sk_state != TCP_TIME_WAIT) { |
1743 | struct dst_entry *dst = sk->sk_rx_dst; | 1648 | struct dst_entry *dst = sk->sk_rx_dst; |
1744 | struct inet_sock *icsk = inet_sk(sk); | 1649 | |
1745 | if (dst) | 1650 | if (dst) |
1746 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1651 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
1747 | if (dst && | 1652 | if (dst && |
1748 | icsk->rx_dst_ifindex == skb->skb_iif) | 1653 | inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) |
1749 | skb_dst_set_noref(skb, dst); | 1654 | skb_dst_set_noref(skb, dst); |
1750 | } | 1655 | } |
1751 | } | 1656 | } |
@@ -1866,7 +1771,7 @@ static void get_openreq6(struct seq_file *seq, | |||
1866 | 0,0, /* could print option size, but that is af dependent. */ | 1771 | 0,0, /* could print option size, but that is af dependent. */ |
1867 | 1, /* timers active (only the expire timer) */ | 1772 | 1, /* timers active (only the expire timer) */ |
1868 | jiffies_to_clock_t(ttd), | 1773 | jiffies_to_clock_t(ttd), |
1869 | req->retrans, | 1774 | req->num_timeout, |
1870 | from_kuid_munged(seq_user_ns(seq), uid), | 1775 | from_kuid_munged(seq_user_ns(seq), uid), |
1871 | 0, /* non standard timer */ | 1776 | 0, /* non standard timer */ |
1872 | 0, /* open_requests have no inode */ | 1777 | 0, /* open_requests have no inode */ |
@@ -2063,10 +1968,6 @@ static const struct inet6_protocol tcpv6_protocol = { | |||
2063 | .early_demux = tcp_v6_early_demux, | 1968 | .early_demux = tcp_v6_early_demux, |
2064 | .handler = tcp_v6_rcv, | 1969 | .handler = tcp_v6_rcv, |
2065 | .err_handler = tcp_v6_err, | 1970 | .err_handler = tcp_v6_err, |
2066 | .gso_send_check = tcp_v6_gso_send_check, | ||
2067 | .gso_segment = tcp_tso_segment, | ||
2068 | .gro_receive = tcp6_gro_receive, | ||
2069 | .gro_complete = tcp6_gro_complete, | ||
2070 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 1971 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
2071 | }; | 1972 | }; |
2072 | 1973 | ||
@@ -2121,10 +2022,10 @@ int __init tcpv6_init(void) | |||
2121 | out: | 2022 | out: |
2122 | return ret; | 2023 | return ret; |
2123 | 2024 | ||
2124 | out_tcpv6_protocol: | ||
2125 | inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); | ||
2126 | out_tcpv6_protosw: | 2025 | out_tcpv6_protosw: |
2127 | inet6_unregister_protosw(&tcpv6_protosw); | 2026 | inet6_unregister_protosw(&tcpv6_protosw); |
2027 | out_tcpv6_protocol: | ||
2028 | inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP); | ||
2128 | goto out; | 2029 | goto out; |
2129 | } | 2030 | } |
2130 | 2031 | ||