Commit 973573c4 authored by David S. Miller's avatar David S. Miller

Merge branch 'l2tp-avoid-aliasing-tunnels-socket-pointer'

Guillaume Nault says:

====================
l2tp: avoid aliasing tunnels socket pointer

We don't need to copy the tunnel's socket pointer in the pseudo-wire
specific session structures. This uselessly complicates the code
and hampers evolution.

This series was part of an effort to protect tunnels socket pointer
with RCU. But since it provides nice cleanup, I submit it separately.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 93f7ea74 da9ca825
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
/* via netdev_priv() */ /* via netdev_priv() */
struct l2tp_eth { struct l2tp_eth {
struct sock *tunnel_sock;
struct l2tp_session *session; struct l2tp_session *session;
atomic_long_t tx_bytes; atomic_long_t tx_bytes;
atomic_long_t tx_packets; atomic_long_t tx_packets;
...@@ -313,7 +312,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel, ...@@ -313,7 +312,6 @@ static int l2tp_eth_create(struct net *net, struct l2tp_tunnel *tunnel,
priv = netdev_priv(dev); priv = netdev_priv(dev);
priv->session = session; priv->session = session;
priv->tunnel_sock = tunnel->sock;
session->recv_skb = l2tp_eth_dev_recv; session->recv_skb = l2tp_eth_dev_recv;
session->session_close = l2tp_eth_delete; session->session_close = l2tp_eth_delete;
#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) #if IS_ENABLED(CONFIG_L2TP_DEBUGFS)
......
...@@ -127,8 +127,6 @@ struct pppol2tp_session { ...@@ -127,8 +127,6 @@ struct pppol2tp_session {
* PPPoX socket */ * PPPoX socket */
struct sock *__sk; /* Copy of .sk, for cleanup */ struct sock *__sk; /* Copy of .sk, for cleanup */
struct rcu_head rcu; /* For asynchronous release */ struct rcu_head rcu; /* For asynchronous release */
struct sock *tunnel_sock; /* Pointer to the tunnel UDP
* socket */
int flags; /* accessed by PPPIOCGFLAGS. int flags; /* accessed by PPPIOCGFLAGS.
* Unused. */ * Unused. */
}; };
...@@ -295,7 +293,6 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -295,7 +293,6 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
int error; int error;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel; struct l2tp_tunnel *tunnel;
struct pppol2tp_session *ps;
int uhlen; int uhlen;
error = -ENOTCONN; error = -ENOTCONN;
...@@ -308,10 +305,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -308,10 +305,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
if (session == NULL) if (session == NULL)
goto error; goto error;
ps = l2tp_session_priv(session); tunnel = session->tunnel;
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
if (tunnel == NULL)
goto error_put_sess;
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
...@@ -322,7 +316,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -322,7 +316,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ 2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
0, GFP_KERNEL); 0, GFP_KERNEL);
if (!skb) if (!skb)
goto error_put_sess_tun; goto error_put_sess;
/* Reserve space for headers. */ /* Reserve space for headers. */
skb_reserve(skb, NET_SKB_PAD); skb_reserve(skb, NET_SKB_PAD);
...@@ -340,20 +334,17 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -340,20 +334,17 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
error = memcpy_from_msg(skb_put(skb, total_len), m, total_len); error = memcpy_from_msg(skb_put(skb, total_len), m, total_len);
if (error < 0) { if (error < 0) {
kfree_skb(skb); kfree_skb(skb);
goto error_put_sess_tun; goto error_put_sess;
} }
local_bh_disable(); local_bh_disable();
l2tp_xmit_skb(session, skb, session->hdr_len); l2tp_xmit_skb(session, skb, session->hdr_len);
local_bh_enable(); local_bh_enable();
sock_put(ps->tunnel_sock);
sock_put(sk); sock_put(sk);
return total_len; return total_len;
error_put_sess_tun:
sock_put(ps->tunnel_sock);
error_put_sess: error_put_sess:
sock_put(sk); sock_put(sk);
error: error:
...@@ -377,10 +368,8 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -377,10 +368,8 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{ {
struct sock *sk = (struct sock *) chan->private; struct sock *sk = (struct sock *) chan->private;
struct sock *sk_tun;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel; struct l2tp_tunnel *tunnel;
struct pppol2tp_session *ps;
int uhlen, headroom; int uhlen, headroom;
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
...@@ -391,13 +380,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -391,13 +380,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
if (session == NULL) if (session == NULL)
goto abort; goto abort;
ps = l2tp_session_priv(session); tunnel = session->tunnel;
sk_tun = ps->tunnel_sock;
if (sk_tun == NULL)
goto abort_put_sess;
tunnel = l2tp_sock_to_tunnel(sk_tun);
if (tunnel == NULL)
goto abort_put_sess;
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
headroom = NET_SKB_PAD + headroom = NET_SKB_PAD +
...@@ -406,7 +389,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -406,7 +389,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
session->hdr_len + /* L2TP header */ session->hdr_len + /* L2TP header */
2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ 2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
if (skb_cow_head(skb, headroom)) if (skb_cow_head(skb, headroom))
goto abort_put_sess_tun; goto abort_put_sess;
/* Setup PPP header */ /* Setup PPP header */
__skb_push(skb, 2); __skb_push(skb, 2);
...@@ -417,12 +400,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -417,12 +400,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
l2tp_xmit_skb(session, skb, session->hdr_len); l2tp_xmit_skb(session, skb, session->hdr_len);
local_bh_enable(); local_bh_enable();
sock_put(sk_tun);
sock_put(sk); sock_put(sk);
return 1; return 1;
abort_put_sess_tun:
sock_put(sk_tun);
abort_put_sess: abort_put_sess:
sock_put(sk); sock_put(sk);
abort: abort:
...@@ -609,7 +590,6 @@ static void pppol2tp_session_init(struct l2tp_session *session) ...@@ -609,7 +590,6 @@ static void pppol2tp_session_init(struct l2tp_session *session)
ps = l2tp_session_priv(session); ps = l2tp_session_priv(session);
mutex_init(&ps->sk_lock); mutex_init(&ps->sk_lock);
ps->tunnel_sock = session->tunnel->sock;
ps->owner = current->pid; ps->owner = current->pid;
/* If PMTU discovery was enabled, use the MTU that was discovered */ /* If PMTU discovery was enabled, use the MTU that was discovered */
...@@ -760,13 +740,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, ...@@ -760,13 +740,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
error = -EEXIST; error = -EEXIST;
goto end; goto end;
} }
/* consistency checks */
if (ps->tunnel_sock != tunnel->sock) {
mutex_unlock(&ps->sk_lock);
error = -EEXIST;
goto end;
}
} else { } else {
/* Default MTU must allow space for UDP/L2TP/PPP headers */ /* Default MTU must allow space for UDP/L2TP/PPP headers */
cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
...@@ -919,9 +892,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -919,9 +892,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
goto end; goto end;
pls = l2tp_session_priv(session); pls = l2tp_session_priv(session);
tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock); tunnel = session->tunnel;
if (tunnel == NULL)
goto end_put_sess;
inet = inet_sk(tunnel->sock); inet = inet_sk(tunnel->sock);
if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) { if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) {
...@@ -1001,8 +972,6 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1001,8 +972,6 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
*usockaddr_len = len; *usockaddr_len = len;
error = 0; error = 0;
sock_put(pls->tunnel_sock);
end_put_sess:
sock_put(sk); sock_put(sk);
end: end:
return error; return error;
...@@ -1241,7 +1210,6 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1241,7 +1210,6 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel; struct l2tp_tunnel *tunnel;
struct pppol2tp_session *ps;
int err; int err;
if (!sk) if (!sk)
...@@ -1265,16 +1233,10 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1265,16 +1233,10 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
/* Special case: if session's session_id is zero, treat ioctl as a /* Special case: if session's session_id is zero, treat ioctl as a
* tunnel ioctl * tunnel ioctl
*/ */
ps = l2tp_session_priv(session);
if ((session->session_id == 0) && if ((session->session_id == 0) &&
(session->peer_session_id == 0)) { (session->peer_session_id == 0)) {
err = -EBADF; tunnel = session->tunnel;
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
if (tunnel == NULL)
goto end_put_sess;
err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
sock_put(ps->tunnel_sock);
goto end_put_sess; goto end_put_sess;
} }
...@@ -1400,7 +1362,6 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, ...@@ -1400,7 +1362,6 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct l2tp_session *session; struct l2tp_session *session;
struct l2tp_tunnel *tunnel; struct l2tp_tunnel *tunnel;
struct pppol2tp_session *ps;
int val; int val;
int err; int err;
...@@ -1425,20 +1386,14 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, ...@@ -1425,20 +1386,14 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
/* Special case: if session_id == 0x0000, treat as operation on tunnel /* Special case: if session_id == 0x0000, treat as operation on tunnel
*/ */
ps = l2tp_session_priv(session);
if ((session->session_id == 0) && if ((session->session_id == 0) &&
(session->peer_session_id == 0)) { (session->peer_session_id == 0)) {
err = -EBADF; tunnel = session->tunnel;
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
if (tunnel == NULL)
goto end_put_sess;
err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
sock_put(ps->tunnel_sock); } else {
} else
err = pppol2tp_session_setsockopt(sk, session, optname, val); err = pppol2tp_session_setsockopt(sk, session, optname, val);
}
end_put_sess:
sock_put(sk); sock_put(sk);
end: end:
return err; return err;
...@@ -1526,7 +1481,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, ...@@ -1526,7 +1481,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
struct l2tp_tunnel *tunnel; struct l2tp_tunnel *tunnel;
int val, len; int val, len;
int err; int err;
struct pppol2tp_session *ps;
if (level != SOL_PPPOL2TP) if (level != SOL_PPPOL2TP)
return -EINVAL; return -EINVAL;
...@@ -1550,16 +1504,10 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, ...@@ -1550,16 +1504,10 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
goto end; goto end;
/* Special case: if session_id == 0x0000, treat as operation on tunnel */ /* Special case: if session_id == 0x0000, treat as operation on tunnel */
ps = l2tp_session_priv(session);
if ((session->session_id == 0) && if ((session->session_id == 0) &&
(session->peer_session_id == 0)) { (session->peer_session_id == 0)) {
err = -EBADF; tunnel = session->tunnel;
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
if (tunnel == NULL)
goto end_put_sess;
err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
sock_put(ps->tunnel_sock);
if (err) if (err)
goto end_put_sess; goto end_put_sess;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment