cfg80211: allow changing station capabilities for unassociated stations
authorAyala Beker <ayala.beker@intel.com>
Mon, 21 Sep 2015 12:49:53 +0000 (15:49 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 29 Sep 2015 13:56:50 +0000 (15:56 +0200)
Currently, cfg80211 rejects capability updates for existing entries
and as a result it's impossible to update entries that were added
unassociated, but that is necessary to go through the full station
states from userspace, adding a station before authentication etc.

Fix this by allowing updates to capabilities for stations that the
driver (or mac80211) assigned unassociated state. Drivers setting
the full station state support flag must use the new station type
for proper operation.

Signed-off-by: Ayala Beker <ayala.beker@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
net/wireless/nl80211.c

index 0f54c9ef4c7d62a619fac81b55eed609b90617cd..90332a1838ccbf8cb7ef34463bc16f76a47859b0 100644 (file)
@@ -858,6 +858,8 @@ struct station_del_parameters {
 /**
  * enum cfg80211_station_type - the type of station being modified
  * @CFG80211_STA_AP_CLIENT: client of an AP interface
+ * @CFG80211_STA_AP_CLIENT_UNASSOC: client of an AP interface that is still
+ *     unassociated (update properties for this type of client is permitted)
  * @CFG80211_STA_AP_MLME_CLIENT: client of an AP interface that has
  *     the AP MLME in the device
  * @CFG80211_STA_AP_STA: AP station on managed interface
@@ -873,6 +875,7 @@ struct station_del_parameters {
  */
 enum cfg80211_station_type {
        CFG80211_STA_AP_CLIENT,
+       CFG80211_STA_AP_CLIENT_UNASSOC,
        CFG80211_STA_AP_MLME_CLIENT,
        CFG80211_STA_AP_STA,
        CFG80211_STA_IBSS,
index 50cd7707040ce2ca3eb43277fd0f898b471a89da..f05ba8b7af61fe250aa6ae46960f2557228f5c89 100644 (file)
@@ -4009,7 +4009,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
                params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
        }
 
-       if (statype != CFG80211_STA_TDLS_PEER_SETUP) {
+       if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
+           statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
                /* reject other things that can't change */
                if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
                        return -EINVAL;
@@ -4021,7 +4022,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
                        return -EINVAL;
        }
 
-       if (statype != CFG80211_STA_AP_CLIENT) {
+       if (statype != CFG80211_STA_AP_CLIENT &&
+           statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
                if (params->vlan)
                        return -EINVAL;
        }
@@ -4033,6 +4035,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
                        return -EOPNOTSUPP;
                break;
        case CFG80211_STA_AP_CLIENT:
+       case CFG80211_STA_AP_CLIENT_UNASSOC:
                /* accept only the listed bits */
                if (params->sta_flags_mask &
                                ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |