summary refs log tree commit diff
path: root/net/l2tp
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2018-08-10 13:21:58 +0200
committerDavid S. Miller <davem@davemloft.net>2018-08-11 12:13:49 -0700
commit79e6760e64d1b69a20af4d97ead291159d4c11c2 (patch)
tree5a28c42dd33fb727f38e45ea2a25722cc60d32be /net/l2tp
parentbdd0292f96e43de46283ea0efdef8d13b4ffe895 (diff)
downloadlinux-79e6760e64d1b69a20af4d97ead291159d4c11c2.tar.gz
l2tp: handle PPPIOC[GS]MRU and PPPIOC[GS]FLAGS in pppol2tp_ioctl()
Let pppol2tp_ioctl() handle ioctl commands directly. It still relies on
pppol2tp_{session,tunnel}_ioctl() for PPPIOCGL2TPSTATS.

Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp')
-rw-r--r--net/l2tp/l2tp_ppp.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index e3ed8d473d91..f4ec6b2a093e 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1045,7 +1045,6 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session,
 {
 	int err = 0;
 	struct sock *sk;
-	int val = (int) arg;
 	struct l2tp_tunnel *tunnel = session->tunnel;
 	struct pppol2tp_ioc_stats stats;
 
@@ -1058,22 +1057,6 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session,
 		return -EBADR;
 
 	switch (cmd) {
-	case PPPIOCGMRU:
-	case PPPIOCGFLAGS:
-		err = -EFAULT;
-		if (put_user(0, (int __user *)arg))
-			break;
-		err = 0;
-		break;
-
-	case PPPIOCSMRU:
-	case PPPIOCSFLAGS:
-		err = -EFAULT;
-		if (get_user(val, (int __user *)arg))
-			break;
-		err = 0;
-		break;
-
 	case PPPIOCGL2TPSTATS:
 		err = -ENXIO;
 		if (!(sk->sk_state & PPPOX_CONNECTED))
@@ -1180,23 +1163,55 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
 			  unsigned long arg)
 {
 	struct l2tp_session *session;
-	struct l2tp_tunnel *tunnel;
+	int val;
+
+	switch (cmd) {
+	case PPPIOCGMRU:
+	case PPPIOCGFLAGS:
+		session = sock->sk->sk_user_data;
+		if (!session)
+			return -ENOTCONN;
 
-	session = sock->sk->sk_user_data;
-	if (!session)
-		return -ENOTCONN;
+		/* Not defined for tunnels */
+		if (!session->session_id && !session->peer_session_id)
+			return -ENOSYS;
 
-	/* Special case: if session's session_id is zero, treat ioctl as a
-	 * tunnel ioctl
-	 */
-	if ((session->session_id == 0) &&
-	    (session->peer_session_id == 0)) {
-		tunnel = session->tunnel;
+		if (put_user(0, (int __user *)arg))
+			return -EFAULT;
+		break;
+
+	case PPPIOCSMRU:
+	case PPPIOCSFLAGS:
+		session = sock->sk->sk_user_data;
+		if (!session)
+			return -ENOTCONN;
 
-		return pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
+		/* Not defined for tunnels */
+		if (!session->session_id && !session->peer_session_id)
+			return -ENOSYS;
+
+		if (get_user(val, (int __user *)arg))
+			return -EFAULT;
+		break;
+
+	case PPPIOCGL2TPSTATS:
+		session = sock->sk->sk_user_data;
+		if (!session)
+			return -ENOTCONN;
+
+		/* Session 0 represents the parent tunnel */
+		if (!session->session_id && !session->peer_session_id)
+			return pppol2tp_tunnel_ioctl(session->tunnel, cmd,
+						     arg);
+		else
+			return pppol2tp_session_ioctl(session, cmd, arg);
+		break;
+
+	default:
+		return -ENOSYS;
 	}
 
-	return pppol2tp_session_ioctl(session, cmd, arg);
+	return 0;
 }
 
 /*****************************************************************************