Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+12 −54
Original line number Diff line number Diff line
@@ -295,7 +295,6 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
	int error;
	struct l2tp_session *session;
	struct l2tp_tunnel *tunnel;
	struct pppol2tp_session *ps;
	int uhlen;

	error = -ENOTCONN;
@@ -308,10 +307,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
	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;

@@ -322,7 +318,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m,
			   2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
			   0, GFP_KERNEL);
	if (!skb)
		goto error_put_sess_tun;
		goto error_put_sess;

	/* Reserve space for headers. */
	skb_reserve(skb, NET_SKB_PAD);
@@ -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);
	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:
@@ -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)
{
	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))
@@ -391,13 +382,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 +
@@ -406,7 +391,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
		   session->hdr_len +	/* L2TP header */
		   2;			/* 2 bytes for PPP_ALLSTATIONS & PPP_UI */
	if (skb_cow_head(skb, headroom))
		goto abort_put_sess_tun;
		goto abort_put_sess;

	/* Setup PPP header */
	__skb_push(skb, 2);
@@ -417,12 +402,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:
@@ -919,9 +902,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)) {
@@ -1001,8 +982,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;
@@ -1241,7 +1220,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)
@@ -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
	 * 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;
	}

@@ -1400,7 +1372,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;

@@ -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
	 */
	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;
@@ -1526,7 +1491,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;
@@ -1550,16 +1514,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 {