aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r--net/wireless/mlme.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 46f3711..caf11a4 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -876,21 +876,53 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
- /* Verify that we are associated with the destination AP */
+ int err = 0;
+
wdev_lock(wdev);
- if (!wdev->current_bss ||
- memcmp(wdev->current_bss->pub.bssid, mgmt->bssid,
- ETH_ALEN) != 0 ||
- ((wdev->iftype == NL80211_IFTYPE_STATION ||
- wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
- memcmp(wdev->current_bss->pub.bssid, mgmt->da,
- ETH_ALEN) != 0)) {
- wdev_unlock(wdev);
- return -ENOTCONN;
- }
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ if (!wdev->current_bss) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ if (memcmp(wdev->current_bss->pub.bssid,
+ mgmt->bssid, ETH_ALEN)) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ /*
+ * check for IBSS DA must be done by driver as
+ * cfg80211 doesn't track the stations
+ */
+ if (wdev->iftype == NL80211_IFTYPE_ADHOC)
+ break;
+ /* for station, check that DA is the AP */
+ if (memcmp(wdev->current_bss->pub.bssid,
+ mgmt->da, ETH_ALEN)) {
+ err = -ENOTCONN;
+ break;
+ }
+ break;
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ case NL80211_IFTYPE_AP_VLAN:
+ if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
+ err = -EINVAL;
+ break;
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
wdev_unlock(wdev);
+
+ if (err)
+ return err;
}
if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)