]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/wireless/wext.c
[NET] NETNS: Omit net_device->nd_net without CONFIG_NET_NS.
[net-next-2.6.git] / net / wireless / wext.c
index d6aaf65192e90f14301c76870f8c8a1ec7238b8d..947188a5b937ed96d71afbf81997211102bae071 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 */
@@ -416,20 +417,6 @@ static const int event_type_size[] = {
        IW_EV_QUAL_LEN,                 /* IW_HEADER_TYPE_QUAL */
 };
 
-/* Size (in bytes) of various events, as packed */
-static const int event_type_pk_size[] = {
-       IW_EV_LCP_PK_LEN,               /* IW_HEADER_TYPE_NULL */
-       0,
-       IW_EV_CHAR_PK_LEN,              /* IW_HEADER_TYPE_CHAR */
-       0,
-       IW_EV_UINT_PK_LEN,              /* IW_HEADER_TYPE_UINT */
-       IW_EV_FREQ_PK_LEN,              /* IW_HEADER_TYPE_FREQ */
-       IW_EV_ADDR_PK_LEN,              /* IW_HEADER_TYPE_ADDR */
-       0,
-       IW_EV_POINT_PK_LEN,             /* Without variable payload */
-       IW_EV_PARAM_PK_LEN,             /* IW_HEADER_TYPE_PARAM */
-       IW_EV_QUAL_PK_LEN,              /* IW_HEADER_TYPE_QUAL */
-};
 
 /************************ COMMON SUBROUTINES ************************/
 /*
@@ -672,7 +659,8 @@ 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);
+       return seq_open_net(inode, file, &wireless_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations wireless_seq_fops = {
@@ -680,17 +668,22 @@ static const struct file_operations wireless_seq_fops = {
        .open    = wireless_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = seq_release_net,
 };
 
-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 **************************/
@@ -1010,7 +1003,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;
@@ -1019,7 +1012,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...
@@ -1053,7 +1046,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;
@@ -1065,11 +1058,11 @@ 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)))
+       if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct iwreq)))
                return -EFAULT;
        return ret;
 }
@@ -1112,7 +1105,7 @@ static void wireless_nlevent_process(unsigned long data)
        struct sk_buff *skb;
 
        while ((skb = skb_dequeue(&wireless_nlevent_queue)))
-               rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+               rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
 }
 
 static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
@@ -1129,10 +1122,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;
@@ -1141,15 +1136,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;
 }
 
 /* ---------------------------------------------------------------- */
@@ -1162,17 +1155,22 @@ 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);
+       if (dev_net(dev) != &init_net)
+               return;
+
+       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);