Commit aa458d17 authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville

mac80211: restructure disassoc/deauth flows

This patch restructure the flow of disassociation and deauthentication
flows to be consistent under all circumstances.
It ensures that BA session is treated down before deauthentication or disassociation,
adds the removal of the obsolete sta form station table and fixes a related bug (sta_info_destroy
without sta_info_unlink) in ieee80211_associated()
and reduce some code duplication
Signed-off-by: default avatarRon Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 79636a5f
...@@ -415,8 +415,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -415,8 +415,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
ieee80211_sta_send_associnfo(sdata, ifsta); ieee80211_sta_send_associnfo(sdata, ifsta);
} else { } else {
netif_carrier_off(sdata->dev);
ieee80211_sta_tear_down_BA_sessions(sdata, ifsta->bssid);
ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
changed |= ieee80211_reset_erp_info(sdata); changed |= ieee80211_reset_erp_info(sdata);
...@@ -439,18 +437,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -439,18 +437,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
} }
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_sta *ifsta, int deauth)
{
if (deauth) {
ifsta->direct_probe_tries = 0;
ifsta->auth_tries = 0;
}
ifsta->assoc_scan_tries = 0;
ifsta->assoc_tries = 0;
ieee80211_set_associated(sdata, ifsta, 0);
}
void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
int encrypt) int encrypt)
{ {
...@@ -844,6 +830,50 @@ static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -844,6 +830,50 @@ static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_tx(sdata, skb, 0); ieee80211_sta_tx(sdata, skb, 0);
} }
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_sta *ifsta, bool deauth,
bool self_disconnected, u16 reason)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
rcu_read_lock();
sta = sta_info_get(local, ifsta->bssid);
if (!sta) {
rcu_read_unlock();
return;
}
if (deauth) {
ifsta->direct_probe_tries = 0;
ifsta->auth_tries = 0;
}
ifsta->assoc_scan_tries = 0;
ifsta->assoc_tries = 0;
netif_carrier_off(sdata->dev);
ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr);
if (self_disconnected) {
if (deauth)
ieee80211_send_deauth(sdata, ifsta, reason);
else
ieee80211_send_disassoc(sdata, ifsta, reason);
}
ieee80211_set_associated(sdata, ifsta, 0);
if (self_disconnected)
ifsta->state = IEEE80211_STA_MLME_DISABLED;
sta_info_unlink(&sta);
rcu_read_unlock();
sta_info_destroy(sta);
}
static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_sta *ifsta) struct ieee80211_if_sta *ifsta)
...@@ -938,7 +968,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, ...@@ -938,7 +968,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
"range\n", "range\n",
sdata->dev->name, print_mac(mac, ifsta->bssid)); sdata->dev->name, print_mac(mac, ifsta->bssid));
disassoc = 1; disassoc = 1;
sta_info_unlink(&sta);
} else } else
ieee80211_send_probe_req(sdata, ifsta->bssid, ieee80211_send_probe_req(sdata, ifsta->bssid,
local->scan_ssid, local->scan_ssid,
...@@ -958,16 +987,12 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, ...@@ -958,16 +987,12 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock(); rcu_read_unlock();
if (disassoc && sta) if (disassoc)
sta_info_destroy(sta); ieee80211_set_disassoc(sdata, ifsta, true, true,
WLAN_REASON_PREV_AUTH_NOT_VALID);
if (disassoc) { else
ifsta->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_set_associated(sdata, ifsta, 0);
} else {
mod_timer(&ifsta->timer, jiffies + mod_timer(&ifsta->timer, jiffies +
IEEE80211_MONITORING_INTERVAL); IEEE80211_MONITORING_INTERVAL);
}
} }
...@@ -1832,7 +1857,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, ...@@ -1832,7 +1857,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
IEEE80211_RETRY_AUTH_INTERVAL); IEEE80211_RETRY_AUTH_INTERVAL);
} }
ieee80211_set_disassoc(sdata, ifsta, 1); ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED; ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
} }
...@@ -1862,7 +1887,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, ...@@ -1862,7 +1887,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
IEEE80211_RETRY_AUTH_INTERVAL); IEEE80211_RETRY_AUTH_INTERVAL);
} }
ieee80211_set_disassoc(sdata, ifsta, 0); ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
} }
...@@ -3200,8 +3225,8 @@ void ieee80211_sta_work(struct work_struct *work) ...@@ -3200,8 +3225,8 @@ void ieee80211_sta_work(struct work_struct *work)
printk(KERN_DEBUG "%s: privacy configuration mismatch and " printk(KERN_DEBUG "%s: privacy configuration mismatch and "
"mixed-cell disabled - disassociate\n", sdata->dev->name); "mixed-cell disabled - disassociate\n", sdata->dev->name);
ieee80211_send_disassoc(sdata, ifsta, WLAN_REASON_UNSPECIFIED); ieee80211_set_disassoc(sdata, ifsta, false, true,
ieee80211_set_disassoc(sdata, ifsta, 0); WLAN_REASON_UNSPECIFIED);
} }
} }
...@@ -4236,8 +4261,7 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason ...@@ -4236,8 +4261,7 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
sdata->vif.type != IEEE80211_IF_TYPE_IBSS) sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
return -EINVAL; return -EINVAL;
ieee80211_send_deauth(sdata, ifsta, reason); ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
ieee80211_set_disassoc(sdata, ifsta, 1);
return 0; return 0;
} }
...@@ -4255,8 +4279,7 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason) ...@@ -4255,8 +4279,7 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED)) if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
return -1; return -1;
ieee80211_send_disassoc(sdata, ifsta, reason); ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
ieee80211_set_disassoc(sdata, ifsta, 0);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment