diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/wireless/core.h | 10 | ||||
-rw-r--r-- | net/wireless/mlme.c | 37 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 44 | ||||
-rw-r--r-- | net/wireless/sme.c | 7 |
4 files changed, 91 insertions, 7 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index 1c7d4df5418c..fb08c28fc90a 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -341,13 +341,17 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
341 | const u8 *bssid, const u8 *prev_bssid, | 341 | const u8 *bssid, const u8 *prev_bssid, |
342 | const u8 *ssid, int ssid_len, | 342 | const u8 *ssid, int ssid_len, |
343 | const u8 *ie, int ie_len, bool use_mfp, | 343 | const u8 *ie, int ie_len, bool use_mfp, |
344 | struct cfg80211_crypto_settings *crypt); | 344 | struct cfg80211_crypto_settings *crypt, |
345 | u32 assoc_flags, struct ieee80211_ht_cap *ht_capa, | ||
346 | struct ieee80211_ht_cap *ht_capa_mask); | ||
345 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 347 | int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
346 | struct net_device *dev, struct ieee80211_channel *chan, | 348 | struct net_device *dev, struct ieee80211_channel *chan, |
347 | const u8 *bssid, const u8 *prev_bssid, | 349 | const u8 *bssid, const u8 *prev_bssid, |
348 | const u8 *ssid, int ssid_len, | 350 | const u8 *ssid, int ssid_len, |
349 | const u8 *ie, int ie_len, bool use_mfp, | 351 | const u8 *ie, int ie_len, bool use_mfp, |
350 | struct cfg80211_crypto_settings *crypt); | 352 | struct cfg80211_crypto_settings *crypt, |
353 | u32 assoc_flags, struct ieee80211_ht_cap *ht_capa, | ||
354 | struct ieee80211_ht_cap *ht_capa_mask); | ||
351 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 355 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
352 | struct net_device *dev, const u8 *bssid, | 356 | struct net_device *dev, const u8 *bssid, |
353 | const u8 *ie, int ie_len, u16 reason, | 357 | const u8 *ie, int ie_len, u16 reason, |
@@ -379,6 +383,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
379 | bool channel_type_valid, unsigned int wait, | 383 | bool channel_type_valid, unsigned int wait, |
380 | const u8 *buf, size_t len, bool no_cck, | 384 | const u8 *buf, size_t len, bool no_cck, |
381 | bool dont_wait_for_ack, u64 *cookie); | 385 | bool dont_wait_for_ack, u64 *cookie); |
386 | void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, | ||
387 | const struct ieee80211_ht_cap *ht_capa_mask); | ||
382 | 388 | ||
383 | /* SME */ | 389 | /* SME */ |
384 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 390 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 6c1bafd508c8..438dfc105b4a 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -501,13 +501,32 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
501 | return err; | 501 | return err; |
502 | } | 502 | } |
503 | 503 | ||
504 | /* Do a logical ht_capa &= ht_capa_mask. */ | ||
505 | void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, | ||
506 | const struct ieee80211_ht_cap *ht_capa_mask) | ||
507 | { | ||
508 | int i; | ||
509 | u8 *p1, *p2; | ||
510 | if (!ht_capa_mask) { | ||
511 | memset(ht_capa, 0, sizeof(*ht_capa)); | ||
512 | return; | ||
513 | } | ||
514 | |||
515 | p1 = (u8*)(ht_capa); | ||
516 | p2 = (u8*)(ht_capa_mask); | ||
517 | for (i = 0; i<sizeof(*ht_capa); i++) | ||
518 | p1[i] &= p2[i]; | ||
519 | } | ||
520 | |||
504 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 521 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
505 | struct net_device *dev, | 522 | struct net_device *dev, |
506 | struct ieee80211_channel *chan, | 523 | struct ieee80211_channel *chan, |
507 | const u8 *bssid, const u8 *prev_bssid, | 524 | const u8 *bssid, const u8 *prev_bssid, |
508 | const u8 *ssid, int ssid_len, | 525 | const u8 *ssid, int ssid_len, |
509 | const u8 *ie, int ie_len, bool use_mfp, | 526 | const u8 *ie, int ie_len, bool use_mfp, |
510 | struct cfg80211_crypto_settings *crypt) | 527 | struct cfg80211_crypto_settings *crypt, |
528 | u32 assoc_flags, struct ieee80211_ht_cap *ht_capa, | ||
529 | struct ieee80211_ht_cap *ht_capa_mask) | ||
511 | { | 530 | { |
512 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 531 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
513 | struct cfg80211_assoc_request req; | 532 | struct cfg80211_assoc_request req; |
@@ -537,6 +556,15 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
537 | memcpy(&req.crypto, crypt, sizeof(req.crypto)); | 556 | memcpy(&req.crypto, crypt, sizeof(req.crypto)); |
538 | req.use_mfp = use_mfp; | 557 | req.use_mfp = use_mfp; |
539 | req.prev_bssid = prev_bssid; | 558 | req.prev_bssid = prev_bssid; |
559 | req.flags = assoc_flags; | ||
560 | if (ht_capa) | ||
561 | memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa)); | ||
562 | if (ht_capa_mask) | ||
563 | memcpy(&req.ht_capa_mask, ht_capa_mask, | ||
564 | sizeof(req.ht_capa_mask)); | ||
565 | cfg80211_oper_and_ht_capa(&req.ht_capa_mask, | ||
566 | rdev->wiphy.ht_capa_mod_mask); | ||
567 | |||
540 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, | 568 | req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, |
541 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 569 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
542 | if (!req.bss) { | 570 | if (!req.bss) { |
@@ -574,14 +602,17 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
574 | const u8 *bssid, const u8 *prev_bssid, | 602 | const u8 *bssid, const u8 *prev_bssid, |
575 | const u8 *ssid, int ssid_len, | 603 | const u8 *ssid, int ssid_len, |
576 | const u8 *ie, int ie_len, bool use_mfp, | 604 | const u8 *ie, int ie_len, bool use_mfp, |
577 | struct cfg80211_crypto_settings *crypt) | 605 | struct cfg80211_crypto_settings *crypt, |
606 | u32 assoc_flags, struct ieee80211_ht_cap *ht_capa, | ||
607 | struct ieee80211_ht_cap *ht_capa_mask) | ||
578 | { | 608 | { |
579 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 609 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
580 | int err; | 610 | int err; |
581 | 611 | ||
582 | wdev_lock(wdev); | 612 | wdev_lock(wdev); |
583 | err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, | 613 | err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, |
584 | ssid, ssid_len, ie, ie_len, use_mfp, crypt); | 614 | ssid, ssid_len, ie, ie_len, use_mfp, crypt, |
615 | assoc_flags, ht_capa, ht_capa_mask); | ||
585 | wdev_unlock(wdev); | 616 | wdev_unlock(wdev); |
586 | 617 | ||
587 | return err; | 618 | return err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 889f06483862..a1cabde7cb5f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -200,6 +200,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
200 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, | 200 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, |
201 | .len = IEEE80211_MAX_DATA_LEN }, | 201 | .len = IEEE80211_MAX_DATA_LEN }, |
202 | [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 }, | 202 | [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 }, |
203 | [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG }, | ||
204 | [NL80211_ATTR_HT_CAPABILITY_MASK] = { | ||
205 | .len = NL80211_HT_CAPABILITY_LEN | ||
206 | }, | ||
203 | }; | 207 | }; |
204 | 208 | ||
205 | /* policy for the key attributes */ | 209 | /* policy for the key attributes */ |
@@ -1032,6 +1036,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
1032 | 1036 | ||
1033 | NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); | 1037 | NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features); |
1034 | 1038 | ||
1039 | if (dev->wiphy.ht_capa_mod_mask) | ||
1040 | NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, | ||
1041 | sizeof(*dev->wiphy.ht_capa_mod_mask), | ||
1042 | dev->wiphy.ht_capa_mod_mask); | ||
1043 | |||
1035 | return genlmsg_end(msg, hdr); | 1044 | return genlmsg_end(msg, hdr); |
1036 | 1045 | ||
1037 | nla_put_failure: | 1046 | nla_put_failure: |
@@ -4413,6 +4422,9 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
4413 | const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; | 4422 | const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; |
4414 | int err, ssid_len, ie_len = 0; | 4423 | int err, ssid_len, ie_len = 0; |
4415 | bool use_mfp = false; | 4424 | bool use_mfp = false; |
4425 | u32 flags = 0; | ||
4426 | struct ieee80211_ht_cap *ht_capa = NULL; | ||
4427 | struct ieee80211_ht_cap *ht_capa_mask = NULL; | ||
4416 | 4428 | ||
4417 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 4429 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
4418 | return -EINVAL; | 4430 | return -EINVAL; |
@@ -4456,11 +4468,25 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
4456 | if (info->attrs[NL80211_ATTR_PREV_BSSID]) | 4468 | if (info->attrs[NL80211_ATTR_PREV_BSSID]) |
4457 | prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); | 4469 | prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); |
4458 | 4470 | ||
4471 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) | ||
4472 | flags |= ASSOC_REQ_DISABLE_HT; | ||
4473 | |||
4474 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | ||
4475 | ht_capa_mask = | ||
4476 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]); | ||
4477 | |||
4478 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | ||
4479 | if (!ht_capa_mask) | ||
4480 | return -EINVAL; | ||
4481 | ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | ||
4482 | } | ||
4483 | |||
4459 | err = nl80211_crypto_settings(rdev, info, &crypto, 1); | 4484 | err = nl80211_crypto_settings(rdev, info, &crypto, 1); |
4460 | if (!err) | 4485 | if (!err) |
4461 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, | 4486 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, |
4462 | ssid, ssid_len, ie, ie_len, use_mfp, | 4487 | ssid, ssid_len, ie, ie_len, use_mfp, |
4463 | &crypto); | 4488 | &crypto, flags, ht_capa, |
4489 | ht_capa_mask); | ||
4464 | 4490 | ||
4465 | return err; | 4491 | return err; |
4466 | } | 4492 | } |
@@ -4950,6 +4976,22 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
4950 | return PTR_ERR(connkeys); | 4976 | return PTR_ERR(connkeys); |
4951 | } | 4977 | } |
4952 | 4978 | ||
4979 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) | ||
4980 | connect.flags |= ASSOC_REQ_DISABLE_HT; | ||
4981 | |||
4982 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | ||
4983 | memcpy(&connect.ht_capa_mask, | ||
4984 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]), | ||
4985 | sizeof(connect.ht_capa_mask)); | ||
4986 | |||
4987 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | ||
4988 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | ||
4989 | return -EINVAL; | ||
4990 | memcpy(&connect.ht_capa, | ||
4991 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]), | ||
4992 | sizeof(connect.ht_capa)); | ||
4993 | } | ||
4994 | |||
4953 | err = cfg80211_connect(rdev, dev, &connect, connkeys); | 4995 | err = cfg80211_connect(rdev, dev, &connect, connkeys); |
4954 | if (err) | 4996 | if (err) |
4955 | kfree(connkeys); | 4997 | kfree(connkeys); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 6e86d5acf145..ed9d0e6f4a06 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -189,7 +189,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
189 | prev_bssid, | 189 | prev_bssid, |
190 | params->ssid, params->ssid_len, | 190 | params->ssid, params->ssid_len, |
191 | params->ie, params->ie_len, | 191 | params->ie, params->ie_len, |
192 | false, ¶ms->crypto); | 192 | false, ¶ms->crypto, |
193 | params->flags, ¶ms->ht_capa, | ||
194 | ¶ms->ht_capa_mask); | ||
193 | if (err) | 195 | if (err) |
194 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 196 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
195 | NULL, 0, | 197 | NULL, 0, |
@@ -773,6 +775,9 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
773 | wdev->connect_keys = NULL; | 775 | wdev->connect_keys = NULL; |
774 | } | 776 | } |
775 | 777 | ||
778 | cfg80211_oper_and_ht_capa(&connect->ht_capa_mask, | ||
779 | rdev->wiphy.ht_capa_mod_mask); | ||
780 | |||
776 | if (connkeys && connkeys->def >= 0) { | 781 | if (connkeys && connkeys->def >= 0) { |
777 | int idx; | 782 | int idx; |
778 | u32 cipher; | 783 | u32 cipher; |