Commit a1cf775d authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: refactor common auth/assoc setup code

As associating is possible without first authenticating
(for FT over DS) association also has to be able to
switch to the right channel, insert the station entry
etc. Factor out this common code into a new function
called ieee80211_prep_connection().
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0775f9f9
...@@ -3089,6 +3089,60 @@ int ieee80211_max_network_latency(struct notifier_block *nb, ...@@ -3089,6 +3089,60 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
return 0; return 0;
} }
static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *bss, bool assoc)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct sta_info *sta;
bool have_sta = false;
int err;
if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
return -EINVAL;
if (assoc) {
rcu_read_lock();
have_sta = sta_info_get(sdata, bss->bssid);
rcu_read_unlock();
}
if (!have_sta) {
sta = sta_info_alloc(sdata, bss->bssid, GFP_KERNEL);
if (!sta)
return -ENOMEM;
}
mutex_lock(&local->mtx);
ieee80211_recalc_idle(sdata->local);
mutex_unlock(&local->mtx);
/* switch to the right channel */
local->oper_channel = bss->channel;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
if (!have_sta) {
/* set BSSID - if STA already there this will be set too */
memcpy(ifmgd->bssid, bss->bssid, ETH_ALEN);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
if (assoc)
sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
err = sta_info_insert(sta);
sta = NULL;
if (err) {
printk(KERN_DEBUG
"%s: failed to insert STA entry for the AP (error %d)\n",
sdata->name, err);
return err;
}
} else
WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, bss->bssid));
return 0;
}
/* config hooks */ /* config hooks */
int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
struct cfg80211_auth_request *req) struct cfg80211_auth_request *req)
...@@ -3096,7 +3150,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, ...@@ -3096,7 +3150,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_mgd_auth_data *auth_data; struct ieee80211_mgd_auth_data *auth_data;
struct sta_info *sta;
u16 auth_alg; u16 auth_alg;
int err; int err;
...@@ -3162,32 +3215,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, ...@@ -3162,32 +3215,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: authenticate with %pM\n", printk(KERN_DEBUG "%s: authenticate with %pM\n",
sdata->name, req->bss->bssid); sdata->name, req->bss->bssid);
mutex_lock(&local->mtx); err = ieee80211_prep_connection(sdata, req->bss, false);
ieee80211_recalc_idle(sdata->local); if (err)
mutex_unlock(&local->mtx);
/* switch to the right channel */
local->oper_channel = req->bss->channel;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
/* set BSSID */
memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
/* add station entry */
sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
if (!sta) {
err = -ENOMEM;
goto err_clear;
}
err = sta_info_insert(sta);
if (err) {
printk(KERN_DEBUG
"%s: failed to insert STA entry for the AP %pM (error %d)\n",
sdata->name, req->bss->bssid, err);
goto err_clear; goto err_clear;
}
err = ieee80211_probe_auth(sdata); err = ieee80211_probe_auth(sdata);
if (err) { if (err) {
...@@ -3218,7 +3248,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ...@@ -3218,7 +3248,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss = (void *)req->bss->priv; struct ieee80211_bss *bss = (void *)req->bss->priv;
struct ieee80211_mgd_assoc_data *assoc_data; struct ieee80211_mgd_assoc_data *assoc_data;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct sta_info *sta;
const u8 *ssidie; const u8 *ssidie;
int i, err; int i, err;
...@@ -3343,41 +3372,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ...@@ -3343,41 +3372,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->assoc_data = assoc_data; ifmgd->assoc_data = assoc_data;
mutex_lock(&local->mtx); err = ieee80211_prep_connection(sdata, req->bss, true);
ieee80211_recalc_idle(sdata->local); if (err)
mutex_unlock(&local->mtx); goto err_clear;
/* switch to the right channel */
local->oper_channel = req->bss->channel;
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
rcu_read_lock();
sta = sta_info_get(sdata, req->bss->bssid);
rcu_read_unlock();
if (!sta) {
/* set BSSID */
memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
if (!sta) {
err = -ENOMEM;
goto err_clear;
}
sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
err = sta_info_insert(sta);
sta = NULL;
if (err) {
printk(KERN_DEBUG
"%s: failed to insert STA entry for the AP (error %d)\n",
sdata->name, err);
goto err_clear;
}
} else
WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid));
if (!bss->dtim_period && if (!bss->dtim_period &&
sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
......
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