diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-01 15:26:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:01:51 -0400 |
commit | f21293549f60f88c74fcb9944737f11048896dc4 (patch) | |
tree | d4a00663f87816c0c742e74d7b2c9bad31a18816 /net/mac80211/wext.c | |
parent | 6829c878ecd24ff0ae41b4668c7e9d0f11b66942 (diff) |
cfg80211: managed mode wext compatibility
This adds code to make it possible to use the cfg80211
connect() API with wireless extensions, and because the
previous patch added emulation of that API with auth()
and assoc(), by extension also supports wext on that.
At the same time, removes code from mac80211 for wext,
but doesn't yet clean up mac80211's mlme code more.
Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
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.c | 215 |
1 files changed, 20 insertions, 195 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 1da81f456744..d4e61dc903e8 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -27,29 +27,6 @@ | |||
27 | #include "aes_ccm.h" | 27 | #include "aes_ccm.h" |
28 | 28 | ||
29 | 29 | ||
30 | static int ieee80211_ioctl_siwgenie(struct net_device *dev, | ||
31 | struct iw_request_info *info, | ||
32 | struct iw_point *data, char *extra) | ||
33 | { | ||
34 | struct ieee80211_sub_if_data *sdata; | ||
35 | |||
36 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
37 | |||
38 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
39 | int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length); | ||
40 | if (ret && ret != -EALREADY) | ||
41 | return ret; | ||
42 | sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; | ||
43 | sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; | ||
44 | sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; | ||
45 | if (ret != -EALREADY) | ||
46 | ieee80211_sta_req_auth(sdata); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | return -EOPNOTSUPP; | ||
51 | } | ||
52 | |||
53 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, | 30 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, |
54 | struct iw_request_info *info, | 31 | struct iw_request_info *info, |
55 | struct iw_freq *freq, char *extra) | 32 | struct iw_freq *freq, char *extra) |
@@ -61,16 +38,13 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
61 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 38 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
62 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); | 39 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); |
63 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | 40 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) |
64 | sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; | 41 | return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra); |
65 | 42 | ||
66 | /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ | 43 | /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ |
67 | if (freq->e == 0) { | 44 | if (freq->e == 0) { |
68 | if (freq->m < 0) { | 45 | if (freq->m < 0) |
69 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 46 | return -EINVAL; |
70 | sdata->u.mgd.flags |= | 47 | else |
71 | IEEE80211_STA_AUTO_CHANNEL_SEL; | ||
72 | return 0; | ||
73 | } else | ||
74 | chan = ieee80211_get_channel(local->hw.wiphy, | 48 | chan = ieee80211_get_channel(local->hw.wiphy, |
75 | ieee80211_channel_to_frequency(freq->m)); | 49 | ieee80211_channel_to_frequency(freq->m)); |
76 | } else { | 50 | } else { |
@@ -95,9 +69,6 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
95 | if (local->oper_channel == chan) | 69 | if (local->oper_channel == chan) |
96 | return 0; | 70 | return 0; |
97 | 71 | ||
98 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
99 | ieee80211_sta_req_auth(sdata); | ||
100 | |||
101 | local->oper_channel = chan; | 72 | local->oper_channel = chan; |
102 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 73 | local->oper_channel_type = NL80211_CHAN_NO_HT; |
103 | ieee80211_hw_config(local, 0); | 74 | ieee80211_hw_config(local, 0); |
@@ -115,6 +86,8 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev, | |||
115 | 86 | ||
116 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 87 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
117 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); | 88 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); |
89 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
90 | return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); | ||
118 | 91 | ||
119 | freq->m = local->oper_channel->center_freq; | 92 | freq->m = local->oper_channel->center_freq; |
120 | freq->e = 6; | 93 | freq->e = 6; |
@@ -128,31 +101,11 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, | |||
128 | struct iw_point *data, char *ssid) | 101 | struct iw_point *data, char *ssid) |
129 | { | 102 | { |
130 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 103 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
131 | size_t len = data->length; | ||
132 | int ret; | ||
133 | 104 | ||
134 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 105 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
135 | return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); | 106 | return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); |
136 | 107 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | |
137 | /* iwconfig uses nul termination in SSID.. */ | 108 | return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); |
138 | if (len > 0 && ssid[len - 1] == '\0') | ||
139 | len--; | ||
140 | |||
141 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
142 | if (data->flags) | ||
143 | sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; | ||
144 | else | ||
145 | sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL; | ||
146 | |||
147 | ret = ieee80211_sta_set_ssid(sdata, ssid, len); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; | ||
152 | sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; | ||
153 | ieee80211_sta_req_auth(sdata); | ||
154 | return 0; | ||
155 | } | ||
156 | 109 | ||
157 | return -EOPNOTSUPP; | 110 | return -EOPNOTSUPP; |
158 | } | 111 | } |
@@ -162,23 +115,14 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev, | |||
162 | struct iw_request_info *info, | 115 | struct iw_request_info *info, |
163 | struct iw_point *data, char *ssid) | 116 | struct iw_point *data, char *ssid) |
164 | { | 117 | { |
165 | size_t len; | ||
166 | struct ieee80211_sub_if_data *sdata; | 118 | struct ieee80211_sub_if_data *sdata; |
167 | 119 | ||
168 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 120 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
169 | 121 | ||
170 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 122 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
171 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); | 123 | return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); |
172 | 124 | else if (sdata->vif.type == NL80211_IFTYPE_STATION) | |
173 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 125 | return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); |
174 | int res = ieee80211_sta_get_ssid(sdata, ssid, &len); | ||
175 | if (res == 0) { | ||
176 | data->length = len; | ||
177 | data->flags = 1; | ||
178 | } else | ||
179 | data->flags = 0; | ||
180 | return res; | ||
181 | } | ||
182 | 126 | ||
183 | return -EOPNOTSUPP; | 127 | return -EOPNOTSUPP; |
184 | } | 128 | } |
@@ -193,24 +137,10 @@ static int ieee80211_ioctl_siwap(struct net_device *dev, | |||
193 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 137 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
194 | return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); | 138 | return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); |
195 | 139 | ||
196 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 140 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
197 | int ret; | 141 | return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); |
198 | 142 | ||
199 | if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) | 143 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { |
200 | sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL | | ||
201 | IEEE80211_STA_AUTO_CHANNEL_SEL; | ||
202 | else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data)) | ||
203 | sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL; | ||
204 | else | ||
205 | sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; | ||
206 | ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; | ||
210 | sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT; | ||
211 | ieee80211_sta_req_auth(sdata); | ||
212 | return 0; | ||
213 | } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { | ||
214 | /* | 144 | /* |
215 | * If it is necessary to update the WDS peer address | 145 | * If it is necessary to update the WDS peer address |
216 | * while the interface is running, then we need to do | 146 | * while the interface is running, then we need to do |
@@ -240,14 +170,10 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, | |||
240 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 170 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
241 | return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); | 171 | return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); |
242 | 172 | ||
243 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 173 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
244 | if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) { | 174 | return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); |
245 | ap_addr->sa_family = ARPHRD_ETHER; | 175 | |
246 | memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN); | 176 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { |
247 | } else | ||
248 | memset(&ap_addr->sa_data, 0, ETH_ALEN); | ||
249 | return 0; | ||
250 | } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { | ||
251 | ap_addr->sa_family = ARPHRD_ETHER; | 177 | ap_addr->sa_family = ARPHRD_ETHER; |
252 | memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); | 178 | memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); |
253 | return 0; | 179 | return 0; |
@@ -395,85 +321,6 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev, | |||
395 | return 0; | 321 | return 0; |
396 | } | 322 | } |
397 | 323 | ||
398 | static int ieee80211_ioctl_siwauth(struct net_device *dev, | ||
399 | struct iw_request_info *info, | ||
400 | struct iw_param *data, char *extra) | ||
401 | { | ||
402 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
403 | int ret = 0; | ||
404 | |||
405 | switch (data->flags & IW_AUTH_INDEX) { | ||
406 | case IW_AUTH_WPA_VERSION: | ||
407 | case IW_AUTH_CIPHER_GROUP: | ||
408 | case IW_AUTH_WPA_ENABLED: | ||
409 | case IW_AUTH_RX_UNENCRYPTED_EAPOL: | ||
410 | case IW_AUTH_KEY_MGMT: | ||
411 | case IW_AUTH_CIPHER_GROUP_MGMT: | ||
412 | break; | ||
413 | case IW_AUTH_CIPHER_PAIRWISE: | ||
414 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
415 | if (data->value & (IW_AUTH_CIPHER_WEP40 | | ||
416 | IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP)) | ||
417 | sdata->u.mgd.flags |= | ||
418 | IEEE80211_STA_TKIP_WEP_USED; | ||
419 | else | ||
420 | sdata->u.mgd.flags &= | ||
421 | ~IEEE80211_STA_TKIP_WEP_USED; | ||
422 | } | ||
423 | break; | ||
424 | case IW_AUTH_DROP_UNENCRYPTED: | ||
425 | sdata->drop_unencrypted = !!data->value; | ||
426 | break; | ||
427 | case IW_AUTH_PRIVACY_INVOKED: | ||
428 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
429 | ret = -EINVAL; | ||
430 | else { | ||
431 | sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | ||
432 | /* | ||
433 | * Privacy invoked by wpa_supplicant, store the | ||
434 | * value and allow associating to a protected | ||
435 | * network without having a key up front. | ||
436 | */ | ||
437 | if (data->value) | ||
438 | sdata->u.mgd.flags |= | ||
439 | IEEE80211_STA_PRIVACY_INVOKED; | ||
440 | } | ||
441 | break; | ||
442 | case IW_AUTH_80211_AUTH_ALG: | ||
443 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
444 | sdata->u.mgd.auth_algs = data->value; | ||
445 | else | ||
446 | ret = -EOPNOTSUPP; | ||
447 | break; | ||
448 | case IW_AUTH_MFP: | ||
449 | if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) { | ||
450 | ret = -EOPNOTSUPP; | ||
451 | break; | ||
452 | } | ||
453 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
454 | switch (data->value) { | ||
455 | case IW_AUTH_MFP_DISABLED: | ||
456 | sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED; | ||
457 | break; | ||
458 | case IW_AUTH_MFP_OPTIONAL: | ||
459 | sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL; | ||
460 | break; | ||
461 | case IW_AUTH_MFP_REQUIRED: | ||
462 | sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED; | ||
463 | break; | ||
464 | default: | ||
465 | ret = -EINVAL; | ||
466 | } | ||
467 | } else | ||
468 | ret = -EOPNOTSUPP; | ||
469 | break; | ||
470 | default: | ||
471 | ret = -EOPNOTSUPP; | ||
472 | break; | ||
473 | } | ||
474 | return ret; | ||
475 | } | ||
476 | |||
477 | /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ | 324 | /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ |
478 | static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) | 325 | static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) |
479 | { | 326 | { |
@@ -541,28 +388,6 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev | |||
541 | return wstats; | 388 | return wstats; |
542 | } | 389 | } |
543 | 390 | ||
544 | static int ieee80211_ioctl_giwauth(struct net_device *dev, | ||
545 | struct iw_request_info *info, | ||
546 | struct iw_param *data, char *extra) | ||
547 | { | ||
548 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
549 | int ret = 0; | ||
550 | |||
551 | switch (data->flags & IW_AUTH_INDEX) { | ||
552 | case IW_AUTH_80211_AUTH_ALG: | ||
553 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
554 | data->value = sdata->u.mgd.auth_algs; | ||
555 | else | ||
556 | ret = -EOPNOTSUPP; | ||
557 | break; | ||
558 | default: | ||
559 | ret = -EOPNOTSUPP; | ||
560 | break; | ||
561 | } | ||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | |||
566 | /* Structures to export the Wireless Handlers */ | 391 | /* Structures to export the Wireless Handlers */ |
567 | 392 | ||
568 | static const iw_handler ieee80211_handler[] = | 393 | static const iw_handler ieee80211_handler[] = |
@@ -615,10 +440,10 @@ static const iw_handler ieee80211_handler[] = | |||
615 | (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ | 440 | (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ |
616 | (iw_handler) NULL, /* -- hole -- */ | 441 | (iw_handler) NULL, /* -- hole -- */ |
617 | (iw_handler) NULL, /* -- hole -- */ | 442 | (iw_handler) NULL, /* -- hole -- */ |
618 | (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ | 443 | (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ |
619 | (iw_handler) NULL, /* SIOCGIWGENIE */ | 444 | (iw_handler) NULL, /* SIOCGIWGENIE */ |
620 | (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */ | 445 | (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */ |
621 | (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */ | 446 | (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */ |
622 | (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ | 447 | (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ |
623 | (iw_handler) NULL, /* SIOCGIWENCODEEXT */ | 448 | (iw_handler) NULL, /* SIOCGIWENCODEEXT */ |
624 | (iw_handler) NULL, /* SIOCSIWPMKSA */ | 449 | (iw_handler) NULL, /* SIOCSIWPMKSA */ |