cfg80211: Add support for randomizing TA of Public Action frames
[platform/kernel/linux-exynos.git] / net / wireless / mlme.c
index cbb48e2..b876f40 100644 (file)
@@ -149,6 +149,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
 }
 EXPORT_SYMBOL(cfg80211_assoc_timeout);
 
+void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct wiphy *wiphy = wdev->wiphy;
+
+       cfg80211_sme_abandon_assoc(wdev);
+
+       cfg80211_unhold_bss(bss_from_pub(bss));
+       cfg80211_put_bss(wiphy, bss);
+}
+EXPORT_SYMBOL(cfg80211_abandon_assoc);
+
 void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -204,14 +216,14 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
                       const u8 *ssid, int ssid_len,
                       const u8 *ie, int ie_len,
                       const u8 *key, int key_len, int key_idx,
-                      const u8 *sae_data, int sae_data_len)
+                      const u8 *auth_data, int auth_data_len)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_auth_request req = {
                .ie = ie,
                .ie_len = ie_len,
-               .sae_data = sae_data,
-               .sae_data_len = sae_data_len,
+               .auth_data = auth_data,
+               .auth_data_len = auth_data_len,
                .auth_type = auth_type,
                .key = key,
                .key_len = key_len,
@@ -333,6 +345,11 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
             !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
                return 0;
 
+       if (ether_addr_equal(wdev->disconnect_bssid, bssid) ||
+           (wdev->current_bss &&
+            ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
+               wdev->conn_owner_nlportid = 0;
+
        return rdev_deauth(rdev, dev, &req);
 }
 
@@ -645,8 +662,25 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
                        return err;
        }
 
-       if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
-               return -EINVAL;
+       if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) {
+               /* Allow random TA to be used with Public Action frames if the
+                * driver has indicated support for this. Otherwise, only allow
+                * the local address to be used.
+                */
+               if (!ieee80211_is_action(mgmt->frame_control) ||
+                   mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
+                       return -EINVAL;
+               if (!wdev->current_bss &&
+                   !wiphy_ext_feature_isset(
+                           &rdev->wiphy,
+                           NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
+                       return -EINVAL;
+               if (wdev->current_bss &&
+                   !wiphy_ext_feature_isset(
+                           &rdev->wiphy,
+                           NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
+                       return -EINVAL;
+       }
 
        /* Transmit the Action frame as requested by user space */
        return rdev_mgmt_tx(rdev, wdev, params, cookie);