aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-02-15 06:44:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:51:42 -0500
commit469002983fc90c2ff0959e2b03335c0fe2e4d5a9 (patch)
treefdcf78dcdaeadba897abd86d39d0275e236803b3 /net/mac80211/wext.c
parent96f5e66e8a79810e2982cdcfa28e554f3d97da21 (diff)
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>
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c141
1 files changed, 80 insertions, 61 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 2b023dce8b24..8a76a979bc92 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -132,13 +132,12 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
132 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) 132 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
133 return -EOPNOTSUPP; 133 return -EOPNOTSUPP;
134 134
135 if (sdata->vif.type == NL80211_IFTYPE_STATION || 135 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
136 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
137 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length); 136 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
138 if (ret) 137 if (ret)
139 return ret; 138 return ret;
140 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 139 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
141 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 140 ieee80211_sta_req_auth(sdata);
142 return 0; 141 return 0;
143 } 142 }
144 143
@@ -255,16 +254,19 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
255{ 254{
256 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 255 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
257 256
258 if (sdata->vif.type == NL80211_IFTYPE_ADHOC || 257 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
259 sdata->vif.type == NL80211_IFTYPE_STATION) 258 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL;
260 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 259 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
260 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
261 261
262 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 262 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
263 if (freq->e == 0) { 263 if (freq->e == 0) {
264 if (freq->m < 0) { 264 if (freq->m < 0) {
265 if (sdata->vif.type == NL80211_IFTYPE_ADHOC || 265 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
266 sdata->vif.type == NL80211_IFTYPE_STATION) 266 sdata->u.ibss.flags |=
267 sdata->u.sta.flags |= 267 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
268 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
269 sdata->u.mgd.flags |=
268 IEEE80211_STA_AUTO_CHANNEL_SEL; 270 IEEE80211_STA_AUTO_CHANNEL_SEL;
269 return 0; 271 return 0;
270 } else 272 } else
@@ -301,32 +303,35 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
301{ 303{
302 struct ieee80211_sub_if_data *sdata; 304 struct ieee80211_sub_if_data *sdata;
303 size_t len = data->length; 305 size_t len = data->length;
306 int ret;
304 307
305 /* iwconfig uses nul termination in SSID.. */ 308 /* iwconfig uses nul termination in SSID.. */
306 if (len > 0 && ssid[len - 1] == '\0') 309 if (len > 0 && ssid[len - 1] == '\0')
307 len--; 310 len--;
308 311
309 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 312 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
310 if (sdata->vif.type == NL80211_IFTYPE_STATION || 313 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
311 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
312 int ret;
313 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 314 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
314 if (len > IEEE80211_MAX_SSID_LEN) 315 if (len > IEEE80211_MAX_SSID_LEN)
315 return -EINVAL; 316 return -EINVAL;
316 memcpy(sdata->u.sta.ssid, ssid, len); 317 memcpy(sdata->u.mgd.ssid, ssid, len);
317 sdata->u.sta.ssid_len = len; 318 sdata->u.mgd.ssid_len = len;
318 return 0; 319 return 0;
319 } 320 }
321
320 if (data->flags) 322 if (data->flags)
321 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 323 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
322 else 324 else
323 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL; 325 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
326
324 ret = ieee80211_sta_set_ssid(sdata, ssid, len); 327 ret = ieee80211_sta_set_ssid(sdata, ssid, len);
325 if (ret) 328 if (ret)
326 return ret; 329 return ret;
327 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 330
331 ieee80211_sta_req_auth(sdata);
328 return 0; 332 return 0;
329 } 333 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
334 return ieee80211_ibss_set_ssid(sdata, ssid, len);
330 335
331 return -EOPNOTSUPP; 336 return -EOPNOTSUPP;
332} 337}
@@ -340,8 +345,7 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
340 345
341 struct ieee80211_sub_if_data *sdata; 346 struct ieee80211_sub_if_data *sdata;
342 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 347 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
343 if (sdata->vif.type == NL80211_IFTYPE_STATION || 348 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
344 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
345 int res = ieee80211_sta_get_ssid(sdata, ssid, &len); 349 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
346 if (res == 0) { 350 if (res == 0) {
347 data->length = len; 351 data->length = len;
@@ -349,6 +353,14 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
349 } else 353 } else
350 data->flags = 0; 354 data->flags = 0;
351 return res; 355 return res;
356 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
357 int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
358 if (res == 0) {
359 data->length = len;
360 data->flags = 1;
361 } else
362 data->flags = 0;
363 return res;
352 } 364 }
353 365
354 return -EOPNOTSUPP; 366 return -EOPNOTSUPP;
@@ -362,26 +374,35 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
362 struct ieee80211_sub_if_data *sdata; 374 struct ieee80211_sub_if_data *sdata;
363 375
364 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 376 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
365 if (sdata->vif.type == NL80211_IFTYPE_STATION || 377 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
366 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
367 int ret; 378 int ret;
368 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 379 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
369 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data, 380 memcpy(sdata->u.mgd.bssid, (u8 *) &ap_addr->sa_data,
370 ETH_ALEN); 381 ETH_ALEN);
371 return 0; 382 return 0;
372 } 383 }
373 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) 384 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
374 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL | 385 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
375 IEEE80211_STA_AUTO_CHANNEL_SEL; 386 IEEE80211_STA_AUTO_CHANNEL_SEL;
376 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data)) 387 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
377 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL; 388 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
378 else 389 else
379 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 390 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
380 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); 391 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
381 if (ret) 392 if (ret)
382 return ret; 393 return ret;
383 ieee80211_sta_req_auth(sdata, &sdata->u.sta); 394 ieee80211_sta_req_auth(sdata);
384 return 0; 395 return 0;
396 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
397 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
398 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
399 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
400 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
401 sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
402 else
403 sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
404
405 return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
385 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 406 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
386 /* 407 /*
387 * If it is necessary to update the WDS peer address 408 * If it is necessary to update the WDS peer address
@@ -410,17 +431,20 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
410 struct ieee80211_sub_if_data *sdata; 431 struct ieee80211_sub_if_data *sdata;
411 432
412 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 433 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
413 if (sdata->vif.type == NL80211_IFTYPE_STATION || 434 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
414 sdata->vif.type == NL80211_IFTYPE_ADHOC) { 435 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
415 if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATED ||
416 sdata->u.sta.state == IEEE80211_STA_MLME_IBSS_JOINED) {
417 ap_addr->sa_family = ARPHRD_ETHER; 436 ap_addr->sa_family = ARPHRD_ETHER;
418 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); 437 memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN);
419 return 0; 438 } else
420 } else {
421 memset(&ap_addr->sa_data, 0, ETH_ALEN); 439 memset(&ap_addr->sa_data, 0, ETH_ALEN);
422 return 0; 440 return 0;
423 } 441 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
442 if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
443 ap_addr->sa_family = ARPHRD_ETHER;
444 memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
445 } else
446 memset(&ap_addr->sa_data, 0, ETH_ALEN);
447 return 0;
424 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 448 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
425 ap_addr->sa_family = ARPHRD_ETHER; 449 ap_addr->sa_family = ARPHRD_ETHER;
426 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 450 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -486,7 +510,7 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
486 510
487 rcu_read_lock(); 511 rcu_read_lock();
488 512
489 sta = sta_info_get(local, sdata->u.sta.bssid); 513 sta = sta_info_get(local, sdata->u.mgd.bssid);
490 514
491 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) 515 if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
492 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; 516 rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
@@ -687,8 +711,7 @@ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
687 struct iw_mlme *mlme = (struct iw_mlme *) extra; 711 struct iw_mlme *mlme = (struct iw_mlme *) extra;
688 712
689 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 713 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
690 if (sdata->vif.type != NL80211_IFTYPE_STATION && 714 if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
691 sdata->vif.type != NL80211_IFTYPE_ADHOC)
692 return -EINVAL; 715 return -EINVAL;
693 716
694 switch (mlme->cmd) { 717 switch (mlme->cmd) {
@@ -784,8 +807,7 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
784 erq->flags |= IW_ENCODE_ENABLED; 807 erq->flags |= IW_ENCODE_ENABLED;
785 808
786 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 809 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
787 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 810 switch (sdata->u.mgd.auth_alg) {
788 switch (ifsta->auth_alg) {
789 case WLAN_AUTH_OPEN: 811 case WLAN_AUTH_OPEN:
790 case WLAN_AUTH_LEAP: 812 case WLAN_AUTH_LEAP:
791 erq->flags |= IW_ENCODE_OPEN; 813 erq->flags |= IW_ENCODE_OPEN;
@@ -849,7 +871,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
849 ret = ieee80211_hw_config(local, 871 ret = ieee80211_hw_config(local,
850 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); 872 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
851 873
852 if (!(sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) 874 if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
853 return ret; 875 return ret;
854 876
855 if (conf->dynamic_ps_timeout > 0 && 877 if (conf->dynamic_ps_timeout > 0 &&
@@ -908,10 +930,10 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
908 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 930 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
909 if (data->value & (IW_AUTH_CIPHER_WEP40 | 931 if (data->value & (IW_AUTH_CIPHER_WEP40 |
910 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP)) 932 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
911 sdata->u.sta.flags |= 933 sdata->u.mgd.flags |=
912 IEEE80211_STA_TKIP_WEP_USED; 934 IEEE80211_STA_TKIP_WEP_USED;
913 else 935 else
914 sdata->u.sta.flags &= 936 sdata->u.mgd.flags &=
915 ~IEEE80211_STA_TKIP_WEP_USED; 937 ~IEEE80211_STA_TKIP_WEP_USED;
916 } 938 }
917 break; 939 break;
@@ -922,21 +944,20 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
922 if (sdata->vif.type != NL80211_IFTYPE_STATION) 944 if (sdata->vif.type != NL80211_IFTYPE_STATION)
923 ret = -EINVAL; 945 ret = -EINVAL;
924 else { 946 else {
925 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; 947 sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
926 /* 948 /*
927 * Privacy invoked by wpa_supplicant, store the 949 * Privacy invoked by wpa_supplicant, store the
928 * value and allow associating to a protected 950 * value and allow associating to a protected
929 * network without having a key up front. 951 * network without having a key up front.
930 */ 952 */
931 if (data->value) 953 if (data->value)
932 sdata->u.sta.flags |= 954 sdata->u.mgd.flags |=
933 IEEE80211_STA_PRIVACY_INVOKED; 955 IEEE80211_STA_PRIVACY_INVOKED;
934 } 956 }
935 break; 957 break;
936 case IW_AUTH_80211_AUTH_ALG: 958 case IW_AUTH_80211_AUTH_ALG:
937 if (sdata->vif.type == NL80211_IFTYPE_STATION || 959 if (sdata->vif.type == NL80211_IFTYPE_STATION)
938 sdata->vif.type == NL80211_IFTYPE_ADHOC) 960 sdata->u.mgd.auth_algs = data->value;
939 sdata->u.sta.auth_algs = data->value;
940 else 961 else
941 ret = -EOPNOTSUPP; 962 ret = -EOPNOTSUPP;
942 break; 963 break;
@@ -945,17 +966,16 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
945 ret = -EOPNOTSUPP; 966 ret = -EOPNOTSUPP;
946 break; 967 break;
947 } 968 }
948 if (sdata->vif.type == NL80211_IFTYPE_STATION || 969 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
949 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
950 switch (data->value) { 970 switch (data->value) {
951 case IW_AUTH_MFP_DISABLED: 971 case IW_AUTH_MFP_DISABLED:
952 sdata->u.sta.mfp = IEEE80211_MFP_DISABLED; 972 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
953 break; 973 break;
954 case IW_AUTH_MFP_OPTIONAL: 974 case IW_AUTH_MFP_OPTIONAL:
955 sdata->u.sta.mfp = IEEE80211_MFP_OPTIONAL; 975 sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
956 break; 976 break;
957 case IW_AUTH_MFP_REQUIRED: 977 case IW_AUTH_MFP_REQUIRED:
958 sdata->u.sta.mfp = IEEE80211_MFP_REQUIRED; 978 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
959 break; 979 break;
960 default: 980 default:
961 ret = -EINVAL; 981 ret = -EINVAL;
@@ -980,9 +1000,9 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
980 1000
981 rcu_read_lock(); 1001 rcu_read_lock();
982 1002
983 if (sdata->vif.type == NL80211_IFTYPE_STATION || 1003 if (sdata->vif.type == NL80211_IFTYPE_STATION)
984 sdata->vif.type == NL80211_IFTYPE_ADHOC) 1004 sta = sta_info_get(local, sdata->u.mgd.bssid);
985 sta = sta_info_get(local, sdata->u.sta.bssid); 1005
986 if (!sta) { 1006 if (!sta) {
987 wstats->discard.fragment = 0; 1007 wstats->discard.fragment = 0;
988 wstats->discard.misc = 0; 1008 wstats->discard.misc = 0;
@@ -1011,9 +1031,8 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
1011 1031
1012 switch (data->flags & IW_AUTH_INDEX) { 1032 switch (data->flags & IW_AUTH_INDEX) {
1013 case IW_AUTH_80211_AUTH_ALG: 1033 case IW_AUTH_80211_AUTH_ALG:
1014 if (sdata->vif.type == NL80211_IFTYPE_STATION || 1034 if (sdata->vif.type == NL80211_IFTYPE_STATION)
1015 sdata->vif.type == NL80211_IFTYPE_ADHOC) 1035 data->value = sdata->u.mgd.auth_algs;
1016 data->value = sdata->u.sta.auth_algs;
1017 else 1036 else
1018 ret = -EOPNOTSUPP; 1037 ret = -EOPNOTSUPP;
1019 break; 1038 break;