diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 20 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 7 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 |
3 files changed, 26 insertions, 3 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1d17677a0ec..119a573af14 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -713,6 +713,12 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) sta->flags |= WLAN_STA_AUTH; } + + if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + sta->flags &= ~WLAN_STA_TDLS_PEER; + if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + sta->flags |= WLAN_STA_TDLS_PEER; + } spin_unlock_irqrestore(&sta->flaglock, flags); if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { @@ -813,6 +819,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, sta_apply_parameters(local, sta, params); + /* Only TDLS-supporting stations can add TDLS peers */ + if ((sta->flags & WLAN_STA_TDLS_PEER) && + !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) && + sdata->vif.type == NL80211_IFTYPE_STATION)) + return -ENOTSUPP; + rate_control_rate_init(sta); layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || @@ -865,6 +877,14 @@ static int ieee80211_change_station(struct wiphy *wiphy, return -ENOENT; } + /* The TDLS bit cannot be toggled after the STA was added */ + if ((params->sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) && + !!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) != + !!test_sta_flags(sta, WLAN_STA_TDLS_PEER)) { + rcu_read_unlock(); + return -EINVAL; + } + if (params->vlan && params->vlan != sta->sdata->dev) { vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cd37a4e3c0d..b98c43a7f19 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1137,8 +1137,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; ieee80211_bss_info_change_notify(sdata, changed); + /* remove AP and TDLS peers */ if (remove_sta) - sta_info_destroy_addr(sdata, bssid); + sta_info_flush(local, sdata); del_timer_sync(&sdata->u.mgd.conn_mon_timer); del_timer_sync(&sdata->u.mgd.bcn_mon_timer); @@ -2738,7 +2739,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, req->reason_code, cookie, !req->local_state_change); if (assoc_bss) - sta_info_destroy_addr(sdata, bssid); + sta_info_flush(sdata->local, sdata); mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); @@ -2778,7 +2779,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, IEEE80211_STYPE_DISASSOC, req->reason_code, cookie, !req->local_state_change); - sta_info_destroy_addr(sdata, bssid); + sta_info_flush(sdata->local, sdata); mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 56a3d38a2cd..b6bd4e9d872 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -45,6 +45,7 @@ * station in power-save mode, reply when the driver unblocks. * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal * buffers. Automatically cleared on station wake-up. + * @WLAN_STA_TDLS_PEER: station is a TDLS peer. */ enum ieee80211_sta_info_flags { WLAN_STA_AUTH = 1<<0, @@ -61,6 +62,7 @@ enum ieee80211_sta_info_flags { WLAN_STA_PS_DRIVER = 1<<12, WLAN_STA_PSPOLL = 1<<13, WLAN_STA_PS_DRIVER_BUF = 1<<14, + WLAN_STA_TDLS_PEER = 1<<15, }; #define STA_TID_NUM 16 |