|
@@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
|
|
|
{
|
|
|
const struct inet_request_sock *ireq = inet_rsk(req);
|
|
|
struct inet_sock *newinet = inet_sk(newsk);
|
|
|
- struct ip_options_rcu *opt = ireq->opt;
|
|
|
+ struct ip_options_rcu *opt;
|
|
|
struct net *net = sock_net(sk);
|
|
|
struct flowi4 *fl4;
|
|
|
struct rtable *rt;
|
|
|
|
|
|
fl4 = &newinet->cork.fl.u.ip4;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ opt = rcu_dereference(newinet->inet_opt);
|
|
|
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
|
|
|
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
|
|
|
sk->sk_protocol, inet_sk_flowi_flags(sk),
|
|
@@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
|
|
|
goto no_route;
|
|
|
if (opt && opt->opt.is_strictroute && rt->rt_gateway)
|
|
|
goto route_err;
|
|
|
+ rcu_read_unlock();
|
|
|
return &rt->dst;
|
|
|
|
|
|
route_err:
|
|
|
ip_rt_put(rt);
|
|
|
no_route:
|
|
|
+ rcu_read_unlock();
|
|
|
IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
|
|
|
return NULL;
|
|
|
}
|