]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/ipv4/inet_connection_sock.c
x86/xen: Reset VCPU0 info pointer after shared_info remap
[mirror_ubuntu-artful-kernel.git] / net / ipv4 / inet_connection_sock.c
index 4089c013cb03b12e31ddffbb7ae903542c012ae0..3ca531d29d2f0993a8f233bdc5b88bc952062bed 100644 (file)
@@ -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
@@ -537,9 +539,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 +577,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 +592,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;
 }