inet: add RCU protection to inet->opt
[deliverable/linux.git] / net / l2tp / l2tp_ip.c
index fce9bd3bd3feb61c3b6a2fbc078d9a5b8f7462c5..962a607b51da8400cd043d7410bba093db145f0a 100644 (file)
@@ -296,12 +296,12 @@ out_in_use:
 
 static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
-       int rc;
-       struct inet_sock *inet = inet_sk(sk);
        struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
+       struct inet_sock *inet = inet_sk(sk);
+       struct flowi4 fl4;
        struct rtable *rt;
        __be32 saddr;
-       int oif;
+       int oif, rc;
 
        rc = -EINVAL;
        if (addr_len < sizeof(*lsa))
@@ -320,7 +320,7 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
        if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
                goto out;
 
-       rt = ip_route_connect(lsa->l2tp_addr.s_addr, saddr,
+       rt = ip_route_connect(&fl4, lsa->l2tp_addr.s_addr, saddr,
                              RT_CONN_FLAGS(sk), oif,
                              IPPROTO_L2TP,
                              0, 0, sk, true);
@@ -416,7 +416,6 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
        int rc;
        struct l2tp_ip_sock *lsa = l2tp_ip_sk(sk);
        struct inet_sock *inet = inet_sk(sk);
-       struct ip_options *opt = inet->opt;
        struct rtable *rt = NULL;
        int connected = 0;
        __be32 daddr;
@@ -471,9 +470,14 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
                rt = (struct rtable *) __sk_dst_check(sk, 0);
 
        if (rt == NULL) {
+               struct ip_options_rcu *inet_opt;
+
+               inet_opt = rcu_dereference_protected(inet->inet_opt,
+                                                    sock_owned_by_user(sk));
+
                /* Use correct destination address if we have options. */
-               if (opt && opt->srr)
-                       daddr = opt->faddr;
+               if (inet_opt && inet_opt->opt.srr)
+                       daddr = inet_opt->opt.faddr;
 
                /* If this fails, retransmit mechanism of transport layer will
                 * keep trying until route appears or the connection times
This page took 0.025095 seconds and 5 git commands to generate.