diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-06 21:45:17 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:02:30 -0400 |
commit | 77fdaa12cea26c204cc12c312fe40bc0f3dcdfd8 (patch) | |
tree | c28fdd28f2ca2783783adb4b5e13b7ba57a223a3 /net/mac80211/cfg.c | |
parent | a7c1cfc9616ee76213a6d4fd4c17f13fdc92ddce (diff) |
mac80211: rework MLME for multiple authentications
Sit tight. This shakes up the world as you know
it. Let go of your spaghetti tongs, they will no
longer be required, the horrible statemachine in
net/mac80211/mlme.c is no more...
With the cfg80211 SME mac80211 now has much less
to keep track of, but, on the other hand, for FT
it needs to be able to keep track of at least one
authentication being in progress while associated.
So convert from a single state machine to having
small ones for all the different things we need to
do. For real FT it will still need work wrt. PS,
but this should be a good step.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 105 |
1 files changed, 4 insertions, 101 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e6d8860f26f2..7cfc14e4ca07 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1172,122 +1172,25 @@ static int ieee80211_scan(struct wiphy *wiphy, | |||
1172 | static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, | 1172 | static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, |
1173 | struct cfg80211_auth_request *req) | 1173 | struct cfg80211_auth_request *req) |
1174 | { | 1174 | { |
1175 | struct ieee80211_sub_if_data *sdata; | 1175 | return ieee80211_mgd_auth(IEEE80211_DEV_TO_SUB_IF(dev), req); |
1176 | const u8 *ssid; | ||
1177 | |||
1178 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1179 | |||
1180 | switch (req->auth_type) { | ||
1181 | case NL80211_AUTHTYPE_OPEN_SYSTEM: | ||
1182 | sdata->u.mgd.auth_alg = WLAN_AUTH_OPEN; | ||
1183 | break; | ||
1184 | case NL80211_AUTHTYPE_SHARED_KEY: | ||
1185 | sdata->u.mgd.auth_alg = WLAN_AUTH_SHARED_KEY; | ||
1186 | break; | ||
1187 | case NL80211_AUTHTYPE_FT: | ||
1188 | sdata->u.mgd.auth_alg = WLAN_AUTH_FT; | ||
1189 | break; | ||
1190 | case NL80211_AUTHTYPE_NETWORK_EAP: | ||
1191 | sdata->u.mgd.auth_alg = WLAN_AUTH_LEAP; | ||
1192 | break; | ||
1193 | default: | ||
1194 | return -EOPNOTSUPP; | ||
1195 | } | ||
1196 | |||
1197 | memcpy(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN); | ||
1198 | |||
1199 | sdata->local->oper_channel = req->bss->channel; | ||
1200 | ieee80211_hw_config(sdata->local, 0); | ||
1201 | |||
1202 | ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); | ||
1203 | if (!ssid) | ||
1204 | return -EINVAL; | ||
1205 | sdata->u.mgd.ssid_len = *(ssid + 1); | ||
1206 | memcpy(sdata->u.mgd.ssid, ssid + 2, sdata->u.mgd.ssid_len); | ||
1207 | |||
1208 | kfree(sdata->u.mgd.sme_auth_ie); | ||
1209 | sdata->u.mgd.sme_auth_ie = NULL; | ||
1210 | sdata->u.mgd.sme_auth_ie_len = 0; | ||
1211 | if (req->ie) { | ||
1212 | sdata->u.mgd.sme_auth_ie = kmalloc(req->ie_len, GFP_KERNEL); | ||
1213 | if (sdata->u.mgd.sme_auth_ie == NULL) | ||
1214 | return -ENOMEM; | ||
1215 | memcpy(sdata->u.mgd.sme_auth_ie, req->ie, req->ie_len); | ||
1216 | sdata->u.mgd.sme_auth_ie_len = req->ie_len; | ||
1217 | } | ||
1218 | |||
1219 | sdata->u.mgd.state = IEEE80211_STA_MLME_DIRECT_PROBE; | ||
1220 | ieee80211_sta_req_auth(sdata); | ||
1221 | return 0; | ||
1222 | } | 1176 | } |
1223 | 1177 | ||
1224 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | 1178 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, |
1225 | struct cfg80211_assoc_request *req) | 1179 | struct cfg80211_assoc_request *req) |
1226 | { | 1180 | { |
1227 | struct ieee80211_sub_if_data *sdata; | 1181 | return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); |
1228 | int ret, i; | ||
1229 | |||
1230 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1231 | |||
1232 | if (memcmp(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN) != 0 || | ||
1233 | !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED)) | ||
1234 | return -ENOLINK; /* not authenticated */ | ||
1235 | |||
1236 | sdata->u.mgd.flags &= ~IEEE80211_STA_DISABLE_11N; | ||
1237 | |||
1238 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | ||
1239 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | ||
1240 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | ||
1241 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) | ||
1242 | sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_11N; | ||
1243 | |||
1244 | sdata->local->oper_channel = req->bss->channel; | ||
1245 | ieee80211_hw_config(sdata->local, 0); | ||
1246 | |||
1247 | ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len); | ||
1248 | if (ret && ret != -EALREADY) | ||
1249 | return ret; | ||
1250 | |||
1251 | if (req->use_mfp) { | ||
1252 | sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED; | ||
1253 | sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED; | ||
1254 | } else { | ||
1255 | sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED; | ||
1256 | sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED; | ||
1257 | } | ||
1258 | |||
1259 | if (req->prev_bssid) { | ||
1260 | sdata->u.mgd.flags |= IEEE80211_STA_PREV_BSSID_SET; | ||
1261 | memcpy(sdata->u.mgd.prev_bssid, req->prev_bssid, ETH_ALEN); | ||
1262 | } else | ||
1263 | sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; | ||
1264 | |||
1265 | if (req->crypto.control_port) | ||
1266 | sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT; | ||
1267 | else | ||
1268 | sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; | ||
1269 | |||
1270 | sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE; | ||
1271 | ieee80211_sta_req_auth(sdata); | ||
1272 | return 0; | ||
1273 | } | 1182 | } |
1274 | 1183 | ||
1275 | static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, | 1184 | static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, |
1276 | struct cfg80211_deauth_request *req) | 1185 | struct cfg80211_deauth_request *req) |
1277 | { | 1186 | { |
1278 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1187 | return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev), req); |
1279 | |||
1280 | /* TODO: req->ie, req->peer_addr */ | ||
1281 | return ieee80211_sta_deauthenticate(sdata, req->reason_code); | ||
1282 | } | 1188 | } |
1283 | 1189 | ||
1284 | static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, | 1190 | static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, |
1285 | struct cfg80211_disassoc_request *req) | 1191 | struct cfg80211_disassoc_request *req) |
1286 | { | 1192 | { |
1287 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1193 | return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev), req); |
1288 | |||
1289 | /* TODO: req->ie, req->peer_addr */ | ||
1290 | return ieee80211_sta_disassociate(sdata, req->reason_code); | ||
1291 | } | 1194 | } |
1292 | 1195 | ||
1293 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | 1196 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, |