aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/core.h15
-rw-r--r--net/wireless/debugfs.c1
-rw-r--r--net/wireless/ibss.c1
-rw-r--r--net/wireless/mlme.c53
-rw-r--r--net/wireless/nl80211.c154
-rw-r--r--net/wireless/nl80211.h6
-rw-r--r--net/wireless/reg.c19
-rw-r--r--net/wireless/scan.c1
-rw-r--r--net/wireless/sme.c16
-rw-r--r--net/wireless/util.c25
-rw-r--r--net/wireless/wext-compat.c1
-rw-r--r--net/wireless/wext-core.c135
-rw-r--r--net/wireless/wext-priv.c1
-rw-r--r--net/wireless/wext-sme.c1
15 files changed, 321 insertions, 109 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 7fdb940..6ac70c1 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/nl80211.h>
#include <linux/debugfs.h>
#include <linux/notifier.h>
diff --git a/net/wireless/core.h b/net/wireless/core.h
index d52da91..b2234b4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -293,13 +293,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
- const u8 *key, int key_len, int key_idx);
+ const u8 *key, int key_len, int key_idx,
+ bool local_state_change);
int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
struct net_device *dev, struct ieee80211_channel *chan,
enum nl80211_auth_type auth_type, const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
- const u8 *key, int key_len, int key_idx);
+ const u8 *key, int key_len, int key_idx,
+ bool local_state_change);
int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct net_device *dev,
struct ieee80211_channel *chan,
@@ -315,13 +317,16 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct cfg80211_crypto_settings *crypt);
int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason);
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change);
int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason);
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change);
int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason);
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change);
void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
struct net_device *dev);
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 2e48956..a4991a3 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/slab.h>
#include "core.h"
#include "debugfs.h"
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 6ef5a49..6a5acf7 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -6,6 +6,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
#include "nl80211.h"
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 62bc885..48ead6f 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/nl80211.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <net/iw_handler.h>
@@ -377,7 +378,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
- const u8 *key, int key_len, int key_idx)
+ const u8 *key, int key_len, int key_idx,
+ bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_auth_request req;
@@ -407,6 +409,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
memset(&req, 0, sizeof(req));
+ req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
req.auth_type = auth_type;
@@ -433,12 +436,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
goto out;
}
- wdev->authtry_bsses[slot] = bss;
+ if (local_state_change)
+ wdev->auth_bsses[slot] = bss;
+ else
+ wdev->authtry_bsses[slot] = bss;
cfg80211_hold_bss(bss);
err = rdev->ops->auth(&rdev->wiphy, dev, &req);
if (err) {
- wdev->authtry_bsses[slot] = NULL;
+ if (local_state_change)
+ wdev->auth_bsses[slot] = NULL;
+ else
+ wdev->authtry_bsses[slot] = NULL;
cfg80211_unhold_bss(bss);
}
@@ -453,14 +462,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
enum nl80211_auth_type auth_type, const u8 *bssid,
const u8 *ssid, int ssid_len,
const u8 *ie, int ie_len,
- const u8 *key, int key_len, int key_idx)
+ const u8 *key, int key_len, int key_idx,
+ bool local_state_change)
{
int err;
wdev_lock(dev->ieee80211_ptr);
err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
ssid, ssid_len, ie, ie_len,
- key, key_len, key_idx);
+ key, key_len, key_idx, local_state_change);
wdev_unlock(dev->ieee80211_ptr);
return err;
@@ -554,7 +564,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason)
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_deauth_request req;
@@ -564,6 +575,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
memset(&req, 0, sizeof(req));
req.reason_code = reason;
+ req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
if (wdev->current_bss &&
@@ -590,13 +602,15 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason)
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
wdev_lock(wdev);
- err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason);
+ err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
+ local_state_change);
wdev_unlock(wdev);
return err;
@@ -604,7 +618,8 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason)
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_disassoc_request req;
@@ -619,6 +634,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
memset(&req, 0, sizeof(req));
req.reason_code = reason;
+ req.local_state_change = local_state_change;
req.ie = ie;
req.ie_len = ie_len;
if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
@@ -631,13 +647,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
struct net_device *dev, const u8 *bssid,
- const u8 *ie, int ie_len, u16 reason)
+ const u8 *ie, int ie_len, u16 reason,
+ bool local_state_change)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
int err;
wdev_lock(wdev);
- err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason);
+ err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
+ local_state_change);
wdev_unlock(wdev);
return err;
@@ -894,3 +912,16 @@ void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,
nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
}
EXPORT_SYMBOL(cfg80211_action_tx_status);
+
+void cfg80211_cqm_rssi_notify(struct net_device *dev,
+ enum nl80211_cqm_rssi_threshold_event rssi_event,
+ gfp_t gfp)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+ /* Indicate roaming trigger event to user space */
+ nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
+}
+EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e447db0..356a84a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7,6 +7,7 @@
#include <linux/if.h>
#include <linux/module.h>
#include <linux/err.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/if_ether.h>
#include <linux/ieee80211.h>
@@ -149,6 +150,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
[NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
+ [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
+ [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
};
/* policy for the attributes */
@@ -2095,7 +2098,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
goto out_rtnl;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
err = -EINVAL;
goto out;
}
@@ -3391,6 +3395,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
int err, ssid_len, ie_len = 0;
enum nl80211_auth_type auth_type;
struct key_parse key;
+ bool local_state_change;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
@@ -3469,9 +3474,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
goto out;
}
+ local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
+
err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
ssid, ssid_len, ie, ie_len,
- key.p.key, key.p.key_len, key.idx);
+ key.p.key, key.p.key_len, key.idx,
+ local_state_change);
out:
cfg80211_unlock_rdev(rdev);
@@ -3648,6 +3656,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
const u8 *ie = NULL, *bssid;
int err, ie_len = 0;
u16 reason_code;
+ bool local_state_change;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
@@ -3693,7 +3702,10 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code);
+ local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
+
+ err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
+ local_state_change);
out:
cfg80211_unlock_rdev(rdev);
@@ -3710,6 +3722,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
const u8 *ie = NULL, *bssid;
int err, ie_len = 0;
u16 reason_code;
+ bool local_state_change;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
return -EINVAL;
@@ -3755,7 +3768,10 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code);
+ local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
+
+ err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
+ local_state_change);
out:
cfg80211_unlock_rdev(rdev);
@@ -4778,6 +4794,84 @@ unlock_rtnl:
return err;
}
+static struct nla_policy
+nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
+ [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
+ [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
+ [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
+};
+
+static int nl80211_set_cqm_rssi(struct genl_info *info,
+ s32 threshold, u32 hysteresis)
+{
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+ struct net_device *dev;
+ int err;
+
+ if (threshold > 0)
+ return -EINVAL;
+
+ rtnl_lock();
+
+ err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+ if (err)
+ goto unlock_rdev;
+
+ wdev = dev->ieee80211_ptr;
+
+ if (!rdev->ops->set_cqm_rssi_config) {
+ err = -EOPNOTSUPP;
+ goto unlock_rdev;
+ }
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION) {
+ err = -EOPNOTSUPP;
+ goto unlock_rdev;
+ }
+
+ err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
+ threshold, hysteresis);
+
+unlock_rdev:
+ cfg80211_unlock_rdev(rdev);
+ dev_put(dev);
+ rtnl_unlock();
+
+ return err;
+}
+
+static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
+{
+ struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
+ struct nlattr *cqm;
+ int err;
+
+ cqm = info->attrs[NL80211_ATTR_CQM];
+ if (!cqm) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
+ nl80211_attr_cqm_policy);
+ if (err)
+ goto out;
+
+ if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
+ attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
+ s32 threshold;
+ u32 hysteresis;
+ threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
+ hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
+ err = nl80211_set_cqm_rssi(info, threshold, hysteresis);
+ } else
+ err = -EINVAL;
+
+out:
+ return err;
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -5082,6 +5176,12 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
},
+ {
+ .cmd = NL80211_CMD_SET_CQM,
+ .doit = nl80211_set_cqm,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5832,6 +5932,52 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
nlmsg_free(msg);
}
+void
+nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ enum nl80211_cqm_rssi_threshold_event rssi_event,
+ gfp_t gfp)
+{
+ struct sk_buff *msg;
+ struct nlattr *pinfoattr;
+ void *hdr;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
+ if (!hdr) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+
+ pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
+ if (!pinfoattr)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+ rssi_event);
+
+ nla_nest_end(msg, pinfoattr);
+
+ if (genlmsg_end(msg, hdr) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_mlme_mcgrp.id, gfp);
+ return;
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+
static int nl80211_netlink_notify(struct notifier_block * nb,
unsigned long state,
void *_notify)
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 4ca51110..2ad7fbc 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -82,4 +82,10 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev,
const u8 *buf, size_t len, bool ack,
gfp_t gfp);
+void
+nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ enum nl80211_cqm_rssi_threshold_event rssi_event,
+ gfp_t gfp);
+
#endif /* __NET_WIRELESS_NL80211_H */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ed89c59..8f0d97d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -33,6 +33,7 @@
*
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/list.h>
#include <linux/random.h>
#include <linux/nl80211.h>
@@ -324,7 +325,7 @@ struct reg_regdb_search_request {
};
static LIST_HEAD(reg_regdb_search_list);
-static DEFINE_SPINLOCK(reg_regdb_search_lock);
+static DEFINE_MUTEX(reg_regdb_search_mutex);
static void reg_regdb_search(struct work_struct *work)
{
@@ -332,7 +333,7 @@ static void reg_regdb_search(struct work_struct *work)
const struct ieee80211_regdomain *curdom, *regdom;
int i, r;
- spin_lock(&reg_regdb_search_lock);
+ mutex_lock(&reg_regdb_search_mutex);
while (!list_empty(&reg_regdb_search_list)) {
request = list_first_entry(&reg_regdb_search_list,
struct reg_regdb_search_request,
@@ -346,18 +347,16 @@ static void reg_regdb_search(struct work_struct *work)
r = reg_copy_regd(&regdom, curdom);
if (r)
break;
- spin_unlock(&reg_regdb_search_lock);
mutex_lock(&cfg80211_mutex);
set_regdom(regdom);
mutex_unlock(&cfg80211_mutex);
- spin_lock(&reg_regdb_search_lock);
break;
}
}
kfree(request);
}
- spin_unlock(&reg_regdb_search_lock);
+ mutex_unlock(&reg_regdb_search_mutex);
}
static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -375,9 +374,9 @@ static void reg_regdb_query(const char *alpha2)
memcpy(request->alpha2, alpha2, 2);
- spin_lock(&reg_regdb_search_lock);
+ mutex_lock(&reg_regdb_search_mutex);
list_add_tail(&request->list, &reg_regdb_search_list);
- spin_unlock(&reg_regdb_search_lock);
+ mutex_unlock(&reg_regdb_search_mutex);
schedule_work(&reg_regdb_work);
}
@@ -2357,10 +2356,10 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
rdev->country_ie_alpha2[1]);
} else
printk(KERN_INFO "cfg80211: Current regulatory "
- "domain intersected: \n");
+ "domain intersected:\n");
} else
- printk(KERN_INFO "cfg80211: Current regulatory "
- "domain intersected: \n");
+ printk(KERN_INFO "cfg80211: Current regulatory "
+ "domain intersected:\n");
} else if (is_world_regdom(rd->alpha2))
printk(KERN_INFO "cfg80211: World regulatory "
"domain updated:\n");
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 978cac3..a026c6d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -4,6 +4,7 @@
* Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
*/
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 17fde0d..c273577 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -7,6 +7,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
@@ -170,7 +171,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
params->ssid, params->ssid_len,
NULL, 0,
params->key, params->key_len,
- params->key_idx);
+ params->key_idx, false);
case CFG80211_CONN_ASSOCIATE_NEXT:
BUG_ON(!rdev->ops->assoc);
wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -185,12 +186,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
if (err)
__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
- WLAN_REASON_DEAUTH_LEAVING);
+ WLAN_REASON_DEAUTH_LEAVING,
+ false);
return err;
case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
- WLAN_REASON_DEAUTH_LEAVING);
+ WLAN_REASON_DEAUTH_LEAVING, false);
/* return an error so that we call __cfg80211_connect_result() */
return -EINVAL;
default:
@@ -675,7 +677,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
continue;
bssid = wdev->auth_bsses[i]->pub.bssid;
ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
- WLAN_REASON_DEAUTH_LEAVING);
+ WLAN_REASON_DEAUTH_LEAVING,
+ false);
WARN(ret, "deauth failed: %d\n", ret);
}
}
@@ -934,7 +937,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
/* wdev->conn->params.bssid must be set if > SCANNING */
err = __cfg80211_mlme_deauth(rdev, dev,
wdev->conn->params.bssid,
- NULL, 0, reason);
+ NULL, 0, reason, false);
if (err)
return err;
} else {
@@ -990,7 +993,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
if (__cfg80211_mlme_deauth(rdev, dev, bssid,
- NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) {
+ NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
+ false)) {
/* whatever -- assume gone anyway */
cfg80211_unhold_bss(wdev->auth_bsses[idx]);
cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be2ab8c..3416373 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -5,6 +5,7 @@
*/
#include <linux/bitops.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include <net/ip.h>
#include "core.h"
@@ -330,11 +331,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
- hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+ /* make sure meshdr->flags is on the linear part */
+ if (!pskb_may_pull(skb, hdrlen + 1))
+ return -1;
if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
- memcpy(dst, meshdr->eaddr1, ETH_ALEN);
- memcpy(src, meshdr->eaddr2, ETH_ALEN);
+ skb_copy_bits(skb, hdrlen +
+ offsetof(struct ieee80211s_hdr, eaddr1),
+ dst, ETH_ALEN);
+ skb_copy_bits(skb, hdrlen +
+ offsetof(struct ieee80211s_hdr, eaddr2),
+ src, ETH_ALEN);
}
+ hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
}
break;
case cpu_to_le16(IEEE80211_FCTL_FROMDS):
@@ -346,9 +354,14 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
- hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+ /* make sure meshdr->flags is on the linear part */
+ if (!pskb_may_pull(skb, hdrlen + 1))
+ return -1;
if (meshdr->flags & MESH_FLAGS_AE_A4)
- memcpy(src, meshdr->eaddr1, ETH_ALEN);
+ skb_copy_bits(skb, hdrlen +
+ offsetof(struct ieee80211s_hdr, eaddr1),
+ src, ETH_ALEN);
+ hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
}
break;
case cpu_to_le16(0):
@@ -357,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
break;
}
- if (unlikely(skb->len - hdrlen < 8))
+ if (!pskb_may_pull(skb, hdrlen + 8))
return -1;
payload = skb->data + hdrlen;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9ab5183..a60a277 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -12,6 +12,7 @@
#include <linux/nl80211.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
+#include <linux/slab.h>
#include <net/iw_handler.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 5e1656b..0ef17bc 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/uaccess.h>
#include <net/cfg80211.h>
@@ -28,226 +29,226 @@ typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *,
* know about.
*/
static const struct iw_ioctl_description standard_ioctl[] = {
- [SIOCSIWCOMMIT - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWCOMMIT)] = {
.header_type = IW_HEADER_TYPE_NULL,
},
- [SIOCGIWNAME - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWNAME)] = {
.header_type = IW_HEADER_TYPE_CHAR,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWNWID - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWNWID)] = {
.header_type = IW_HEADER_TYPE_PARAM,
.flags = IW_DESCR_FLAG_EVENT,
},
- [SIOCGIWNWID - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWNWID)] = {
.header_type = IW_HEADER_TYPE_PARAM,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWFREQ - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWFREQ)] = {
.header_type = IW_HEADER_TYPE_FREQ,
.flags = IW_DESCR_FLAG_EVENT,
},
- [SIOCGIWFREQ - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWFREQ)] = {
.header_type = IW_HEADER_TYPE_FREQ,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWMODE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWMODE)] = {
.header_type = IW_HEADER_TYPE_UINT,
.flags = IW_DESCR_FLAG_EVENT,
},
- [SIOCGIWMODE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWMODE)] = {
.header_type = IW_HEADER_TYPE_UINT,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWSENS - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWSENS)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWSENS - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWSENS)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWRANGE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWRANGE)] = {
.header_type = IW_HEADER_TYPE_NULL,
},
- [SIOCGIWRANGE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWRANGE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_range),
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWPRIV - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWPRIV)] = {
.header_type = IW_HEADER_TYPE_NULL,
},
- [SIOCGIWPRIV - SIOCIWFIRST] = { /* (handled directly by us) */
+ [IW_IOCTL_IDX(SIOCGIWPRIV)] = { /* (handled directly by us) */
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct iw_priv_args),
.max_tokens = 16,
.flags = IW_DESCR_FLAG_NOMAX,
},
- [SIOCSIWSTATS - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWSTATS)] = {
.header_type = IW_HEADER_TYPE_NULL,
},
- [SIOCGIWSTATS - SIOCIWFIRST] = { /* (handled directly by us) */
+ [IW_IOCTL_IDX(SIOCGIWSTATS)] = { /* (handled directly by us) */
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_statistics),
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWSPY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWSPY)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr),
.max_tokens = IW_MAX_SPY,
},
- [SIOCGIWSPY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWSPY)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr) +
sizeof(struct iw_quality),
.max_tokens = IW_MAX_SPY,
},
- [SIOCSIWTHRSPY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWTHRSPY)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct iw_thrspy),
.min_tokens = 1,
.max_tokens = 1,
},
- [SIOCGIWTHRSPY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWTHRSPY)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct iw_thrspy),
.min_tokens = 1,
.max_tokens = 1,
},
- [SIOCSIWAP - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWAP)] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
- [SIOCGIWAP - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWAP)] = {
.header_type = IW_HEADER_TYPE_ADDR,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWMLME - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWMLME)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_mlme),
.max_tokens = sizeof(struct iw_mlme),
},
- [SIOCGIWAPLIST - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWAPLIST)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr) +
sizeof(struct iw_quality),
.max_tokens = IW_MAX_AP,
.flags = IW_DESCR_FLAG_NOMAX,
},
- [SIOCSIWSCAN - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWSCAN)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = 0,
.max_tokens = sizeof(struct iw_scan_req),
},
- [SIOCGIWSCAN - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWSCAN)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_SCAN_MAX_DATA,
.flags = IW_DESCR_FLAG_NOMAX,
},
- [SIOCSIWESSID - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWESSID)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE,
.flags = IW_DESCR_FLAG_EVENT,
},
- [SIOCGIWESSID - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWESSID)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE,
.flags = IW_DESCR_FLAG_DUMP,
},
- [SIOCSIWNICKN - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWNICKN)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE,
},
- [SIOCGIWNICKN - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWNICKN)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ESSID_MAX_SIZE,
},
- [SIOCSIWRATE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWRATE)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWRATE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWRATE)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWRTS - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWRTS)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWRTS - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWRTS)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWFRAG - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWFRAG)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWFRAG - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWFRAG)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWTXPOW - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWTXPOW)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWTXPOW - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWTXPOW)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWRETRY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWRETRY)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWRETRY - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWRETRY)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWENCODE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWENCODE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ENCODING_TOKEN_MAX,
.flags = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT,
},
- [SIOCGIWENCODE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWENCODE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_ENCODING_TOKEN_MAX,
.flags = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT,
},
- [SIOCSIWPOWER - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWPOWER)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWPOWER - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWPOWER)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWGENIE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWGENIE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
- [SIOCGIWGENIE - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWGENIE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
- [SIOCSIWAUTH - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWAUTH)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCGIWAUTH - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWAUTH)] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
- [SIOCSIWENCODEEXT - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWENCODEEXT)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
- [SIOCGIWENCODEEXT - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCGIWENCODEEXT)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_encode_ext),
.max_tokens = sizeof(struct iw_encode_ext) +
IW_ENCODING_TOKEN_MAX,
},
- [SIOCSIWPMKSA - SIOCIWFIRST] = {
+ [IW_IOCTL_IDX(SIOCSIWPMKSA)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.min_tokens = sizeof(struct iw_pmksa),
@@ -261,44 +262,44 @@ static const unsigned standard_ioctl_num = ARRAY_SIZE(standard_ioctl);
* we know about.
*/
static const struct iw_ioctl_description standard_event[] = {
- [IWEVTXDROP - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVTXDROP)] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
- [IWEVQUAL - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVQUAL)] = {
.header_type = IW_HEADER_TYPE_QUAL,
},
- [IWEVCUSTOM - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVCUSTOM)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_CUSTOM_MAX,
},
- [IWEVREGISTERED - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVREGISTERED)] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
- [IWEVEXPIRED - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVEXPIRED)] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
- [IWEVGENIE - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVGENIE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
- [IWEVMICHAELMICFAILURE - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVMICHAELMICFAILURE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_michaelmicfailure),
},
- [IWEVASSOCREQIE - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVASSOCREQIE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
- [IWEVASSOCRESPIE - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVASSOCRESPIE)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = IW_GENERIC_IE_MAX,
},
- [IWEVPMKIDCAND - IWEVFIRST] = {
+ [IW_EVENT_IDX(IWEVPMKIDCAND)] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = 1,
.max_tokens = sizeof(struct iw_pmkid_cand),
@@ -449,11 +450,11 @@ void wireless_send_event(struct net_device * dev,
/* Get the description of the Event */
if (cmd <= SIOCIWLAST) {
- cmd_index = cmd - SIOCIWFIRST;
+ cmd_index = IW_IOCTL_IDX(cmd);
if (cmd_index < standard_ioctl_num)
descr = &(standard_ioctl[cmd_index]);
} else {
- cmd_index = cmd - IWEVFIRST;
+ cmd_index = IW_EVENT_IDX(cmd);
if (cmd_index < standard_event_num)
descr = &(standard_event[cmd_index]);
}
@@ -662,7 +663,7 @@ static iw_handler get_handler(struct net_device *dev, unsigned int cmd)
return NULL;
/* Try as a standard command */
- index = cmd - SIOCIWFIRST;
+ index = IW_IOCTL_IDX(cmd);
if (index < handlers->num_standard)
return handlers->standard[index];
@@ -954,9 +955,9 @@ static int ioctl_standard_call(struct net_device * dev,
int ret = -EINVAL;
/* Get the description of the IOCTL */
- if ((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+ if (IW_IOCTL_IDX(cmd) >= standard_ioctl_num)
return -EOPNOTSUPP;
- descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+ descr = &(standard_ioctl[IW_IOCTL_IDX(cmd)]);
/* Check if we have a pointer to user space data or not */
if (descr->header_type != IW_HEADER_TYPE_POINT) {
@@ -1012,7 +1013,7 @@ static int compat_standard_call(struct net_device *dev,
struct iw_point iwp;
int err;
- descr = standard_ioctl + (cmd - SIOCIWFIRST);
+ descr = standard_ioctl + IW_IOCTL_IDX(cmd);
if (descr->header_type != IW_HEADER_TYPE_POINT)
return ioctl_standard_call(dev, iwr, cmd, info, handler);
diff --git a/net/wireless/wext-priv.c b/net/wireless/wext-priv.c
index a3c2277..3feb28e 100644
--- a/net/wireless/wext-priv.c
+++ b/net/wireless/wext-priv.c
@@ -7,6 +7,7 @@
*
* (As all part of the Linux kernel, this file is GPL)
*/
+#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <net/iw_handler.h>
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 5615a88..d5c6140 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -7,6 +7,7 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/cfg80211.h>
#include "wext-compat.h"
#include "nl80211.h"