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.c47
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,