mac80211: split IBSS/managed code
This patch splits out the ibss code and data from managed (station) mode.
The reason to do this is to better separate the state machines, and have
the code be contained better so it gets easier to determine what exactly
a given change will affect, that in turn makes it easier to understand.
This is quite some churn, especially because I split sdata->u.sta into
sdata->u.mgd and sdata->u.ibss, but I think it's easier to maintain that
way. I've also shuffled around some code -- null function sending is only
applicable to managed interfaces so put that into that file, some other
functions are needed from various places so put them into util, and also
rearranged the prototypes in ieee80211_i.h accordingly.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 2b023dc..8a76a97 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -132,13 +132,12 @@
if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
return -EOPNOTSUPP;
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
if (ret)
return ret;
- sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
- ieee80211_sta_req_auth(sdata, &sdata->u.sta);
+ sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
+ ieee80211_sta_req_auth(sdata);
return 0;
}
@@ -255,16 +254,19 @@
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_STATION)
- sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
if (freq->e == 0) {
if (freq->m < 0) {
- if (sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_STATION)
- sdata->u.sta.flags |=
+ if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ sdata->u.ibss.flags |=
+ IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+ else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sdata->u.mgd.flags |=
IEEE80211_STA_AUTO_CHANNEL_SEL;
return 0;
} else
@@ -301,32 +303,35 @@
{
struct ieee80211_sub_if_data *sdata;
size_t len = data->length;
+ int ret;
/* iwconfig uses nul termination in SSID.. */
if (len > 0 && ssid[len - 1] == '\0')
len--;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- int ret;
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
if (len > IEEE80211_MAX_SSID_LEN)
return -EINVAL;
- memcpy(sdata->u.sta.ssid, ssid, len);
- sdata->u.sta.ssid_len = len;
+ memcpy(sdata->u.mgd.ssid, ssid, len);
+ sdata->u.mgd.ssid_len = len;
return 0;
}
+
if (data->flags)
- sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
else
- sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL;
+ sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
+
ret = ieee80211_sta_set_ssid(sdata, ssid, len);
if (ret)
return ret;
- ieee80211_sta_req_auth(sdata, &sdata->u.sta);
+
+ ieee80211_sta_req_auth(sdata);
return 0;
- }
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ return ieee80211_ibss_set_ssid(sdata, ssid, len);
return -EOPNOTSUPP;
}
@@ -340,8 +345,7 @@
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
if (res == 0) {
data->length = len;
@@ -349,6 +353,14 @@
} else
data->flags = 0;
return res;
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
+ if (res == 0) {
+ data->length = len;
+ data->flags = 1;
+ } else
+ data->flags = 0;
+ return res;
}
return -EOPNOTSUPP;
@@ -362,26 +374,35 @@
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
int ret;
if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
- memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
+ memcpy(sdata->u.mgd.bssid, (u8 *) &ap_addr->sa_data,
ETH_ALEN);
return 0;
}
if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
- sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
+ sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
IEEE80211_STA_AUTO_CHANNEL_SEL;
else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
- sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
+ sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
else
- sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
if (ret)
return ret;
- ieee80211_sta_req_auth(sdata, &sdata->u.sta);
+ ieee80211_sta_req_auth(sdata);
return 0;
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
+ sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
+ IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+ else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
+ sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
+ else
+ sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
+
+ return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
/*
* If it is necessary to update the WDS peer address
@@ -410,17 +431,20 @@
struct ieee80211_sub_if_data *sdata;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
- if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATED ||
- sdata->u.sta.state == IEEE80211_STA_MLME_IBSS_JOINED) {
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+ if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
ap_addr->sa_family = ARPHRD_ETHER;
- memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
- return 0;
- } else {
+ memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN);
+ } else
memset(&ap_addr->sa_data, 0, ETH_ALEN);
- return 0;
- }
+ return 0;
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
+ } else
+ memset(&ap_addr->sa_data, 0, ETH_ALEN);
+ return 0;
} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -486,7 +510,7 @@
rcu_read_lock();
- sta = sta_info_get(local, sdata->u.sta.bssid);
+ sta = sta_info_get(local, sdata->u.mgd.bssid);
if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
@@ -687,8 +711,7 @@
struct iw_mlme *mlme = (struct iw_mlme *) extra;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
return -EINVAL;
switch (mlme->cmd) {
@@ -784,8 +807,7 @@
erq->flags |= IW_ENCODE_ENABLED;
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- struct ieee80211_if_sta *ifsta = &sdata->u.sta;
- switch (ifsta->auth_alg) {
+ switch (sdata->u.mgd.auth_alg) {
case WLAN_AUTH_OPEN:
case WLAN_AUTH_LEAP:
erq->flags |= IW_ENCODE_OPEN;
@@ -849,7 +871,7 @@
ret = ieee80211_hw_config(local,
IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
- if (!(sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED))
+ if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
return ret;
if (conf->dynamic_ps_timeout > 0 &&
@@ -908,10 +930,10 @@
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
if (data->value & (IW_AUTH_CIPHER_WEP40 |
IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
- sdata->u.sta.flags |=
+ sdata->u.mgd.flags |=
IEEE80211_STA_TKIP_WEP_USED;
else
- sdata->u.sta.flags &=
+ sdata->u.mgd.flags &=
~IEEE80211_STA_TKIP_WEP_USED;
}
break;
@@ -922,21 +944,20 @@
if (sdata->vif.type != NL80211_IFTYPE_STATION)
ret = -EINVAL;
else {
- sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
+ sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
/*
* Privacy invoked by wpa_supplicant, store the
* value and allow associating to a protected
* network without having a key up front.
*/
if (data->value)
- sdata->u.sta.flags |=
+ sdata->u.mgd.flags |=
IEEE80211_STA_PRIVACY_INVOKED;
}
break;
case IW_AUTH_80211_AUTH_ALG:
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC)
- sdata->u.sta.auth_algs = data->value;
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sdata->u.mgd.auth_algs = data->value;
else
ret = -EOPNOTSUPP;
break;
@@ -945,17 +966,16 @@
ret = -EOPNOTSUPP;
break;
}
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
switch (data->value) {
case IW_AUTH_MFP_DISABLED:
- sdata->u.sta.mfp = IEEE80211_MFP_DISABLED;
+ sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
break;
case IW_AUTH_MFP_OPTIONAL:
- sdata->u.sta.mfp = IEEE80211_MFP_OPTIONAL;
+ sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
break;
case IW_AUTH_MFP_REQUIRED:
- sdata->u.sta.mfp = IEEE80211_MFP_REQUIRED;
+ sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
break;
default:
ret = -EINVAL;
@@ -980,9 +1000,9 @@
rcu_read_lock();
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC)
- sta = sta_info_get(local, sdata->u.sta.bssid);
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sta = sta_info_get(local, sdata->u.mgd.bssid);
+
if (!sta) {
wstats->discard.fragment = 0;
wstats->discard.misc = 0;
@@ -1011,9 +1031,8 @@
switch (data->flags & IW_AUTH_INDEX) {
case IW_AUTH_80211_AUTH_ALG:
- if (sdata->vif.type == NL80211_IFTYPE_STATION ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC)
- data->value = sdata->u.sta.auth_algs;
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ data->value = sdata->u.mgd.auth_algs;
else
ret = -EOPNOTSUPP;
break;