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,  	struct inet_connection_sock *icsk = inet_csk(sk);  	struct ipv6_pinfo *np = inet6_sk(sk);  	struct tcp_sock *tp = tcp_sk(sk); -	struct in6_addr *saddr = NULL, *final_p = NULL, final; +	struct in6_addr *saddr = NULL, *final_p, final;  	struct flowi fl;  	struct dst_entry *dst;  	int addr_type; @@ -250,12 +250,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,  	fl.fl_ip_dport = usin->sin6_port;  	fl.fl_ip_sport = inet->inet_sport; -	if (np->opt && np->opt->srcrt) { -		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt; -		ipv6_addr_copy(&final, &fl.fl6_dst); -		ipv6_addr_copy(&fl.fl6_dst, rt0->addr); -		final_p = &final; -	} +	final_p = fl6_update_dst(&fl, np->opt, &final);  	security_sk_classify_flow(sk, &fl); @@ -477,7 +472,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,  	struct ipv6_pinfo *np = inet6_sk(sk);  	struct sk_buff * skb;  	struct ipv6_txoptions *opt = NULL; -	struct in6_addr * final_p = NULL, final; +	struct in6_addr * final_p, final;  	struct flowi fl;  	struct dst_entry *dst;  	int err = -1; @@ -494,12 +489,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,  	security_req_classify_flow(req, &fl);  	opt = np->opt; -	if (opt && opt->srcrt) { -		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; -		ipv6_addr_copy(&final, &fl.fl6_dst); -		ipv6_addr_copy(&fl.fl6_dst, rt0->addr); -		final_p = &final; -	} +	final_p = fl6_update_dst(&fl, opt, &final);  	err = ip6_dst_lookup(sk, &dst, &fl);  	if (err) @@ -1167,7 +1157,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)  	}  #ifdef CONFIG_SYN_COOKIES -	if (!th->rst && !th->syn && th->ack) +	if (!th->syn)  		sk = cookie_v6_check(sk, skb);  #endif  	return sk; @@ -1279,13 +1269,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)  	treq = inet6_rsk(req);  	ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr);  	ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); -	if (!want_cookie) +	if (!want_cookie || tmp_opt.tstamp_ok)  		TCP_ECN_create_request(req, tcp_hdr(skb)); -	if (want_cookie) { -		isn = cookie_v6_init_sequence(sk, skb, &req->mss); -		req->cookie_ts = tmp_opt.tstamp_ok; -	} else if (!isn) { +	if (!isn) {  		if (ipv6_opt_accepted(sk, skb) ||  		    np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||  		    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)  		if (!sk->sk_bound_dev_if &&  		    ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)  			treq->iif = inet6_iif(skb); - -		isn = tcp_v6_init_sequence(skb); +		if (!want_cookie) { +			isn = tcp_v6_init_sequence(skb); +		} else { +			isn = cookie_v6_init_sequence(sk, skb, &req->mss); +			req->cookie_ts = tmp_opt.tstamp_ok; +		}  	}  	tcp_rsk(req)->snt_isn = isn; @@ -1392,18 +1383,13 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,  		goto out_overflow;  	if (dst == NULL) { -		struct in6_addr *final_p = NULL, final; +		struct in6_addr *final_p, final;  		struct flowi fl;  		memset(&fl, 0, sizeof(fl));  		fl.proto = IPPROTO_TCP;  		ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); -		if (opt && opt->srcrt) { -			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; -			ipv6_addr_copy(&final, &fl.fl6_dst); -			ipv6_addr_copy(&fl.fl6_dst, rt0->addr); -			final_p = &final; -		} +		final_p = fl6_update_dst(&fl, opt, &final);  		ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);  		fl.oif = sk->sk_bound_dev_if;  		fl.mark = sk->sk_mark; @@ -2156,6 +2142,8 @@ struct proto tcpv6_prot = {  	.setsockopt		= tcp_setsockopt,  	.getsockopt		= tcp_getsockopt,  	.recvmsg		= tcp_recvmsg, +	.sendmsg		= tcp_sendmsg, +	.sendpage		= tcp_sendpage,  	.backlog_rcv		= tcp_v6_do_rcv,  	.hash			= tcp_v6_hash,  	.unhash			= inet_unhash, @@ -2174,6 +2162,7 @@ struct proto tcpv6_prot = {  	.twsk_prot		= &tcp6_timewait_sock_ops,  	.rsk_prot		= &tcp6_request_sock_ops,  	.h.hashinfo		= &tcp_hashinfo, +	.no_autobind		= true,  #ifdef CONFIG_COMPAT  	.compat_setsockopt	= compat_tcp_setsockopt,  	.compat_getsockopt	= compat_tcp_getsockopt,  | 
