Loading bzImage directly.
[safe/jmp/linux-2.6] / net / wireless / wext.c
index f733303..85e5f9d 100644 (file)
@@ -93,6 +93,7 @@
 #include <linux/if_arp.h>              /* ARPHRD_ETHER */
 #include <linux/etherdevice.h>         /* compare_ether_addr */
 #include <linux/interrupt.h>
+#include <net/net_namespace.h>
 
 #include <linux/wireless.h>            /* Pretty obvious */
 #include <net/iw_handler.h>            /* New driver API */
@@ -476,7 +477,7 @@ static struct iw_statistics *get_wireless_stats(struct net_device *dev)
                return dev->wireless_handlers->get_wireless_stats(dev);
 
        /* Not found */
-       return (struct iw_statistics *) NULL;
+       return NULL;
 }
 
 /* ---------------------------------------------------------------- */
@@ -501,11 +502,11 @@ static struct iw_statistics *get_wireless_stats(struct net_device *dev)
 static int call_commit_handler(struct net_device *dev)
 {
        if ((netif_running(dev)) &&
-          (dev->wireless_handlers->standard[0] != NULL)) {
+          (dev->wireless_handlers->standard[0] != NULL))
                /* Call the commit handler on the driver */
                return dev->wireless_handlers->standard[0](dev, NULL,
                                                           NULL, NULL);
-       else
+       else
                return 0;               /* Command completed successfully */
 }
 
@@ -554,8 +555,7 @@ static int iw_handler_get_iwstats(struct net_device *               dev,
        struct iw_statistics *stats;
 
        stats = get_wireless_stats(dev);
-       if (stats != (struct iw_statistics *) NULL) {
-
+       if (stats) {
                /* Copy statistics to extra */
                memcpy(extra, stats, sizeof(struct iw_statistics));
                wrqu->data.length = sizeof(struct iw_statistics);
@@ -673,7 +673,26 @@ static const struct seq_operations wireless_seq_ops = {
 
 static int wireless_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &wireless_seq_ops);
+       struct seq_file *seq;
+       int res;
+       res = seq_open(file, &wireless_seq_ops);
+       if (!res) {
+               seq = file->private_data;
+               seq->private = get_proc_net(inode);
+               if (!seq->private) {
+                       seq_release(inode, file);
+                       res = -ENXIO;
+               }
+       }
+       return res;
+}
+
+static int wireless_seq_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq = file->private_data;
+       struct net *net = seq->private;
+       put_net(net);
+       return seq_release(inode, file);
 }
 
 static const struct file_operations wireless_seq_fops = {
@@ -681,17 +700,22 @@ static const struct file_operations wireless_seq_fops = {
        .open    = wireless_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = wireless_seq_release,
 };
 
-int __init wext_proc_init(void)
+int wext_proc_init(struct net *net)
 {
        /* Create /proc/net/wireless entry */
-       if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops))
+       if (!proc_net_fops_create(net, "wireless", S_IRUGO, &wireless_seq_fops))
                return -ENOMEM;
 
        return 0;
 }
+
+void wext_proc_exit(struct net *net)
+{
+       proc_net_remove(net, "wireless");
+}
 #endif /* CONFIG_PROC_FS */
 
 /************************** IOCTL SUPPORT **************************/
@@ -814,9 +838,8 @@ static int ioctl_standard_call(struct net_device *  dev,
                /* Create the kernel buffer */
                /*    kzalloc ensures NULL-termination for essid_compat */
                extra = kzalloc(extra_size, GFP_KERNEL);
-               if (extra == NULL) {
+               if (extra == NULL)
                        return -ENOMEM;
-               }
 
                /* If it is a SET, get all the extra data in here */
                if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
@@ -957,18 +980,14 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
                        if (iwr->u.data.length > (descr->set_args &
                                                 IW_PRIV_SIZE_MASK))
                                return -E2BIG;
-               } else {
-                       /* Check NULL pointer */
-                       if (iwr->u.data.pointer == NULL)
-                               return -EFAULT;
-               }
+               } else if (iwr->u.data.pointer == NULL)
+                       return -EFAULT;
 
                /* Always allocate for max space. Easier, and won't last
                 * long... */
                extra = kmalloc(extra_size, GFP_KERNEL);
-               if (extra == NULL) {
+               if (extra == NULL)
                        return -ENOMEM;
-               }
 
                /* If it is a SET, get all the extra data in here */
                if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
@@ -1016,7 +1035,7 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
  * Main IOCTl dispatcher.
  * Check the type of IOCTL and call the appropriate wrapper...
  */
-static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
+static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd)
 {
        struct net_device *dev;
        iw_handler      handler;
@@ -1025,7 +1044,7 @@ static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
         * The copy_to/from_user() of ifr is also dealt with in there */
 
        /* Make sure the device exist */
-       if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
+       if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL)
                return -ENODEV;
 
        /* A bunch of special cases, then the generic case...
@@ -1059,7 +1078,7 @@ static int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
 }
 
 /* entry point from dev ioctl */
-int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
+int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
                      void __user *arg)
 {
        int ret;
@@ -1071,9 +1090,9 @@ int wext_handle_ioctl(struct ifreq *ifr, unsigned int cmd,
            && !capable(CAP_NET_ADMIN))
                return -EPERM;
 
-       dev_load(ifr->ifr_name);
+       dev_load(net, ifr->ifr_name);
        rtnl_lock();
-       ret = wireless_process_ioctl(ifr, cmd);
+       ret = wireless_process_ioctl(net, ifr, cmd);
        rtnl_unlock();
        if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct ifreq)))
                return -EFAULT;
@@ -1135,10 +1154,12 @@ static int rtnetlink_fill_iwinfo(struct sk_buff *skb, struct net_device *dev,
 {
        struct ifinfomsg *r;
        struct nlmsghdr  *nlh;
-       unsigned char    *b = skb_tail_pointer(skb);
 
-       nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
-       r = NLMSG_DATA(nlh);
+       nlh = nlmsg_put(skb, 0, 0, type, sizeof(*r), 0);
+       if (nlh == NULL)
+               return -EMSGSIZE;
+
+       r = nlmsg_data(nlh);
        r->ifi_family = AF_UNSPEC;
        r->__ifi_pad = 0;
        r->ifi_type = dev->type;
@@ -1147,15 +1168,13 @@ static int rtnetlink_fill_iwinfo(struct sk_buff *skb, struct net_device *dev,
        r->ifi_change = 0;      /* Wireless changes don't affect those flags */
 
        /* Add the wireless events in the netlink packet */
-       RTA_PUT(skb, IFLA_WIRELESS, event_len, event);
+       NLA_PUT(skb, IFLA_WIRELESS, event_len, event);
 
-       nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-       return skb->len;
+       return nlmsg_end(skb, nlh);
 
-nlmsg_failure:
-rtattr_failure:
-       nlmsg_trim(skb, b);
-       return -1;
+nla_put_failure:
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
 }
 
 /* ---------------------------------------------------------------- */
@@ -1168,17 +1187,19 @@ rtattr_failure:
 static void rtmsg_iwinfo(struct net_device *dev, char *event, int event_len)
 {
        struct sk_buff *skb;
-       int size = NLMSG_GOODSIZE;
+       int err;
 
-       skb = alloc_skb(size, GFP_ATOMIC);
+       skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!skb)
                return;
 
-       if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK,
-                                 event, event_len) < 0) {
+       err = rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK, event, event_len);
+       if (err < 0) {
+               WARN_ON(err == -EMSGSIZE);
                kfree_skb(skb);
                return;
        }
+
        NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
        skb_queue_tail(&wireless_nlevent_queue, skb);
        tasklet_schedule(&wireless_nlevent_tasklet);
@@ -1259,7 +1280,7 @@ void wireless_send_event(struct net_device *      dev,
        event->len = event_len;
        event->cmd = cmd;
        memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN);
-       if (extra != NULL)
+       if (extra)
                memcpy(((char *) event) + hdr_len, extra, extra_len);
 
        /* Send via the RtNetlink event channel */
@@ -1290,11 +1311,11 @@ EXPORT_SYMBOL(wireless_send_event);
  * Because this is called on the Rx path via wireless_spy_update(),
  * we want it to be efficient...
  */
-static inline struct iw_spy_data * get_spydata(struct net_device *dev)
+static inline struct iw_spy_data *get_spydata(struct net_device *dev)
 {
        /* This is the new way */
        if (dev->wireless_data)
-               return(dev->wireless_data->spy_data);
+               return dev->wireless_data->spy_data;
        return NULL;
 }