Let pppol2tp_ioctl() handle ioctl commands directly. It still relies on
pppol2tp_{session,tunnel}_ioctl() for PPPIOCGL2TPSTATS.

Signed-off-by: Guillaume Nault <g.na...@alphalink.fr>
---
Checkpatch does not like the -ENOSYS return value, which should only be
used for non-existing syscalls. I have kept them so that userspace gets
the same errors before and after this patch.

However I am feeling that I may be too conservative and that, maybe
the *MRU and *FLAGS commands should be dropped entirely, like *IFMTU
was. That would drop two of the three -ENOSYS errors (the last one is
dropped by the last patch anyway).

David, James, do you have any preference? After all, the MRU/FLAGS
ioctls never had any effect on pppol2tp sockets. So I do not expect
code to use them or expect them to succeed. I you are ok, I will send
a followup patch for dropping those commands.

 net/l2tp/l2tp_ppp.c | 73 +++++++++++++++++++++++++++------------------
 1 file 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;
 }
 
 /*****************************************************************************
-- 
2.18.0

Reply via email to