diff options
Diffstat (limited to 'net/wireless')
| -rw-r--r-- | net/wireless/core.h | 4 | ||||
| -rw-r--r-- | net/wireless/mlme.c | 16 | ||||
| -rw-r--r-- | net/wireless/nl80211.c | 100 | ||||
| -rw-r--r-- | net/wireless/nl80211.h | 4 | ||||
| -rw-r--r-- | net/wireless/scan.c | 27 | ||||
| -rw-r--r-- | net/wireless/sme.c | 19 | ||||
| -rw-r--r-- | net/wireless/util.c | 16 |
7 files changed, 144 insertions, 42 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index 796a4bdf8b0d..b9ec3061ed72 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -375,7 +375,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
| 375 | struct ieee80211_channel *chan, bool offchan, | 375 | struct ieee80211_channel *chan, bool offchan, |
| 376 | enum nl80211_channel_type channel_type, | 376 | enum nl80211_channel_type channel_type, |
| 377 | bool channel_type_valid, unsigned int wait, | 377 | bool channel_type_valid, unsigned int wait, |
| 378 | const u8 *buf, size_t len, u64 *cookie); | 378 | const u8 *buf, size_t len, bool no_cck, |
| 379 | u64 *cookie); | ||
| 379 | 380 | ||
| 380 | /* SME */ | 381 | /* SME */ |
| 381 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 382 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
| @@ -406,6 +407,7 @@ void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); | |||
| 406 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); | 407 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); |
| 407 | 408 | ||
| 408 | /* internal helpers */ | 409 | /* internal helpers */ |
| 410 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); | ||
| 409 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | 411 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, |
| 410 | struct key_params *params, int key_idx, | 412 | struct key_params *params, int key_idx, |
| 411 | bool pairwise, const u8 *mac_addr); | 413 | bool pairwise, const u8 *mac_addr); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 832f6574e4ed..21fc9702f81c 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -900,7 +900,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
| 900 | struct ieee80211_channel *chan, bool offchan, | 900 | struct ieee80211_channel *chan, bool offchan, |
| 901 | enum nl80211_channel_type channel_type, | 901 | enum nl80211_channel_type channel_type, |
| 902 | bool channel_type_valid, unsigned int wait, | 902 | bool channel_type_valid, unsigned int wait, |
| 903 | const u8 *buf, size_t len, u64 *cookie) | 903 | const u8 *buf, size_t len, bool no_cck, |
| 904 | u64 *cookie) | ||
| 904 | { | 905 | { |
| 905 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 906 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
| 906 | const struct ieee80211_mgmt *mgmt; | 907 | const struct ieee80211_mgmt *mgmt; |
| @@ -991,7 +992,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
| 991 | /* Transmit the Action frame as requested by user space */ | 992 | /* Transmit the Action frame as requested by user space */ |
| 992 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, | 993 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, |
| 993 | channel_type, channel_type_valid, | 994 | channel_type, channel_type_valid, |
| 994 | wait, buf, len, cookie); | 995 | wait, buf, len, no_cck, cookie); |
| 995 | } | 996 | } |
| 996 | 997 | ||
| 997 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, | 998 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, |
| @@ -1095,3 +1096,14 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | |||
| 1095 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); | 1096 | nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); |
| 1096 | } | 1097 | } |
| 1097 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); | 1098 | EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); |
| 1099 | |||
| 1100 | void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | ||
| 1101 | const u8 *bssid, bool preauth, gfp_t gfp) | ||
| 1102 | { | ||
| 1103 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
| 1104 | struct wiphy *wiphy = wdev->wiphy; | ||
| 1105 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 1106 | |||
| 1107 | nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); | ||
| 1108 | } | ||
| 1109 | EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 11089541bb03..b85075761e24 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -191,6 +191,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
| 191 | .len = IEEE80211_MAX_DATA_LEN }, | 191 | .len = IEEE80211_MAX_DATA_LEN }, |
| 192 | [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, | 192 | [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, |
| 193 | [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, | 193 | [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, |
| 194 | [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG }, | ||
| 194 | }; | 195 | }; |
| 195 | 196 | ||
| 196 | /* policy for the key attributes */ | 197 | /* policy for the key attributes */ |
| @@ -1235,6 +1236,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 1235 | goto bad_res; | 1236 | goto bad_res; |
| 1236 | } | 1237 | } |
| 1237 | 1238 | ||
| 1239 | if (!netdev) { | ||
| 1240 | result = -EINVAL; | ||
| 1241 | goto bad_res; | ||
| 1242 | } | ||
| 1243 | |||
| 1238 | nla_for_each_nested(nl_txq_params, | 1244 | nla_for_each_nested(nl_txq_params, |
| 1239 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 1245 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
| 1240 | rem_txq_params) { | 1246 | rem_txq_params) { |
| @@ -1247,6 +1253,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
| 1247 | goto bad_res; | 1253 | goto bad_res; |
| 1248 | 1254 | ||
| 1249 | result = rdev->ops->set_txq_params(&rdev->wiphy, | 1255 | result = rdev->ops->set_txq_params(&rdev->wiphy, |
| 1256 | netdev, | ||
| 1250 | &txq_params); | 1257 | &txq_params); |
| 1251 | if (result) | 1258 | if (result) |
| 1252 | goto bad_res; | 1259 | goto bad_res; |
| @@ -2613,7 +2620,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
| 2613 | 2620 | ||
| 2614 | /* parse WME attributes if sta is WME capable */ | 2621 | /* parse WME attributes if sta is WME capable */ |
| 2615 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && | 2622 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && |
| 2616 | (params.sta_flags_set & NL80211_STA_FLAG_WME) && | 2623 | (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && |
| 2617 | info->attrs[NL80211_ATTR_STA_WME]) { | 2624 | info->attrs[NL80211_ATTR_STA_WME]) { |
| 2618 | struct nlattr *tb[NL80211_STA_WME_MAX + 1]; | 2625 | struct nlattr *tb[NL80211_STA_WME_MAX + 1]; |
| 2619 | struct nlattr *nla; | 2626 | struct nlattr *nla; |
| @@ -3620,6 +3627,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 3620 | } | 3627 | } |
| 3621 | } | 3628 | } |
| 3622 | 3629 | ||
| 3630 | request->no_cck = | ||
| 3631 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | ||
| 3632 | |||
| 3623 | request->dev = dev; | 3633 | request->dev = dev; |
| 3624 | request->wiphy = &rdev->wiphy; | 3634 | request->wiphy = &rdev->wiphy; |
| 3625 | 3635 | ||
| @@ -4126,22 +4136,6 @@ static bool nl80211_valid_wpa_versions(u32 wpa_versions) | |||
| 4126 | NL80211_WPA_VERSION_2)); | 4136 | NL80211_WPA_VERSION_2)); |
| 4127 | } | 4137 | } |
| 4128 | 4138 | ||
| 4129 | static bool nl80211_valid_akm_suite(u32 akm) | ||
| 4130 | { | ||
| 4131 | return akm == WLAN_AKM_SUITE_8021X || | ||
| 4132 | akm == WLAN_AKM_SUITE_PSK; | ||
| 4133 | } | ||
| 4134 | |||
| 4135 | static bool nl80211_valid_cipher_suite(u32 cipher) | ||
| 4136 | { | ||
| 4137 | return cipher == WLAN_CIPHER_SUITE_WEP40 || | ||
| 4138 | cipher == WLAN_CIPHER_SUITE_WEP104 || | ||
| 4139 | cipher == WLAN_CIPHER_SUITE_TKIP || | ||
| 4140 | cipher == WLAN_CIPHER_SUITE_CCMP || | ||
| 4141 | cipher == WLAN_CIPHER_SUITE_AES_CMAC; | ||
| 4142 | } | ||
| 4143 | |||
| 4144 | |||
| 4145 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | 4139 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) |
| 4146 | { | 4140 | { |
| 4147 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4141 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
| @@ -4274,7 +4268,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
| 4274 | memcpy(settings->ciphers_pairwise, data, len); | 4268 | memcpy(settings->ciphers_pairwise, data, len); |
| 4275 | 4269 | ||
| 4276 | for (i = 0; i < settings->n_ciphers_pairwise; i++) | 4270 | for (i = 0; i < settings->n_ciphers_pairwise; i++) |
| 4277 | if (!nl80211_valid_cipher_suite( | 4271 | if (!cfg80211_supported_cipher_suite( |
| 4272 | &rdev->wiphy, | ||
| 4278 | settings->ciphers_pairwise[i])) | 4273 | settings->ciphers_pairwise[i])) |
| 4279 | return -EINVAL; | 4274 | return -EINVAL; |
| 4280 | } | 4275 | } |
| @@ -4282,7 +4277,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
| 4282 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { | 4277 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { |
| 4283 | settings->cipher_group = | 4278 | settings->cipher_group = |
| 4284 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); | 4279 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); |
| 4285 | if (!nl80211_valid_cipher_suite(settings->cipher_group)) | 4280 | if (!cfg80211_supported_cipher_suite(&rdev->wiphy, |
| 4281 | settings->cipher_group)) | ||
| 4286 | return -EINVAL; | 4282 | return -EINVAL; |
| 4287 | } | 4283 | } |
| 4288 | 4284 | ||
| @@ -4295,7 +4291,7 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
| 4295 | 4291 | ||
| 4296 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { | 4292 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { |
| 4297 | void *data; | 4293 | void *data; |
| 4298 | int len, i; | 4294 | int len; |
| 4299 | 4295 | ||
| 4300 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); | 4296 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); |
| 4301 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); | 4297 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); |
| @@ -4304,11 +4300,10 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | |||
| 4304 | if (len % sizeof(u32)) | 4300 | if (len % sizeof(u32)) |
| 4305 | return -EINVAL; | 4301 | return -EINVAL; |
| 4306 | 4302 | ||
| 4307 | memcpy(settings->akm_suites, data, len); | 4303 | if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES) |
| 4304 | return -EINVAL; | ||
| 4308 | 4305 | ||
| 4309 | for (i = 0; i < settings->n_ciphers_pairwise; i++) | 4306 | memcpy(settings->akm_suites, data, len); |
| 4310 | if (!nl80211_valid_akm_suite(settings->akm_suites[i])) | ||
| 4311 | return -EINVAL; | ||
| 4312 | } | 4307 | } |
| 4313 | 4308 | ||
| 4314 | return 0; | 4309 | return 0; |
| @@ -4527,8 +4522,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
| 4527 | 4522 | ||
| 4528 | wiphy = &rdev->wiphy; | 4523 | wiphy = &rdev->wiphy; |
| 4529 | 4524 | ||
| 4530 | if (info->attrs[NL80211_ATTR_MAC]) | 4525 | if (info->attrs[NL80211_ATTR_MAC]) { |
| 4531 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 4526 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
| 4527 | |||
| 4528 | if (!is_valid_ether_addr(ibss.bssid)) | ||
| 4529 | return -EINVAL; | ||
| 4530 | } | ||
| 4532 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 4531 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
| 4533 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 4532 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
| 4534 | 4533 | ||
| @@ -5185,6 +5184,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
| 5185 | struct sk_buff *msg; | 5184 | struct sk_buff *msg; |
| 5186 | unsigned int wait = 0; | 5185 | unsigned int wait = 0; |
| 5187 | bool offchan; | 5186 | bool offchan; |
| 5187 | bool no_cck; | ||
| 5188 | 5188 | ||
| 5189 | if (!info->attrs[NL80211_ATTR_FRAME] || | 5189 | if (!info->attrs[NL80211_ATTR_FRAME] || |
| 5190 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5190 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
| @@ -5221,6 +5221,8 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
| 5221 | 5221 | ||
| 5222 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; | 5222 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; |
| 5223 | 5223 | ||
| 5224 | no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | ||
| 5225 | |||
| 5224 | freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); | 5226 | freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); |
| 5225 | chan = rdev_freq_to_chan(rdev, freq, channel_type); | 5227 | chan = rdev_freq_to_chan(rdev, freq, channel_type); |
| 5226 | if (chan == NULL) | 5228 | if (chan == NULL) |
| @@ -5241,7 +5243,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
| 5241 | channel_type_valid, wait, | 5243 | channel_type_valid, wait, |
| 5242 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 5244 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
| 5243 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 5245 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
| 5244 | &cookie); | 5246 | no_cck, &cookie); |
| 5245 | if (err) | 5247 | if (err) |
| 5246 | goto free_msg; | 5248 | goto free_msg; |
| 5247 | 5249 | ||
| @@ -7266,6 +7268,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
| 7266 | nlmsg_free(msg); | 7268 | nlmsg_free(msg); |
| 7267 | } | 7269 | } |
| 7268 | 7270 | ||
| 7271 | void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | ||
| 7272 | struct net_device *netdev, int index, | ||
| 7273 | const u8 *bssid, bool preauth, gfp_t gfp) | ||
| 7274 | { | ||
| 7275 | struct sk_buff *msg; | ||
| 7276 | struct nlattr *attr; | ||
| 7277 | void *hdr; | ||
| 7278 | |||
| 7279 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
| 7280 | if (!msg) | ||
| 7281 | return; | ||
| 7282 | |||
| 7283 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); | ||
| 7284 | if (!hdr) { | ||
| 7285 | nlmsg_free(msg); | ||
| 7286 | return; | ||
| 7287 | } | ||
| 7288 | |||
| 7289 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | ||
| 7290 | NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | ||
| 7291 | |||
| 7292 | attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); | ||
| 7293 | if (!attr) | ||
| 7294 | goto nla_put_failure; | ||
| 7295 | |||
| 7296 | NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); | ||
| 7297 | NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); | ||
| 7298 | if (preauth) | ||
| 7299 | NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); | ||
| 7300 | |||
| 7301 | nla_nest_end(msg, attr); | ||
| 7302 | |||
| 7303 | if (genlmsg_end(msg, hdr) < 0) { | ||
| 7304 | nlmsg_free(msg); | ||
| 7305 | return; | ||
| 7306 | } | ||
| 7307 | |||
| 7308 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
| 7309 | nl80211_mlme_mcgrp.id, gfp); | ||
| 7310 | return; | ||
| 7311 | |||
| 7312 | nla_put_failure: | ||
| 7313 | genlmsg_cancel(msg, hdr); | ||
| 7314 | nlmsg_free(msg); | ||
| 7315 | } | ||
| 7316 | |||
| 7269 | void | 7317 | void |
| 7270 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 7318 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, |
| 7271 | struct net_device *netdev, const u8 *peer, | 7319 | struct net_device *netdev, const u8 *peer, |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 5d69c56400ae..f24a1fbeaf19 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
| @@ -113,4 +113,8 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | |||
| 113 | struct net_device *netdev, const u8 *bssid, | 113 | struct net_device *netdev, const u8 *bssid, |
| 114 | const u8 *replay_ctr, gfp_t gfp); | 114 | const u8 *replay_ctr, gfp_t gfp); |
| 115 | 115 | ||
| 116 | void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | ||
| 117 | struct net_device *netdev, int index, | ||
| 118 | const u8 *bssid, bool preauth, gfp_t gfp); | ||
| 119 | |||
| 116 | #endif /* __NET_WIRELESS_NL80211_H */ | 120 | #endif /* __NET_WIRELESS_NL80211_H */ |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b0f003966953..0fb142410404 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -228,6 +228,33 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) | |||
| 228 | } | 228 | } |
| 229 | EXPORT_SYMBOL(cfg80211_find_ie); | 229 | EXPORT_SYMBOL(cfg80211_find_ie); |
| 230 | 230 | ||
| 231 | const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | ||
| 232 | const u8 *ies, int len) | ||
| 233 | { | ||
| 234 | struct ieee80211_vendor_ie *ie; | ||
| 235 | const u8 *pos = ies, *end = ies + len; | ||
| 236 | int ie_oui; | ||
| 237 | |||
| 238 | while (pos < end) { | ||
| 239 | pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, | ||
| 240 | end - pos); | ||
| 241 | if (!pos) | ||
| 242 | return NULL; | ||
| 243 | |||
| 244 | if (end - pos < sizeof(*ie)) | ||
| 245 | return NULL; | ||
| 246 | |||
| 247 | ie = (struct ieee80211_vendor_ie *)pos; | ||
| 248 | ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; | ||
| 249 | if (ie_oui == oui && ie->oui_type == oui_type) | ||
| 250 | return pos; | ||
| 251 | |||
| 252 | pos += 2 + ie->len; | ||
| 253 | } | ||
| 254 | return NULL; | ||
| 255 | } | ||
| 256 | EXPORT_SYMBOL(cfg80211_find_vendor_ie); | ||
| 257 | |||
| 231 | static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) | 258 | static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) |
| 232 | { | 259 | { |
| 233 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); | 260 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index dec0fa28372e..6e86d5acf145 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
| @@ -110,17 +110,22 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
| 110 | else { | 110 | else { |
| 111 | int i = 0, j; | 111 | int i = 0, j; |
| 112 | enum ieee80211_band band; | 112 | enum ieee80211_band band; |
| 113 | struct ieee80211_supported_band *bands; | ||
| 114 | struct ieee80211_channel *channel; | ||
| 113 | 115 | ||
| 114 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 116 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
| 115 | if (!wdev->wiphy->bands[band]) | 117 | bands = wdev->wiphy->bands[band]; |
| 118 | if (!bands) | ||
| 116 | continue; | 119 | continue; |
| 117 | for (j = 0; j < wdev->wiphy->bands[band]->n_channels; | 120 | for (j = 0; j < bands->n_channels; j++) { |
| 118 | i++, j++) | 121 | channel = &bands->channels[j]; |
| 119 | request->channels[i] = | 122 | if (channel->flags & IEEE80211_CHAN_DISABLED) |
| 120 | &wdev->wiphy->bands[band]->channels[j]; | 123 | continue; |
| 121 | request->rates[band] = | 124 | request->channels[i++] = channel; |
| 122 | (1 << wdev->wiphy->bands[band]->n_bitrates) - 1; | 125 | } |
| 126 | request->rates[band] = (1 << bands->n_bitrates) - 1; | ||
| 123 | } | 127 | } |
| 128 | n_channels = i; | ||
| 124 | } | 129 | } |
| 125 | request->n_channels = n_channels; | 130 | request->n_channels = n_channels; |
| 126 | request->ssids = (void *)&request->channels[n_channels]; | 131 | request->ssids = (void *)&request->channels[n_channels]; |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 39dbf4ad7ca1..6304ed63588a 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -151,12 +151,19 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy) | |||
| 151 | set_mandatory_flags_band(wiphy->bands[band], band); | 151 | set_mandatory_flags_band(wiphy->bands[band], band); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher) | ||
| 155 | { | ||
| 156 | int i; | ||
| 157 | for (i = 0; i < wiphy->n_cipher_suites; i++) | ||
| 158 | if (cipher == wiphy->cipher_suites[i]) | ||
| 159 | return true; | ||
| 160 | return false; | ||
| 161 | } | ||
| 162 | |||
| 154 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | 163 | int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, |
| 155 | struct key_params *params, int key_idx, | 164 | struct key_params *params, int key_idx, |
| 156 | bool pairwise, const u8 *mac_addr) | 165 | bool pairwise, const u8 *mac_addr) |
| 157 | { | 166 | { |
| 158 | int i; | ||
| 159 | |||
| 160 | if (key_idx > 5) | 167 | if (key_idx > 5) |
| 161 | return -EINVAL; | 168 | return -EINVAL; |
| 162 | 169 | ||
| @@ -226,10 +233,7 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, | |||
| 226 | } | 233 | } |
| 227 | } | 234 | } |
| 228 | 235 | ||
| 229 | for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) | 236 | if (!cfg80211_supported_cipher_suite(&rdev->wiphy, params->cipher)) |
| 230 | if (params->cipher == rdev->wiphy.cipher_suites[i]) | ||
| 231 | break; | ||
| 232 | if (i == rdev->wiphy.n_cipher_suites) | ||
| 233 | return -EINVAL; | 237 | return -EINVAL; |
| 234 | 238 | ||
| 235 | return 0; | 239 | return 0; |
