diff options
Diffstat (limited to 'net/ipv4/inet_connection_sock.c')
| -rw-r--r-- | net/ipv4/inet_connection_sock.c | 16 | 
1 files changed, 9 insertions, 7 deletions
| diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index b9c64b40a83a..b47a59cb3573 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -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) @@ -537,9 +540,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 +578,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 +593,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;  } |