This moves all ioctl32 code for ppp close to the
native ioctl implementation.

CC: linux-ppp@vger.kernel.org
CC: netdev@vger.kernel.org
Signed-off-by: Arnd Bergmann <[EMAIL PROTECTED]>

Index: linux-2.6.14-rc/drivers/net/ppp_generic.c
===================================================================
--- linux-2.6.14-rc.orig/drivers/net/ppp_generic.c      2005-11-05 
02:41:10.000000000 +0100
+++ linux-2.6.14-rc/drivers/net/ppp_generic.c   2005-11-05 02:41:29.000000000 
+0100
@@ -46,6 +46,8 @@
 #include <linux/rwsem.h>
 #include <linux/stddef.h>
 #include <linux/device.h>
+#include <linux/compat.h>
+
 #include <net/slhc_vj.h>
 #include <asm/atomic.h>
 
@@ -837,12 +839,189 @@
        return err;
 }
 
+#ifdef CONFIG_COMPAT
+/* FIXME: These could be better integrated into the driver */
+
+struct sock_fprog32 {
+       unsigned short  len;
+       compat_caddr_t  filter;
+};
+
+#define PPPIOCSPASS32  _IOW('t', 71, struct sock_fprog32)
+#define PPPIOCSACTIVE32        _IOW('t', 70, struct sock_fprog32)
+
+static int ppp_sock_fprog_ioctl_trans(struct file *file, unsigned int cmd, 
unsigned long arg)
+{
+       struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
+       struct sock_fprog __user *u_fprog64 = 
compat_alloc_user_space(sizeof(struct sock_fprog));
+       void __user *fptr64;
+       u32 fptr32;
+       u16 flen;
+
+       if (get_user(flen, &u_fprog32->len) ||
+           get_user(fptr32, &u_fprog32->filter))
+               return -EFAULT;
+
+       fptr64 = compat_ptr(fptr32);
+
+       if (put_user(flen, &u_fprog64->len) ||
+           put_user(fptr64, &u_fprog64->filter))
+               return -EFAULT;
+
+       if (cmd == PPPIOCSPASS32)
+               cmd = PPPIOCSPASS;
+       else
+               cmd = PPPIOCSACTIVE;
+
+       return ppp_ioctl(file->f_dentry->d_inode, file, cmd,
+                        (unsigned long) u_fprog64);
+}
+
+struct ppp_option_data32 {
+       compat_caddr_t  ptr;
+       u32             length;
+       compat_int_t    transmit;
+};
+#define PPPIOCSCOMPRESS32      _IOW('t', 77, struct ppp_option_data32)
+
+struct ppp_idle32 {
+       compat_time_t xmit_idle;
+       compat_time_t recv_idle;
+};
+#define PPPIOCGIDLE32          _IOR('t', 63, struct ppp_idle32)
+
+static int ppp_gidle(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct ppp_idle __user *idle;
+       struct ppp_idle32 __user *idle32;
+       __kernel_time_t xmit, recv;
+       int err;
+
+       idle = compat_alloc_user_space(sizeof(*idle));
+       idle32 = compat_ptr(arg);
+
+       err = ppp_ioctl(file->f_dentry->d_inode, file, PPPIOCGIDLE, (unsigned 
long) idle);
+
+       if (!err) {
+               if (get_user(xmit, &idle->xmit_idle) ||
+                   get_user(recv, &idle->recv_idle) ||
+                   put_user(xmit, &idle32->xmit_idle) ||
+                   put_user(recv, &idle32->recv_idle))
+                       err = -EFAULT;
+       }
+       return err;
+}
+
+static int ppp_scompress(struct file *file, unsigned int cmd, unsigned long 
arg)
+{
+       struct ppp_option_data __user *odata;
+       struct ppp_option_data32 __user *odata32;
+       __u32 data;
+       void __user *datap;
+
+       odata = compat_alloc_user_space(sizeof(*odata));
+       odata32 = compat_ptr(arg);
+
+       if (get_user(data, &odata32->ptr))
+               return -EFAULT;
+
+       datap = compat_ptr(data);
+       if (put_user(datap, &odata->ptr))
+               return -EFAULT;
+
+       if (copy_in_user(&odata->length, &odata32->length,
+                        sizeof(__u32) + sizeof(int)))
+               return -EFAULT;
+
+       return ppp_ioctl(file->f_dentry->d_inode, file, PPPIOCSCOMPRESS, 
(unsigned long) odata);
+}
+
+static int ppp_ioctl_trans(struct file *file, unsigned int cmd, unsigned long 
arg)
+{
+       int err;
+
+       switch (cmd) {
+       case PPPIOCGIDLE32:
+               err = ppp_gidle(file, cmd, arg);
+               break;
+
+       case PPPIOCSCOMPRESS32:
+               err = ppp_scompress(file, cmd, arg);
+               break;
+
+       default:
+               do {
+                       static int count;
+                       if (++count <= 20)
+                               printk("ppp_ioctl: Unknown cmd(%08x) 
arg(%08x)\n",
+                                      (unsigned int)cmd, (unsigned int)arg);
+               } while(0);
+               err = -EINVAL;
+               break;
+       };
+
+       return err;
+}
+
+static long ppp_compat_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
+{
+       int ret;
+       ret = -ENOIOCTLCMD;
+
+       lock_kernel();
+       switch (cmd) {
+       case PPPIOCGIDLE32:
+       case PPPIOCSCOMPRESS32:
+               ret = ppp_ioctl_trans(file, cmd, arg);
+               break;
+
+       case PPPIOCSPASS32:
+       case PPPIOCSACTIVE32:
+               ret = ppp_sock_fprog_ioctl_trans(file, cmd, arg);
+               break;
+
+       case PPPIOCGFLAGS:
+       case PPPIOCSFLAGS:
+       case PPPIOCGASYNCMAP:
+       case PPPIOCSASYNCMAP:
+       case PPPIOCGUNIT:
+       case PPPIOCGRASYNCMAP:
+       case PPPIOCSRASYNCMAP:
+       case PPPIOCGMRU:
+       case PPPIOCSMRU:
+       case PPPIOCSMAXCID:
+       case PPPIOCGXASYNCMAP:
+       case PPPIOCSXASYNCMAP:
+       case PPPIOCXFERUNIT:
+       case PPPIOCGNPMODE:
+       case PPPIOCSNPMODE:
+       case PPPIOCGDEBUG:
+       case PPPIOCSDEBUG:
+       case PPPIOCNEWUNIT:
+       case PPPIOCATTACH:
+       case PPPIOCDETACH:
+       case PPPIOCSMRRU:
+       case PPPIOCCONNECT:
+       case PPPIOCDISCONN:
+       case PPPIOCATTCHAN:
+       case PPPIOCGCHAN:
+               ret = ppp_ioctl(file->f_dentry->d_inode, file, cmd, arg);
+               break;
+       }
+       unlock_kernel();
+       return ret;
+}
+#endif
+
 static struct file_operations ppp_device_fops = {
        .owner          = THIS_MODULE,
        .read           = ppp_read,
        .write          = ppp_write,
        .poll           = ppp_poll,
        .ioctl          = ppp_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = ppp_compat_ioctl,
+#endif
        .open           = ppp_open,
        .release        = ppp_release
 };
Index: linux-2.6.14-rc/net/compat.c
===================================================================
--- linux-2.6.14-rc.orig/net/compat.c   2005-11-05 02:41:28.000000000 +0100
+++ linux-2.6.14-rc/net/compat.c        2005-11-05 02:41:29.000000000 +0100
@@ -1016,126 +1016,6 @@
        return ret;
 }
 
-struct sock_fprog32 {
-       unsigned short  len;
-       compat_caddr_t  filter;
-};
-
-#define PPPIOCSPASS32  _IOW('t', 71, struct sock_fprog32)
-#define PPPIOCSACTIVE32        _IOW('t', 70, struct sock_fprog32)
-
-static int ppp_sock_fprog_ioctl_trans(struct file *file, unsigned int cmd, 
unsigned long arg)
-{
-       struct sock_fprog32 __user *u_fprog32 = compat_ptr(arg);
-       struct sock_fprog __user *u_fprog64 = 
compat_alloc_user_space(sizeof(struct sock_fprog));
-       void __user *fptr64;
-       u32 fptr32;
-       u16 flen;
-
-       if (get_user(flen, &u_fprog32->len) ||
-           get_user(fptr32, &u_fprog32->filter))
-               return -EFAULT;
-
-       fptr64 = compat_ptr(fptr32);
-
-       if (put_user(flen, &u_fprog64->len) ||
-           put_user(fptr64, &u_fprog64->filter))
-               return -EFAULT;
-
-       if (cmd == PPPIOCSPASS32)
-               cmd = PPPIOCSPASS;
-       else
-               cmd = PPPIOCSACTIVE;
-
-       return sock_ioctl(file, cmd, (unsigned long) u_fprog64);
-}
-
-struct ppp_option_data32 {
-       compat_caddr_t  ptr;
-       u32                     length;
-       compat_int_t            transmit;
-};
-#define PPPIOCSCOMPRESS32      _IOW('t', 77, struct ppp_option_data32)
-
-struct ppp_idle32 {
-       compat_time_t xmit_idle;
-       compat_time_t recv_idle;
-};
-#define PPPIOCGIDLE32          _IOR('t', 63, struct ppp_idle32)
-
-static int ppp_gidle(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ppp_idle __user *idle;
-       struct ppp_idle32 __user *idle32;
-       __kernel_time_t xmit, recv;
-       int err;
-
-       idle = compat_alloc_user_space(sizeof(*idle));
-       idle32 = compat_ptr(arg);
-
-       err = sock_ioctl(file, PPPIOCGIDLE, (unsigned long) idle);
-
-       if (!err) {
-               if (get_user(xmit, &idle->xmit_idle) ||
-                   get_user(recv, &idle->recv_idle) ||
-                   put_user(xmit, &idle32->xmit_idle) ||
-                   put_user(recv, &idle32->recv_idle))
-                       err = -EFAULT;
-       }
-       return err;
-}
-
-static int ppp_scompress(struct file *file, unsigned int cmd, unsigned long 
arg)
-{
-       struct ppp_option_data __user *odata;
-       struct ppp_option_data32 __user *odata32;
-       __u32 data;
-       void __user *datap;
-
-       odata = compat_alloc_user_space(sizeof(*odata));
-       odata32 = compat_ptr(arg);
-
-       if (get_user(data, &odata32->ptr))
-               return -EFAULT;
-
-       datap = compat_ptr(data);
-       if (put_user(datap, &odata->ptr))
-               return -EFAULT;
-
-       if (copy_in_user(&odata->length, &odata32->length,
-                        sizeof(__u32) + sizeof(int)))
-               return -EFAULT;
-
-       return sock_ioctl(file, PPPIOCSCOMPRESS, (unsigned long) odata);
-}
-
-static int ppp_ioctl_trans(struct file *file, unsigned int cmd, unsigned long 
arg)
-{
-       int err;
-
-       switch (cmd) {
-       case PPPIOCGIDLE32:
-               err = ppp_gidle(file, cmd, arg);
-               break;
-
-       case PPPIOCSCOMPRESS32:
-               err = ppp_scompress(file, cmd, arg);
-               break;
-
-       default:
-               do {
-                       static int count;
-                       if (++count <= 20)
-                               printk("ppp_ioctl: Unknown cmd(%08x) 
arg(%08x)\n",
-                                      (unsigned int)cmd, (unsigned int)arg);
-               } while(0);
-               err = -EINVAL;
-               break;
-       };
-
-       return err;
-}
-
 #ifdef WIRELESS_EXT
 struct compat_iw_point {
        compat_caddr_t pointer;
@@ -1283,40 +1163,6 @@
 /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen 
just an -EINVAL anyways. */
 INVAL_IOCTL(SIOCRTMSG)
 HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
-/* ppp */
-HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans)
-HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans)
-HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans)
-HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans)
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-/* PPPIOCSCOMPRESS is translated */
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-/* PPPIOCSPASS is translated */
-/* PPPIOCSACTIVE is translated */
-/* PPPIOCGIDLE is translated */
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
 /* PPPOX */
 COMPATIBLE_IOCTL(PPPOEIOCSFWD)
 COMPATIBLE_IOCTL(PPPOEIOCDFWD)

--

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to