netpoll: don't dereference NULL dev from np
[safe/jmp/linux-2.6] / net / wanrouter / wanmain.c
index 13b650a..466e2d2 100644 (file)
@@ -3,7 +3,7 @@
 *
 *              This module is completely hardware-independent and provides
 *              the following common services for the WAN Link Drivers:
-*               o WAN device managenment (registering, unregistering)
+*               o WAN device management (registering, unregistering)
 *               o Network interface management
 *               o Physical connection management (dial-up, incoming calls)
 *               o Logical connection management (switched virtual circuits)
 * Jun 02, 1999  Gideon Hack    Updates for Linux 2.0.X and 2.2.X kernels.
 *****************************************************************************/
 
-#include <linux/config.h>
 #include <linux/stddef.h>      /* offsetof(), etc. */
+#include <linux/capability.h>
 #include <linux/errno.h>       /* return codes */
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/module.h>      /* support for loadable modules */
 #include <linux/slab.h>                /* kmalloc(), kfree() */
 #include <linux/mm.h>
 #include <linux/vmalloc.h>     /* vmalloc, vfree */
 #include <asm/uaccess.h>        /* copy_to/from_user */
 #include <linux/init.h>         /* __initfunc et al. */
-#include <net/syncppp.h>
 
 #define KMEM_SAFETYZONE 8
 
-/***********FOR DEBUGGING PURPOSES*********************************************
-static void * dbg_kmalloc(unsigned int size, int prio, int line) {
-       int i = 0;
-       void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
-       char * c1 = v;
-       c1 += sizeof(unsigned int);
-       *((unsigned int *)v) = size;
-
-       for (i = 0; i < KMEM_SAFETYZONE; i++) {
-               c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
-               c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
-               c1 += 8;
-       }
-       c1 += size;
-       for (i = 0; i < KMEM_SAFETYZONE; i++) {
-               c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
-               c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
-               c1 += 8;
-       }
-       v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
-       printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);
-       return v;
-}
-static void dbg_kfree(void * v, int line) {
-       unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
-       unsigned int size = *sp;
-       char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
-       int i = 0;
-       for (i = 0; i < KMEM_SAFETYZONE; i++) {
-               if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
-                   || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
-                       printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
-                       printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-                                       c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-               }
-               c1 += 8;
-       }
-       c1 += size;
-       for (i = 0; i < KMEM_SAFETYZONE; i++) {
-               if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
-                   || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
-                  ) {
-                       printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
-                       printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-                                       c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-               }
-               c1 += 8;
-       }
-       printk(KERN_INFO "line %d  kfree(%p)\n",line,v);
-       v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
-       kfree(v);
-}
-
-#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
-#define kfree(x) dbg_kfree(x,__LINE__)
-*****************************************************************************/
+#define DEV_TO_SLAVE(dev)      (*((struct net_device **)netdev_priv(dev)))
 
 /*
  *     Function Prototypes
@@ -143,8 +86,10 @@ static int wanrouter_device_del_if(struct wan_device *wandev,
 
 static struct wan_device *wanrouter_find_device(char *name);
 static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
-void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
-void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
+static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+       __acquires(lock);
+static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+       __releases(lock);
 
 
 
@@ -161,8 +106,8 @@ struct wan_device* wanrouter_router_devlist; /* list of registered devices */
  *     Organize Unique Identifiers for encapsulation/decapsulation
  */
 
-static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
 #if 0
+static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
 static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
 #endif
 
@@ -303,6 +248,8 @@ int unregister_wan_device(char *name)
        return 0;
 }
 
