l2tp: avoid using ->tunnel_sock for getting session's parent tunnel
commit 7198c77aa05560c257ee377ec1f4796812121580 upstream. 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: Guillaume Nault <g.nault@alphalink.fr> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
This commit is contained in:
parent
6fba7b6d29
commit
92fcbabfb0
|
@ -310,7 +310,6 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
|
|||
int error;
|
||||
struct l2tp_session *session;
|
||||
struct l2tp_tunnel *tunnel;
|
||||
struct pppol2tp_session *ps;
|
||||
int uhlen;
|
||||
|
||||
error = -ENOTCONN;
|
||||
|
@ -323,10 +322,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
|
|||
if (session == NULL)
|
||||
goto error;
|
||||
|
||||
ps = l2tp_session_priv(session);
|
||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
||||
if (tunnel == NULL)
|
||||
goto error_put_sess;
|
||||
tunnel = session->tunnel;
|
||||
|
||||
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
||||
|
||||
|
@ -337,7 +333,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
|
|||
sizeof(ppph) + total_len,
|
||||
0, GFP_KERNEL);
|
||||
if (!skb)
|
||||
goto error_put_sess_tun;
|
||||
goto error_put_sess;
|
||||
|
||||
/* Reserve space for headers. */
|
||||
skb_reserve(skb, NET_SKB_PAD);
|
||||
|
@ -356,20 +352,17 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
|
|||
total_len);
|
||||
if (error < 0) {
|
||||
kfree_skb(skb);
|
||||
goto error_put_sess_tun;
|
||||
goto error_put_sess;
|
||||
}
|
||||
|
||||
local_bh_disable();
|
||||
l2tp_xmit_skb(session, skb, session->hdr_len);
|
||||
local_bh_enable();
|
||||
|
||||
sock_put(ps->tunnel_sock);
|
||||
sock_put(sk);
|
||||
|
||||
return total_len;
|
||||
|
||||
error_put_sess_tun:
|
||||
sock_put(ps->tunnel_sock);
|
||||
error_put_sess:
|
||||
sock_put(sk);
|
||||
error:
|
||||
|
@ -394,10 +387,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||
{
|
||||
static const u8 ppph[2] = { 0xff, 0x03 };
|
||||
struct sock *sk = (struct sock *) chan->private;
|
||||
struct sock *sk_tun;
|
||||
struct l2tp_session *session;
|
||||
struct l2tp_tunnel *tunnel;
|
||||
struct pppol2tp_session *ps;
|
||||
int uhlen, headroom;
|
||||
|
||||
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
|
||||
|
@ -408,13 +399,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||
if (session == NULL)
|
||||
goto abort;
|
||||
|
||||
ps = l2tp_session_priv(session);
|
||||
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;
|
||||
tunnel = session->tunnel;
|
||||
|
||||
uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
|
||||
headroom = NET_SKB_PAD +
|
||||
|
@ -423,7 +408,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||
session->hdr_len + /* L2TP header */
|
||||
sizeof(ppph); /* PPP header */
|
||||
if (skb_cow_head(skb, headroom))
|
||||
goto abort_put_sess_tun;
|
||||
goto abort_put_sess;
|
||||
|
||||
/* Setup PPP header */
|
||||
__skb_push(skb, sizeof(ppph));
|
||||
|
@ -434,12 +419,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
|
|||
l2tp_xmit_skb(session, skb, session->hdr_len);
|
||||
local_bh_enable();
|
||||
|
||||
sock_put(sk_tun);
|
||||
sock_put(sk);
|
||||
|
||||
return 1;
|
||||
|
||||
abort_put_sess_tun:
|
||||
sock_put(sk_tun);
|
||||
abort_put_sess:
|
||||
sock_put(sk);
|
||||
abort:
|
||||
|
@ -935,9 +918,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||
goto end;
|
||||
|
||||
pls = l2tp_session_priv(session);
|
||||
tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock);
|
||||
if (tunnel == NULL)
|
||||
goto end_put_sess;
|
||||
tunnel = session->tunnel;
|
||||
|
||||
inet = inet_sk(tunnel->sock);
|
||||
if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) {
|
||||
|
@ -1017,8 +998,6 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
|
|||
*usockaddr_len = len;
|
||||
error = 0;
|
||||
|
||||
sock_put(pls->tunnel_sock);
|
||||
end_put_sess:
|
||||
sock_put(sk);
|
||||
end:
|
||||
return error;
|
||||
|
@ -1259,7 +1238,6 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
|
|||
struct sock *sk = sock->sk;
|
||||
struct l2tp_session *session;
|
||||
struct l2tp_tunnel *tunnel;
|
||||
struct pppol2tp_session *ps;
|
||||
int err;
|
||||
|
||||
if (!sk)
|
||||
|
@ -1283,16 +1261,10 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
|
|||
/* Special case: if session's session_id is zero, treat ioctl as a
|
||||
* tunnel ioctl
|
||||
*/
|
||||
ps = l2tp_session_priv(session);
|
||||
if ((session->session_id == 0) &&
|
||||
(session->peer_session_id == 0)) {
|
||||
err = -EBADF;
|
||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
||||
if (tunnel == NULL)
|
||||
goto end_put_sess;
|
||||
|
||||
tunnel = session->tunnel;
|
||||
err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
|
||||
sock_put(ps->tunnel_sock);
|
||||
goto end_put_sess;
|
||||
}
|
||||
|
||||
|
@ -1417,7 +1389,6 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
|||
struct sock *sk = sock->sk;
|
||||
struct l2tp_session *session;
|
||||
struct l2tp_tunnel *tunnel;
|
||||
struct pppol2tp_session *ps;
|
||||
int val;
|
||||
int err;
|
||||
|
||||
|
@ -1442,20 +1413,14 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
|||
|
||||
/* Special case: if session_id == 0x0000, treat as operation on tunnel
|
||||
*/
|
||||
ps = l2tp_session_priv(session);
|
||||
if ((session->session_id == 0) &&
|
||||
(session->peer_session_id == 0)) {
|
||||
err = -EBADF;
|
||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
||||
if (tunnel == NULL)
|
||||
goto end_put_sess;
|
||||
|
||||
tunnel = session->tunnel;
|
||||
err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
|
||||
sock_put(ps->tunnel_sock);
|
||||
} else
|
||||
} else {
|
||||
err = pppol2tp_session_setsockopt(sk, session, optname, val);
|
||||
}
|
||||
|
||||
end_put_sess:
|
||||
sock_put(sk);
|
||||
end:
|
||||
return err;
|
||||
|
@ -1543,7 +1508,6 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
|||
struct l2tp_tunnel *tunnel;
|
||||
int val, len;
|
||||
int err;
|
||||
struct pppol2tp_session *ps;
|
||||
|
||||
if (level != SOL_PPPOL2TP)
|
||||
return -EINVAL;
|
||||
|
@ -1567,16 +1531,10 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
|||
goto end;
|
||||
|
||||
/* Special case: if session_id == 0x0000, treat as operation on tunnel */
|
||||
ps = l2tp_session_priv(session);
|
||||
if ((session->session_id == 0) &&
|
||||
(session->peer_session_id == 0)) {
|
||||
err = -EBADF;
|
||||
tunnel = l2tp_sock_to_tunnel(ps->tunnel_sock);
|
||||
if (tunnel == NULL)
|
||||
goto end_put_sess;
|
||||
|
||||
tunnel = session->tunnel;
|
||||
err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
|
||||
sock_put(ps->tunnel_sock);
|
||||
if (err)
|
||||
goto end_put_sess;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue