Commit 7198c77a authored by Guillaume Nault's avatar Guillaume Nault Committed by David S. Miller

l2tp: avoid using ->tunnel_sock for getting session's parent tunnel

Sessions don't need to use l2tp_sock_to_tunnel(xxx->tunnel_sock) for
accessing their parent tunnel. They have the .tunnel field in the
l2tp_session structure for that. Furthermore, in all these cases, the
session is registered, so we're guaranteed that .tunnel isn't NULL and
that the session properly holds a reference on the tunnel.
Signed-off-by: default avatarGuillaume Nault <g.nault@alphalink.fr>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8fdfd659
...@@ -295,7 +295,6 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -295,7 +295,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 +307,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -308,10 +307,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 +318,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -322,7 +318,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 +336,17 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -340,20 +336,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 +370,8 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, ...@@ -377,10 +370,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 +382,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -391,13 +382,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 +391,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -406,7 +391,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 +402,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) ...@@ -417,12 +402,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:
...@@ -919,9 +902,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -919,9 +902,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 +982,6 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1001,8 +982,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 +1220,6 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1241,7 +1220,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 +1243,10 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd, ...@@ -1265,16 +1243,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 +1372,6 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, ...@@ -1400,7 +1372,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 +1396,14 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, ...@@ -1425,20 +1396,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 +1491,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, ...@@ -1526,7 +1491,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 +1514,10 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname, ...@@ -1550,16 +1514,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