summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/nl80211.c16
-rw-r--r--net/wireless/scan.c43
-rw-r--r--net/wireless/sme.c19
-rw-r--r--net/wireless/util.c2
5 files changed, 49 insertions, 36 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h
index bf0fb40e3c8..3dce1f167eb 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -245,6 +245,7 @@ struct cfg80211_event {
u16 status;
} cr;
struct {
+ struct ieee80211_channel *channel;
u8 bssid[ETH_ALEN];
const u8 *req_ie;
const u8 *resp_ie;
@@ -392,7 +393,9 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
struct net_device *dev, u16 reason,
bool wextev);
-void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+void __cfg80211_roamed(struct wireless_dev *wdev,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len);
int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2222ce08ee9..88a565f130a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3294,8 +3294,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
struct cfg80211_scan_request *request;
- struct cfg80211_ssid *ssid;
- struct ieee80211_channel *channel;
struct nlattr *attr;
struct wiphy *wiphy;
int err, tmp, n_ssids = 0, n_channels, i;
@@ -3342,8 +3340,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
request = kzalloc(sizeof(*request)
- + sizeof(*ssid) * n_ssids
- + sizeof(channel) * n_channels
+ + sizeof(*request->ssids) * n_ssids
+ + sizeof(*request->channels) * n_channels
+ ie_len, GFP_KERNEL);
if (!request)
return -ENOMEM;
@@ -3408,12 +3406,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
i = 0;
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
+ request->ssids[i].ssid_len = nla_len(attr);
if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
err = -EINVAL;
goto out_free;
}
memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
- request->ssids[i].ssid_len = nla_len(attr);
i++;
}
}
@@ -3449,8 +3447,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
struct cfg80211_sched_scan_request *request;
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1];
- struct cfg80211_ssid *ssid;
- struct ieee80211_channel *channel;
struct nlattr *attr;
struct wiphy *wiphy;
int err, tmp, n_ssids = 0, n_channels, i;
@@ -3507,8 +3503,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
return -EINVAL;
request = kzalloc(sizeof(*request)
- + sizeof(*ssid) * n_ssids
- + sizeof(channel) * n_channels
+ + sizeof(*request->ssids) * n_ssids
+ + sizeof(*request->channels) * n_channels
+ ie_len, GFP_KERNEL);
if (!request)
return -ENOMEM;
@@ -3576,6 +3572,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
tmp) {
+ request->ssids[i].ssid_len = nla_len(attr);
if (request->ssids[i].ssid_len >
IEEE80211_MAX_SSID_LEN) {
err = -EINVAL;
@@ -3583,7 +3580,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
}
memcpy(request->ssids[i].ssid, nla_data(attr),
nla_len(attr));
- request->ssids[i].ssid_len = nla_len(attr);
i++;
}
}
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 73a441d237b..7a6c67667d7 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -267,13 +267,35 @@ static bool is_bss(struct cfg80211_bss *a,
return memcmp(ssidie + 2, ssid, ssid_len) == 0;
}
+static bool is_mesh_bss(struct cfg80211_bss *a)
+{
+ const u8 *ie;
+
+ if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
+ return false;
+
+ ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
+ a->information_elements,
+ a->len_information_elements);
+ if (!ie)
+ return false;
+
+ ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
+ a->information_elements,
+ a->len_information_elements);
+ if (!ie)
+ return false;
+
+ return true;
+}
+
static bool is_mesh(struct cfg80211_bss *a,
const u8 *meshid, size_t meshidlen,
const u8 *meshcfg)
{
const u8 *ie;
- if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
+ if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
return false;
ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
@@ -311,7 +333,7 @@ static int cmp_bss(struct cfg80211_bss *a,
if (a->channel != b->channel)
return b->channel->center_freq - a->channel->center_freq;
- if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) {
+ if (is_mesh_bss(a) && is_mesh_bss(b)) {
r = cmp_ies(WLAN_EID_MESH_ID,
a->information_elements,
a->len_information_elements,
@@ -457,7 +479,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
struct cfg80211_internal_bss *res)
{
struct cfg80211_internal_bss *found = NULL;
- const u8 *meshid, *meshcfg;
/*
* The reference to "res" is donated to this function.
@@ -470,22 +491,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
res->ts = jiffies;
- if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
- /* must be mesh, verify */
- meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
- res->pub.information_elements,
- res->pub.len_information_elements);
- meshcfg = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
- res->pub.information_elements,
- res->pub.len_information_elements);
- if (!meshid || !meshcfg ||
- meshcfg[1] != sizeof(struct ieee80211_meshconf_ie)) {
- /* bogus mesh */
- kref_put(&res->ref, bss_release);
- return NULL;
- }
- }
-
spin_lock_bh(&dev->bss_lock);
found = rb_find_bss(dev, res);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index e17b0bee6bd..b7b6ff8be55 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -250,7 +250,8 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
if (wdev->conn->params.privacy)
capa |= WLAN_CAPABILITY_PRIVACY;
- bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid,
+ bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
+ wdev->conn->params.bssid,
wdev->conn->params.ssid,
wdev->conn->params.ssid_len,
WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
@@ -470,7 +471,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
}
if (!bss)
- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+ bss = cfg80211_get_bss(wdev->wiphy,
+ wdev->conn ? wdev->conn->params.channel :
+ NULL,
+ bssid,
wdev->ssid, wdev->ssid_len,
WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS);
@@ -538,7 +542,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
}
EXPORT_SYMBOL(cfg80211_connect_result);
-void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+void __cfg80211_roamed(struct wireless_dev *wdev,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len)
{
@@ -565,7 +571,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
cfg80211_put_bss(&wdev->current_bss->pub);
wdev->current_bss = NULL;
- bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+ bss = cfg80211_get_bss(wdev->wiphy, channel, bssid,
wdev->ssid, wdev->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
@@ -603,7 +609,9 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
#endif
}
-void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+void cfg80211_roamed(struct net_device *dev,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
const u8 *req_ie, size_t req_ie_len,
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
{
@@ -619,6 +627,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
return;
ev->type = EVENT_ROAMED;
+ ev->rm.channel = channel;
memcpy(ev->rm.bssid, bssid, ETH_ALEN);
ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
ev->rm.req_ie_len = req_ie_len;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f0536d44d43..4d7b83fbc32 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -746,7 +746,7 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
NULL);
break;
case EVENT_ROAMED:
- __cfg80211_roamed(wdev, ev->rm.bssid,
+ __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid,
ev->rm.req_ie, ev->rm.req_ie_len,
ev->rm.resp_ie, ev->rm.resp_ie_len);
break;