+#if 0
+
 /*
  *     Encapsulate packet.
  *
@@ -332,8 +279,8 @@ int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
                skb_push(skb, 7);
                skb->data[0] = 0;
                skb->data[1] = NLPID_SNAP;
-               memcpy(&skb->data[2], wanrouter_oui_ether,
-                      sizeof(wanrouter_oui_ether));
+               skb_copy_to_linear_data_offset(skb, 2, wanrouter_oui_ether,
+                                              sizeof(wanrouter_oui_ether));
                *((unsigned short*)&skb->data[5]) = htons(type);
                break;
 
@@ -369,10 +316,10 @@ __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
                cnt += 1;
                break;
 
-        case NLPID_SNAP:       /* SNAP encapsulation */
+       case NLPID_SNAP:        /* SNAP encapsulation */
                if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
                           sizeof(wanrouter_oui_ether))){
-                       printk(KERN_INFO
+                       printk(KERN_INFO
                                "%s: unsupported SNAP OUI %02X-%02X-%02X "
                                "on interface %s!\n", wanrouter_modname,
                                skb->data[cnt+1], skb->data[cnt+2],
@@ -394,10 +341,11 @@ __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
        skb->protocol = ethertype;
        skb->pkt_type = PACKET_HOST;    /*      Physically point to point */
        skb_pull(skb, cnt);
-       skb->mac.raw  = skb->data;
+       skb_reset_mac_header(skb);
        return ethertype;
 }
 
+#endif  /*  0  */
 
 /*
  *     WAN device IOCTL.
@@ -405,9 +353,9 @@ __be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
  *     o execute requested action or pass command to the device driver
  */
 
-int wanrouter_ioctl(struct inode *inode, struct file *file,
-               unsigned int cmd, unsigned long arg)
+long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
+       struct inode *inode = file->f_path.dentry->d_inode;
        int err = 0;
        struct proc_dir_entry *dent;
        struct wan_device *wandev;
@@ -427,6 +375,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
        if (wandev->magic != ROUTER_MAGIC)
                return -EINVAL;
 
+       lock_kernel();
        switch (cmd) {
        case ROUTER_SETUP:
                err = wanrouter_device_setup(wandev, data);
@@ -458,6 +407,7 @@ int wanrouter_ioctl(struct inode *inode, struct file *file,
                        err = wandev->ioctl(wandev, cmd, arg);
                else err = -EINVAL;
        }
+       unlock_kernel();
        return err;
 }
 
@@ -504,22 +454,22 @@ static int wanrouter_device_setup(struct wan_device *wandev,
                kfree(conf);
                printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n",
                                wandev->name);
-               return -EINVAL;
+               return -EINVAL;
        }
 
        if (conf->data_size && conf->data) {
-               if (conf->data_size > 128000 || conf->data_size < 0) {
+               if (conf->data_size > 128000) {
                        printk(KERN_INFO
                            "%s: ERROR, Invalid firmware data size %i !\n",
                                        wandev->name, conf->data_size);
                        kfree(conf);
-                       return -EINVAL;
+                       return -EINVAL;
                }
 
                data = vmalloc(conf->data_size);
                if (!data) {
                        printk(KERN_INFO
-                               "%s: ERROR, Faild allocate kernel memory !\n",
+                               "%s: ERROR, Faild allocate kernel memory !\n",
                                wandev->name);
                        kfree(conf);
                        return -ENOBUFS;
@@ -565,7 +515,7 @@ static int wanrouter_device_shutdown(struct wan_device *wandev)
                if (err)
                        return err;
                /* The above function deallocates the current dev
-                * structure. Therefore, we cannot use dev->priv
+                * structure. Therefore, we cannot use netdev_priv(dev)
                 * as the next element: wandev->dev points to the
                 * next element */
                dev = wandev->dev;
@@ -620,9 +570,6 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 {
        wanif_conf_t *cnf;
        struct net_device *dev = NULL;
-#ifdef CONFIG_WANPIPE_MULTPPP
-       struct ppp_device *pppdev=NULL;
-#endif
        int err;
 
        if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
@@ -641,33 +588,11 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
                goto out;
 
        if (cnf->config_id == WANCONFIG_MPPP) {
-#ifdef CONFIG_WANPIPE_MULTPPP
-               pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
-               err = -ENOBUFS;
-               if (pppdev == NULL)
-                       goto out;
-               memset(pppdev, 0, sizeof(struct ppp_device));
-               pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-               if (pppdev->dev == NULL) {
-                       kfree(pppdev);
-                       err = -ENOBUFS;
-                       goto out;
-               }
-               memset(pppdev->dev, 0, sizeof(struct net_device));
-               err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);
-               dev = pppdev->dev;
-#else
                printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
                                wandev->name);
                err = -EPROTONOSUPPORT;
                goto out;
-#endif
        } else {
-               dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-               err = -ENOBUFS;
-               if (dev == NULL)
-                       goto out;
-               memset(dev, 0, sizeof(struct net_device));
                err = wandev->new_if(wandev, dev, cnf);
        }
 
@@ -697,10 +622,9 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
                                        wandev->dev = dev;
                                } else {
                                        for (slave=wandev->dev;
-                                        *((struct net_device **)slave->priv);
-                                slave = *((struct net_device **)slave->priv));
-
-                                    *((struct net_device **)slave->priv) = dev;
+                                            DEV_TO_SLAVE(slave);
+                                            slave = DEV_TO_SLAVE(slave))
+                                               DEV_TO_SLAVE(slave) = dev;
                                }
                                ++wandev->ndev;
 
@@ -711,25 +635,9 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
                }
                if (wandev->del_if)
                        wandev->del_if(wandev, dev);
+               free_netdev(dev);
        }
 
-       /* This code has moved from del_if() function */
-       if (dev->priv) {
-               kfree(dev->priv);
-               dev->priv = NULL;
-       }
-
-#ifdef CONFIG_WANPIPE_MULTPPP
-       if (cnf->config_id == WANCONFIG_MPPP)
-               kfree(pppdev);
-       else
-               kfree(dev);
-#else
-       /* Sync PPP is disabled */
-       if (cnf->config_id != WANCONFIG_MPPP)
-               kfree(dev);
-#endif
-
 out:
        kfree(cnf);
        return err;
@@ -745,7 +653,7 @@ out:
 static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
 {
        char name[WAN_IFNAME_SZ + 1];
-        int err = 0;
+       int err = 0;
 
        if (wandev->state == WAN_UNCONFIGURED)
                return -ENODEV;
@@ -768,8 +676,8 @@ static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_nam
         * interfaces are deleted and the link irrecoverably disconnected.
         */
 
-        if (!wandev->ndev && wandev->shutdown)
-                err = wandev->shutdown(wandev);
+       if (!wandev->ndev && wandev->shutdown)
+               err = wandev->shutdown(wandev);
 
        return err;
 }
@@ -819,7 +727,7 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
        dev = wandev->dev;
        prev = NULL;
        while (dev && strcmp(name, dev->name)) {
-               struct net_device **slave = dev->priv;
+               struct net_device **slave = netdev_priv(dev);
                prev = dev;
                dev = *slave;
        }
@@ -836,12 +744,12 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
 
        lock_adapter_irq(&wandev->lock, &smp_flags);
        if (prev) {
-               struct net_device **prev_slave = prev->priv;
-               struct net_device **slave = dev->priv;
+               struct net_device **prev_slave = netdev_priv(prev);
+               struct net_device **slave = netdev_priv(dev);
 
                *prev_slave = *slave;
        } else {
-               struct net_device **slave = dev->priv;
+               struct net_device **slave = netdev_priv(dev);
                wandev->dev = *slave;
        }
        --wandev->ndev;
@@ -849,13 +757,6 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
 
        printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name);
 
-       /* Due to new interface linking method using dev->priv,
-        * this code has moved from del_if() function.*/
-       if (dev->priv){
-               kfree(dev->priv);
-               dev->priv=NULL;
-       }
-
        unregister_netdev(dev);
 
        free_netdev(dev);
@@ -863,23 +764,21 @@ static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
        return 0;
 }
 
-void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+       __acquires(lock)
 {
-               spin_lock_irqsave(lock, *smp_flags);
+       spin_lock_irqsave(lock, *smp_flags);
 }
 
 
-void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
+       __releases(lock)
 {
        spin_unlock_irqrestore(lock, *smp_flags);
 }
 
 EXPORT_SYMBOL(register_wan_device);
 EXPORT_SYMBOL(unregister_wan_device);
-EXPORT_SYMBOL(wanrouter_encapsulate);
-EXPORT_SYMBOL(wanrouter_type_trans);
-EXPORT_SYMBOL(lock_adapter_irq);
-EXPORT_SYMBOL(unlock_adapter_irq);
 
 MODULE_LICENSE("GPL");