diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 60a5295a7de6..7a8237acd210 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -101,12 +101,18 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | |||
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
104 | static u32 tcp_v6_init_sequence(const struct sk_buff *skb, u32 *tsoff) | 104 | static u32 tcp_v6_init_seq(const struct sk_buff *skb) |
105 | { | 105 | { |
106 | return secure_tcpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 106 | return secure_tcpv6_seq(ipv6_hdr(skb)->daddr.s6_addr32, |
107 | ipv6_hdr(skb)->saddr.s6_addr32, | 107 | ipv6_hdr(skb)->saddr.s6_addr32, |
108 | tcp_hdr(skb)->dest, | 108 | tcp_hdr(skb)->dest, |
109 | tcp_hdr(skb)->source, tsoff); | 109 | tcp_hdr(skb)->source); |
110 | } | ||
111 | |||
112 | static u32 tcp_v6_init_ts_off(const struct sk_buff *skb) | ||
113 | { | ||
114 | return secure_tcpv6_ts_off(ipv6_hdr(skb)->daddr.s6_addr32, | ||
115 | ipv6_hdr(skb)->saddr.s6_addr32); | ||
110 | } | 116 | } |
111 | 117 | ||
112 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | 118 | static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
@@ -122,7 +128,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
122 | struct flowi6 fl6; | 128 | struct flowi6 fl6; |
123 | struct dst_entry *dst; | 129 | struct dst_entry *dst; |
124 | int addr_type; | 130 | int addr_type; |
125 | u32 seq; | ||
126 | int err; | 131 | int err; |
127 | struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; | 132 | struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; |
128 | 133 | ||
@@ -265,11 +270,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
265 | sk->sk_gso_type = SKB_GSO_TCPV6; | 270 | sk->sk_gso_type = SKB_GSO_TCPV6; |
266 | ip6_dst_store(sk, dst, NULL, NULL); | 271 | ip6_dst_store(sk, dst, NULL, NULL); |
267 | 272 | ||
268 | if (tcp_death_row->sysctl_tw_recycle && | ||
269 | !tp->rx_opt.ts_recent_stamp && | ||
270 | ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr)) | ||
271 | tcp_fetch_timewait_stamp(sk, dst); | ||
272 | |||
273 | icsk->icsk_ext_hdr_len = 0; | 273 | icsk->icsk_ext_hdr_len = 0; |
274 | if (opt) | 274 | if (opt) |
275 | icsk->icsk_ext_hdr_len = opt->opt_flen + | 275 | icsk->icsk_ext_hdr_len = opt->opt_flen + |
@@ -287,13 +287,13 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
287 | sk_set_txhash(sk); | 287 | sk_set_txhash(sk); |
288 | 288 | ||
289 | if (likely(!tp->repair)) { | 289 | if (likely(!tp->repair)) { |
290 | seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, | ||
291 | sk->sk_v6_daddr.s6_addr32, | ||
292 | inet->inet_sport, | ||
293 | inet->inet_dport, | ||
294 | &tp->tsoffset); | ||
295 | if (!tp->write_seq) | 290 | if (!tp->write_seq) |
296 | tp->write_seq = seq; | 291 | tp->write_seq = secure_tcpv6_seq(np->saddr.s6_addr32, |
292 | sk->sk_v6_daddr.s6_addr32, | ||
293 | inet->inet_sport, | ||
294 | inet->inet_dport); | ||
295 | tp->tsoffset = secure_tcpv6_ts_off(np->saddr.s6_addr32, | ||
296 | sk->sk_v6_daddr.s6_addr32); | ||
297 | } | 297 | } |
298 | 298 | ||
299 | if (tcp_fastopen_defer_connect(sk, &err)) | 299 | if (tcp_fastopen_defer_connect(sk, &err)) |
@@ -391,10 +391,12 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
391 | np = inet6_sk(sk); | 391 | np = inet6_sk(sk); |
392 | 392 | ||
393 | if (type == NDISC_REDIRECT) { | 393 | if (type == NDISC_REDIRECT) { |
394 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | 394 | if (!sock_owned_by_user(sk)) { |
395 | struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie); | ||
395 | 396 | ||
396 | if (dst) | 397 | if (dst) |
397 | dst->ops->redirect(dst, sk, skb); | 398 | dst->ops->redirect(dst, sk, skb); |
399 | } | ||
398 | goto out; | 400 | goto out; |
399 | } | 401 | } |
400 | 402 | ||
@@ -725,11 +727,8 @@ static void tcp_v6_init_req(struct request_sock *req, | |||
725 | 727 | ||
726 | static struct dst_entry *tcp_v6_route_req(const struct sock *sk, | 728 | static struct dst_entry *tcp_v6_route_req(const struct sock *sk, |
727 | struct flowi *fl, | 729 | struct flowi *fl, |
728 | const struct request_sock *req, | 730 | const struct request_sock *req) |
729 | bool *strict) | ||
730 | { | 731 | { |
731 | if (strict) | ||
732 | *strict = true; | ||
733 | return inet6_csk_route_req(sk, &fl->u.ip6, req, IPPROTO_TCP); | 732 | return inet6_csk_route_req(sk, &fl->u.ip6, req, IPPROTO_TCP); |
734 | } | 733 | } |
735 | 734 | ||
@@ -755,7 +754,8 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { | |||
755 | .cookie_init_seq = cookie_v6_init_sequence, | 754 | .cookie_init_seq = cookie_v6_init_sequence, |
756 | #endif | 755 | #endif |
757 | .route_req = tcp_v6_route_req, | 756 | .route_req = tcp_v6_route_req, |
758 | .init_seq = tcp_v6_init_sequence, | 757 | .init_seq = tcp_v6_init_seq, |
758 | .init_ts_off = tcp_v6_init_ts_off, | ||
759 | .send_synack = tcp_v6_send_synack, | 759 | .send_synack = tcp_v6_send_synack, |
760 | }; | 760 | }; |
761 | 761 | ||
@@ -1299,8 +1299,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1299 | goto discard; | 1299 | goto discard; |
1300 | 1300 | ||
1301 | if (nsk != sk) { | 1301 | if (nsk != sk) { |
1302 | sock_rps_save_rxhash(nsk, skb); | ||
1303 | sk_mark_napi_id(nsk, skb); | ||
1304 | if (tcp_child_process(sk, nsk, skb)) | 1302 | if (tcp_child_process(sk, nsk, skb)) |
1305 | goto reset; | 1303 | goto reset; |
1306 | if (opt_skb) | 1304 | if (opt_skb) |
@@ -1919,7 +1917,7 @@ struct proto tcpv6_prot = { | |||
1919 | .sysctl_rmem = sysctl_tcp_rmem, | 1917 | .sysctl_rmem = sysctl_tcp_rmem, |
1920 | .max_header = MAX_TCP_HEADER, | 1918 | .max_header = MAX_TCP_HEADER, |
1921 | .obj_size = sizeof(struct tcp6_sock), | 1919 | .obj_size = sizeof(struct tcp6_sock), |
1922 | .slab_flags = SLAB_DESTROY_BY_RCU, | 1920 | .slab_flags = SLAB_TYPESAFE_BY_RCU, |
1923 | .twsk_prot = &tcp6_timewait_sock_ops, | 1921 | .twsk_prot = &tcp6_timewait_sock_ops, |
1924 | .rsk_prot = &tcp6_request_sock_ops, | 1922 | .rsk_prot = &tcp6_request_sock_ops, |
1925 | .h.hashinfo = &tcp_hashinfo, | 1923 | .h.hashinfo = &tcp_hashinfo, |
@@ -1931,8 +1929,9 @@ struct proto tcpv6_prot = { | |||
1931 | .diag_destroy = tcp_abort, | 1929 | .diag_destroy = tcp_abort, |
1932 | }; | 1930 | }; |
1933 | 1931 | ||
1934 | static const struct inet6_protocol tcpv6_protocol = { | 1932 | static struct inet6_protocol tcpv6_protocol = { |
1935 | .early_demux = tcp_v6_early_demux, | 1933 | .early_demux = tcp_v6_early_demux, |
1934 | .early_demux_handler = tcp_v6_early_demux, | ||
1936 | .handler = tcp_v6_rcv, | 1935 | .handler = tcp_v6_rcv, |
1937 | .err_handler = tcp_v6_err, | 1936 | .err_handler = tcp_v6_err, |
1938 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 1937 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |