linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / atm / ioctl.c
index b8133d1..eb109af 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/atmdev.h>
 #include <linux/atmclip.h>     /* CLIP_*ENCAP */
 #include <linux/atmarp.h>      /* manifest constants */
+#include <linux/capability.h>
 #include <linux/sonet.h>       /* for ioctls */
 #include <linux/atmsvc.h>
 #include <linux/atmmpc.h>
@@ -21,6 +22,7 @@
 
 #include "resources.h"
 #include "signaling.h"         /* for WAITING and sigd_attach */
+#include "common.h"
 
 
 static DECLARE_MUTEX(ioctl_mutex);
@@ -46,9 +48,11 @@ EXPORT_SYMBOL(deregister_atm_ioctl);
 
 int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
+       struct sock *sk = sock->sk;
        struct atm_vcc *vcc;
        int error;
        struct list_head * pos;
+       void __user *argp = (void __user *)arg;
 
        vcc = ATM_SD(sock);
        switch (cmd) {
@@ -58,9 +62,9 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                                error =  -EINVAL;
                                goto done;
                        }
-                       error = put_user(vcc->sk->sk_sndbuf -
-                                        atomic_read(&vcc->sk->sk_wmem_alloc),
-                                        (int *) arg) ? -EFAULT : 0;
+                       error = put_user(sk->sk_sndbuf -
+                                        atomic_read(&sk->sk_wmem_alloc),
+                                        (int __user *) argp) ? -EFAULT : 0;
                        goto done;
                case SIOCINQ:
                        {
@@ -70,14 +74,13 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                                        error = -EINVAL;
                                        goto done;
                                }
-                               skb = skb_peek(&vcc->sk->sk_receive_queue);
+                               skb = skb_peek(&sk->sk_receive_queue);
                                error = put_user(skb ? skb->len : 0,
-                                                (int *) arg) ? -EFAULT : 0;
+                                                (int __user *)argp) ? -EFAULT : 0;
                                goto done;
                        }
                case SIOCGSTAMP: /* borrowed from IP */
-                       error = sock_get_timestamp(vcc->sk, (struct timeval *)
-                                                  arg);
+                       error = sock_get_timestamp(sk, argp);
                        goto done;
                case ATM_SETSC:
                        printk(KERN_WARNING "ATM_SETSC is obsolete\n");
@@ -103,17 +106,35 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        if (!error)
                                sock->state = SS_CONNECTED;
                        goto done;
-               default:
+               case ATM_SETBACKEND:
+               case ATM_NEWBACKENDIF:
+                       {
+                               atm_backend_t backend;
+                               error = get_user(backend, (atm_backend_t __user *) argp);
+                               if (error)
+                                       goto done;
+                               switch (backend) {
+                                       case ATM_BACKEND_PPP:
+                                               request_module("pppoatm");
+                                               break;
+                                       case ATM_BACKEND_BR2684:
+                                               request_module("br2684");
+                                               break;
+                               }
+                       }
+                       break;
+               case ATMMPC_CTRL:
+               case ATMMPC_DATA:
+                       request_module("mpoa");
+                       break;
+               case ATMARPD_CTRL:
+                       request_module("clip");
+                       break;
+               case ATMLEC_CTRL:
+                       request_module("lec");
                        break;
        }
 
-       if (cmd == ATMMPC_CTRL || cmd == ATMMPC_DATA)
-               request_module("mpoa");
-       if (cmd == ATMARPD_CTRL)
-               request_module("clip");
-       if (cmd == ATMLEC_CTRL)
-               request_module("lec");
-
        error = -ENOIOCTLCMD;
 
        down(&ioctl_mutex);
@@ -131,7 +152,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        if (error != -ENOIOCTLCMD)
                goto done;
 
-       error = atm_dev_ioctl(cmd, arg);
+       error = atm_dev_ioctl(cmd, argp);
 
 done:
        return error;