diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 47 |
1 files changed, 18 insertions, 29 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2b7c3a100e2c..fe6d40418c0b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -129,7 +129,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
129 | struct inet_connection_sock *icsk = inet_csk(sk); | 129 | struct inet_connection_sock *icsk = inet_csk(sk); |
130 | struct ipv6_pinfo *np = inet6_sk(sk); | 130 | struct ipv6_pinfo *np = inet6_sk(sk); |
131 | struct tcp_sock *tp = tcp_sk(sk); | 131 | struct tcp_sock *tp = tcp_sk(sk); |
132 | struct in6_addr *saddr = NULL, *final_p = NULL, final; | 132 | struct in6_addr *saddr = NULL, *final_p, final; |
133 | struct flowi fl; | 133 | struct flowi fl; |
134 | struct dst_entry *dst; | 134 | struct dst_entry *dst; |
135 | int addr_type; | 135 | int addr_type; |
@@ -250,12 +250,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
250 | fl.fl_ip_dport = usin->sin6_port; | 250 | fl.fl_ip_dport = usin->sin6_port; |
251 | fl.fl_ip_sport = inet->inet_sport; | 251 | fl.fl_ip_sport = inet->inet_sport; |
252 | 252 | ||
253 | if (np->opt && np->opt->srcrt) { | 253 | final_p = fl6_update_dst(&fl, np->opt, &final); |
254 | struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; | ||
255 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
256 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
257 | final_p = &final; | ||
258 | } | ||
259 | 254 | ||
260 | security_sk_classify_flow(sk, &fl); | 255 | security_sk_classify_flow(sk, &fl); |
261 | 256 | ||
@@ -477,7 +472,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
477 | struct ipv6_pinfo *np = inet6_sk(sk); | 472 | struct ipv6_pinfo *np = inet6_sk(sk); |
478 | struct sk_buff * skb; | 473 | struct sk_buff * skb; |
479 | struct ipv6_txoptions *opt = NULL; | 474 | struct ipv6_txoptions *opt = NULL; |
480 | struct in6_addr * final_p = NULL, final; | 475 | struct in6_addr * final_p, final; |
481 | struct flowi fl; | 476 | struct flowi fl; |
482 | struct dst_entry *dst; | 477 | struct dst_entry *dst; |
483 | int err = -1; | 478 | int err = -1; |
@@ -494,12 +489,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
494 | security_req_classify_flow(req, &fl); | 489 | security_req_classify_flow(req, &fl); |
495 | 490 | ||
496 | opt = np->opt; | 491 | opt = np->opt; |
497 | if (opt && opt->srcrt) { | 492 | final_p = fl6_update_dst(&fl, opt, &final); |
498 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; | ||
499 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
500 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
501 | final_p = &final; | ||
502 | } | ||
503 | 493 | ||
504 | err = ip6_dst_lookup(sk, &dst, &fl); | 494 | err = ip6_dst_lookup(sk, &dst, &fl); |
505 | if (err) | 495 | if (err) |
@@ -1167,7 +1157,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) | |||
1167 | } | 1157 | } |
1168 | 1158 | ||
1169 | #ifdef CONFIG_SYN_COOKIES | 1159 | #ifdef CONFIG_SYN_COOKIES |
1170 | if (!th->rst && !th->syn && th->ack) | 1160 | if (!th->syn) |
1171 | sk = cookie_v6_check(sk, skb); | 1161 | sk = cookie_v6_check(sk, skb); |
1172 | #endif | 1162 | #endif |
1173 | return sk; | 1163 | return sk; |
@@ -1279,13 +1269,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1279 | treq = inet6_rsk(req); | 1269 | treq = inet6_rsk(req); |
1280 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); | 1270 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); |
1281 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); | 1271 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); |
1282 | if (!want_cookie) | 1272 | if (!want_cookie || tmp_opt.tstamp_ok) |
1283 | TCP_ECN_create_request(req, tcp_hdr(skb)); | 1273 | TCP_ECN_create_request(req, tcp_hdr(skb)); |
1284 | 1274 | ||
1285 | if (want_cookie) { | 1275 | if (!isn) { |
1286 | isn = cookie_v6_init_sequence(sk, skb, &req->mss); | ||
1287 | req->cookie_ts = tmp_opt.tstamp_ok; | ||
1288 | } else if (!isn) { | ||
1289 | if (ipv6_opt_accepted(sk, skb) || | 1276 | if (ipv6_opt_accepted(sk, skb) || |
1290 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || | 1277 | np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || |
1291 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { | 1278 | np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) { |
@@ -1298,8 +1285,12 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
1298 | if (!sk->sk_bound_dev_if && | 1285 | if (!sk->sk_bound_dev_if && |
1299 | ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) | 1286 | ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) |
1300 | treq->iif = inet6_iif(skb); | 1287 | treq->iif = inet6_iif(skb); |
1301 | 1288 | if (!want_cookie) { | |
1302 | isn = tcp_v6_init_sequence(skb); | 1289 | isn = tcp_v6_init_sequence(skb); |
1290 | } else { | ||
1291 | isn = cookie_v6_init_sequence(sk, skb, &req->mss); | ||
1292 | req->cookie_ts = tmp_opt.tstamp_ok; | ||
1293 | } | ||
1303 | } | 1294 | } |
1304 | tcp_rsk(req)->snt_isn = isn; | 1295 | tcp_rsk(req)->snt_isn = isn; |
1305 | 1296 | ||
@@ -1392,18 +1383,13 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1392 | goto out_overflow; | 1383 | goto out_overflow; |
1393 | 1384 | ||
1394 | if (dst == NULL) { | 1385 | if (dst == NULL) { |
1395 | struct in6_addr *final_p = NULL, final; | 1386 | struct in6_addr *final_p, final; |
1396 | struct flowi fl; | 1387 | struct flowi fl; |
1397 | 1388 | ||
1398 | memset(&fl, 0, sizeof(fl)); | 1389 | memset(&fl, 0, sizeof(fl)); |
1399 | fl.proto = IPPROTO_TCP; | 1390 | fl.proto = IPPROTO_TCP; |
1400 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); | 1391 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); |
1401 | if (opt && opt->srcrt) { | 1392 | final_p = fl6_update_dst(&fl, opt, &final); |
1402 | struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; | ||
1403 | ipv6_addr_copy(&final, &fl.fl6_dst); | ||
1404 | ipv6_addr_copy(&fl.fl6_dst, rt0->addr); | ||
1405 | final_p = &final; | ||
1406 | } | ||
1407 | ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); | 1393 | ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); |
1408 | fl.oif = sk->sk_bound_dev_if; | 1394 | fl.oif = sk->sk_bound_dev_if; |
1409 | fl.mark = sk->sk_mark; | 1395 | fl.mark = sk->sk_mark; |
@@ -2156,6 +2142,8 @@ struct proto tcpv6_prot = { | |||
2156 | .setsockopt = tcp_setsockopt, | 2142 | .setsockopt = tcp_setsockopt, |
2157 | .getsockopt = tcp_getsockopt, | 2143 | .getsockopt = tcp_getsockopt, |
2158 | .recvmsg = tcp_recvmsg, | 2144 | .recvmsg = tcp_recvmsg, |
2145 | .sendmsg = tcp_sendmsg, | ||
2146 | .sendpage = tcp_sendpage, | ||
2159 | .backlog_rcv = tcp_v6_do_rcv, | 2147 | .backlog_rcv = tcp_v6_do_rcv, |
2160 | .hash = tcp_v6_hash, | 2148 | .hash = tcp_v6_hash, |
2161 | .unhash = inet_unhash, | 2149 | .unhash = inet_unhash, |
@@ -2174,6 +2162,7 @@ struct proto tcpv6_prot = { | |||
2174 | .twsk_prot = &tcp6_timewait_sock_ops, | 2162 | .twsk_prot = &tcp6_timewait_sock_ops, |
2175 | .rsk_prot = &tcp6_request_sock_ops, | 2163 | .rsk_prot = &tcp6_request_sock_ops, |
2176 | .h.hashinfo = &tcp_hashinfo, | 2164 | .h.hashinfo = &tcp_hashinfo, |
2165 | .no_autobind = true, | ||
2177 | #ifdef CONFIG_COMPAT | 2166 | #ifdef CONFIG_COMPAT |
2178 | .compat_setsockopt = compat_tcp_setsockopt, | 2167 | .compat_setsockopt = compat_tcp_setsockopt, |
2179 | .compat_getsockopt = compat_tcp_getsockopt, | 2168 | .compat_getsockopt = compat_tcp_getsockopt, |