diff options
| author | James Morris <james.l.morris@oracle.com> | 2017-11-29 12:47:41 +1100 | 
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2017-11-29 12:47:41 +1100 | 
| commit | cf40a76e7d5874bb25f4404eecc58a2e033af885 (patch) | |
| tree | 8fd81cbea03c87b3d41d7ae5b1d11eadd35d6ef5 /net/ipv4/inet_connection_sock.c | |
| parent | ab5348c9c23cd253f5902980d2d8fe067dc24c82 (diff) | |
| parent | 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff) | |
Merge tag 'v4.15-rc1' into next-seccomp
Linux 4.15-rc1
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
| -rw-r--r-- | net/ipv4/inet_connection_sock.c | 75 | 
1 files changed, 37 insertions, 38 deletions
| diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 4089c013cb03..4ca46dc08e63 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -39,11 +39,11 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);   *                          IPV6_ADDR_ANY only equals to IPV6_ADDR_ANY,   *                          and 0.0.0.0 equals to 0.0.0.0 only   */ -static int ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, -				const struct in6_addr *sk2_rcv_saddr6, -				__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, -				bool sk1_ipv6only, bool sk2_ipv6only, -				bool match_wildcard) +static bool ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6, +				 const struct in6_addr *sk2_rcv_saddr6, +				 __be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, +				 bool sk1_ipv6only, bool sk2_ipv6only, +				 bool match_wildcard)  {  	int addr_type = ipv6_addr_type(sk1_rcv_saddr6);  	int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED; @@ -52,29 +52,29 @@ static int ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6,  	if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED) {  		if (!sk2_ipv6only) {  			if (sk1_rcv_saddr == sk2_rcv_saddr) -				return 1; +				return true;  			if (!sk1_rcv_saddr || !sk2_rcv_saddr)  				return match_wildcard;  		} -		return 0; +		return false;  	}  	if (addr_type == IPV6_ADDR_ANY && addr_type2 == IPV6_ADDR_ANY) -		return 1; +		return true;  	if (addr_type2 == IPV6_ADDR_ANY && match_wildcard &&  	    !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED)) -		return 1; +		return true;  	if (addr_type == IPV6_ADDR_ANY && match_wildcard &&  	    !(sk1_ipv6only && addr_type2 == IPV6_ADDR_MAPPED)) -		return 1; +		return true;  	if (sk2_rcv_saddr6 &&  	    ipv6_addr_equal(sk1_rcv_saddr6, sk2_rcv_saddr6)) -		return 1; +		return true; -	return 0; +	return false;  }  #endif @@ -82,20 +82,20 @@ static int ipv6_rcv_saddr_equal(const struct in6_addr *sk1_rcv_saddr6,   * match_wildcard == false: addresses must be exactly the same, i.e.   *                          0.0.0.0 only equals to 0.0.0.0   */ -static int ipv4_rcv_saddr_equal(__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, -				bool sk2_ipv6only, bool match_wildcard) +static bool ipv4_rcv_saddr_equal(__be32 sk1_rcv_saddr, __be32 sk2_rcv_saddr, +				 bool sk2_ipv6only, bool match_wildcard)  {  	if (!sk2_ipv6only) {  		if (sk1_rcv_saddr == sk2_rcv_saddr) -			return 1; +			return true;  		if (!sk1_rcv_saddr || !sk2_rcv_saddr)  			return match_wildcard;  	} -	return 0; +	return false;  } -int inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2, -			 bool match_wildcard) +bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2, +			  bool match_wildcard)  {  #if IS_ENABLED(CONFIG_IPV6)  	if (sk->sk_family == AF_INET6) @@ -266,7 +266,7 @@ static inline int sk_reuseport_match(struct inet_bind_bucket *tb,  #if IS_ENABLED(CONFIG_IPV6)  	if (tb->fast_sk_family == AF_INET6)  		return ipv6_rcv_saddr_equal(&tb->fast_v6_rcv_saddr, -					    &sk->sk_v6_rcv_saddr, +					    inet6_rcv_saddr(sk),  					    tb->fast_rcv_saddr,  					    sk->sk_rcv_saddr,  					    tb->fast_ipv6_only, @@ -321,13 +321,14 @@ tb_found:  			goto fail_unlock;  	}  success: -	if (!hlist_empty(&tb->owners)) { +	if (hlist_empty(&tb->owners)) {  		tb->fastreuse = reuse;  		if (sk->sk_reuseport) {  			tb->fastreuseport = FASTREUSEPORT_ANY;  			tb->fastuid = uid;  			tb->fast_rcv_saddr = sk->sk_rcv_saddr;  			tb->fast_ipv6_only = ipv6_only_sock(sk); +			tb->fast_sk_family = sk->sk_family;  #if IS_ENABLED(CONFIG_IPV6)  			tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;  #endif @@ -354,6 +355,7 @@ success:  				tb->fastuid = uid;  				tb->fast_rcv_saddr = sk->sk_rcv_saddr;  				tb->fast_ipv6_only = ipv6_only_sock(sk); +				tb->fast_sk_family = sk->sk_family;  #if IS_ENABLED(CONFIG_IPV6)  				tb->fast_v6_rcv_saddr = sk->sk_v6_rcv_saddr;  #endif @@ -473,6 +475,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern)  		}  		spin_unlock_bh(&queue->fastopenq.lock);  	} +	mem_cgroup_sk_alloc(newsk);  out:  	release_sock(sk);  	if (req) @@ -492,17 +495,15 @@ EXPORT_SYMBOL(inet_csk_accept);   * to optimize.   */  void inet_csk_init_xmit_timers(struct sock *sk, -			       void (*retransmit_handler)(unsigned long), -			       void (*delack_handler)(unsigned long), -			       void (*keepalive_handler)(unsigned long)) +			       void (*retransmit_handler)(struct timer_list *t), +			       void (*delack_handler)(struct timer_list *t), +			       void (*keepalive_handler)(struct timer_list *t))  {  	struct inet_connection_sock *icsk = inet_csk(sk); -	setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler, -			(unsigned long)sk); -	setup_timer(&icsk->icsk_delack_timer, delack_handler, -			(unsigned long)sk); -	setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk); +	timer_setup(&icsk->icsk_retransmit_timer, retransmit_handler, 0); +	timer_setup(&icsk->icsk_delack_timer, delack_handler, 0); +	timer_setup(&sk->sk_timer, keepalive_handler, 0);  	icsk->icsk_pending = icsk->icsk_ack.pending = 0;  }  EXPORT_SYMBOL(inet_csk_init_xmit_timers); @@ -537,9 +538,11 @@ struct dst_entry *inet_csk_route_req(const struct sock *sk,  {  	const struct inet_request_sock *ireq = inet_rsk(req);  	struct net *net = read_pnet(&ireq->ireq_net); -	struct ip_options_rcu *opt = ireq->opt; +	struct ip_options_rcu *opt;  	struct rtable *rt; +	opt = ireq_opt_deref(ireq); +  	flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,  			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,  			   sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -573,10 +576,9 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,  	struct flowi4 *fl4;  	struct rtable *rt; +	opt = rcu_dereference(ireq->ireq_opt);  	fl4 = &newinet->cork.fl.u.ip4; -	rcu_read_lock(); -	opt = rcu_dereference(newinet->inet_opt);  	flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark,  			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,  			   sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -589,13 +591,11 @@ struct dst_entry *inet_csk_route_child_sock(const struct sock *sk,  		goto no_route;  	if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)  		goto route_err; -	rcu_read_unlock();  	return &rt->dst;  route_err:  	ip_rt_put(rt);  no_route: -	rcu_read_unlock();  	__IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);  	return NULL;  } @@ -674,9 +674,9 @@ void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req  }  EXPORT_SYMBOL(inet_csk_reqsk_queue_drop_and_put); -static void reqsk_timer_handler(unsigned long data) +static void reqsk_timer_handler(struct timer_list *t)  { -	struct request_sock *req = (struct request_sock *)data; +	struct request_sock *req = from_timer(req, t, rsk_timer);  	struct sock *sk_listener = req->rsk_listener;  	struct net *net = sock_net(sk_listener);  	struct inet_connection_sock *icsk = inet_csk(sk_listener); @@ -747,8 +747,7 @@ static void reqsk_queue_hash_req(struct request_sock *req,  	req->num_timeout = 0;  	req->sk = NULL; -	setup_pinned_timer(&req->rsk_timer, reqsk_timer_handler, -			    (unsigned long)req); +	timer_setup(&req->rsk_timer, reqsk_timer_handler, TIMER_PINNED);  	mod_timer(&req->rsk_timer, jiffies + timeout);  	inet_ehash_insert(req_to_sk(req), NULL); @@ -916,7 +915,6 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req,  		tcp_sk(child)->fastopen_rsk = NULL;  	}  	inet_csk_destroy_sock(child); -	reqsk_put(req);  }  struct sock *inet_csk_reqsk_queue_add(struct sock *sk, @@ -987,6 +985,7 @@ void inet_csk_listen_stop(struct sock *sk)  		sock_hold(child);  		inet_child_forget(sk, req, child); +		reqsk_put(req);  		bh_unlock_sock(child);  		local_bh_enable();  		sock_put(child); | 
