aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c358
1 files changed, 324 insertions, 34 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cea338150d0..fb18bb4dea7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -83,8 +83,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
83 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 83 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
84 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, 84 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
85 85
86 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, 86 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
87 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, 87 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
88 88
89 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, 89 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
90 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 90 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
@@ -126,8 +126,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, 126 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, 127 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
128 128
129 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, 129 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
130 .len = NL80211_HT_CAPABILITY_LEN },
131 130
132 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, 131 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
133 [NL80211_ATTR_IE] = { .type = NLA_BINARY, 132 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
@@ -176,6 +175,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
176 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, 175 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, 176 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 177 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
178 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
179 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
179}; 180};
180 181
181/* policy for the key attributes */ 182/* policy for the key attributes */
@@ -204,6 +205,18 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
204 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, 205 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
205 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, 206 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
206 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, 207 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
208 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
209 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
210 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
211 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
212};
213
214/* policy for GTK rekey offload attributes */
215static const struct nla_policy
216nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
217 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
218 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
219 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
207}; 220};
208 221
209/* ifidx get helper */ 222/* ifidx get helper */
@@ -683,8 +696,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
683 dev->wiphy.coverage_class); 696 dev->wiphy.coverage_class);
684 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 697 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
685 dev->wiphy.max_scan_ssids); 698 dev->wiphy.max_scan_ssids);
699 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
700 dev->wiphy.max_sched_scan_ssids);
686 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 701 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
687 dev->wiphy.max_scan_ie_len); 702 dev->wiphy.max_scan_ie_len);
703 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
704 dev->wiphy.max_sched_scan_ie_len);
688 705
689 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) 706 if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
690 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); 707 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
@@ -920,6 +937,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
920 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); 937 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
921 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) 938 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
922 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 939 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
940 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
941 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
942 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
943 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
944 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
945 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
946 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
947 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
948 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
949 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
923 if (dev->wiphy.wowlan.n_patterns) { 950 if (dev->wiphy.wowlan.n_patterns) {
924 struct nl80211_wowlan_pattern_support pat = { 951 struct nl80211_wowlan_pattern_support pat = {
925 .max_patterns = dev->wiphy.wowlan.n_patterns, 952 .max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -2209,6 +2236,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2209 } 2236 }
2210 nla_nest_end(msg, sinfoattr); 2237 nla_nest_end(msg, sinfoattr);
2211 2238
2239 if (sinfo->assoc_req_ies)
2240 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2241 sinfo->assoc_req_ies);
2242
2212 return genlmsg_end(msg, hdr); 2243 return genlmsg_end(msg, hdr);
2213 2244
2214 nla_put_failure: 2245 nla_put_failure:
@@ -2236,6 +2267,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
2236 } 2267 }
2237 2268
2238 while (1) { 2269 while (1) {
2270 memset(&sinfo, 0, sizeof(sinfo));
2239 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 2271 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2240 mac_addr, &sinfo); 2272 mac_addr, &sinfo);
2241 if (err == -ENOENT) 2273 if (err == -ENOENT)
@@ -3297,7 +3329,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3297 struct nlattr *attr; 3329 struct nlattr *attr;
3298 struct wiphy *wiphy; 3330 struct wiphy *wiphy;
3299 int err, tmp, n_ssids = 0, n_channels, i; 3331 int err, tmp, n_ssids = 0, n_channels, i;
3300 enum ieee80211_band band;
3301 size_t ie_len; 3332 size_t ie_len;
3302 3333
3303 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3334 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
@@ -3317,6 +3348,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3317 if (!n_channels) 3348 if (!n_channels)
3318 return -EINVAL; 3349 return -EINVAL;
3319 } else { 3350 } else {
3351 enum ieee80211_band band;
3320 n_channels = 0; 3352 n_channels = 0;
3321 3353
3322 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 3354 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
@@ -3377,6 +3409,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3377 i++; 3409 i++;
3378 } 3410 }
3379 } else { 3411 } else {
3412 enum ieee80211_band band;
3413
3380 /* all channels */ 3414 /* all channels */
3381 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 3415 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3382 int j; 3416 int j;
@@ -3423,6 +3457,30 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3423 request->ie_len); 3457 request->ie_len);
3424 } 3458 }
3425 3459
3460 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3461 if (wiphy->bands[i])
3462 request->rates[i] =
3463 (1 << wiphy->bands[i]->n_bitrates) - 1;
3464
3465 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
3466 nla_for_each_nested(attr,
3467 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
3468 tmp) {
3469 enum ieee80211_band band = nla_type(attr);
3470
3471 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
3472 err = -EINVAL;
3473 goto out_free;
3474 }
3475 err = ieee80211_get_ratemask(wiphy->bands[band],
3476 nla_data(attr),
3477 nla_len(attr),
3478 &request->rates[band]);
3479 if (err)
3480 goto out_free;
3481 }
3482 }
3483
3426 request->dev = dev; 3484 request->dev = dev;
3427 request->wiphy = &rdev->wiphy; 3485 request->wiphy = &rdev->wiphy;
3428 3486
@@ -3488,7 +3546,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3488 tmp) 3546 tmp)
3489 n_ssids++; 3547 n_ssids++;
3490 3548
3491 if (n_ssids > wiphy->max_scan_ssids) 3549 if (n_ssids > wiphy->max_sched_scan_ssids)
3492 return -EINVAL; 3550 return -EINVAL;
3493 3551
3494 if (info->attrs[NL80211_ATTR_IE]) 3552 if (info->attrs[NL80211_ATTR_IE])
@@ -3496,7 +3554,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3496 else 3554 else
3497 ie_len = 0; 3555 ie_len = 0;
3498 3556
3499 if (ie_len > wiphy->max_scan_ie_len) 3557 if (ie_len > wiphy->max_sched_scan_ie_len)
3500 return -EINVAL; 3558 return -EINVAL;
3501 3559
3502 mutex_lock(&rdev->sched_scan_mtx); 3560 mutex_lock(&rdev->sched_scan_mtx);
@@ -3632,7 +3690,8 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
3632 return err; 3690 return err;
3633} 3691}
3634 3692
3635static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3693static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
3694 u32 seq, int flags,
3636 struct cfg80211_registered_device *rdev, 3695 struct cfg80211_registered_device *rdev,
3637 struct wireless_dev *wdev, 3696 struct wireless_dev *wdev,
3638 struct cfg80211_internal_bss *intbss) 3697 struct cfg80211_internal_bss *intbss)
@@ -3644,11 +3703,13 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3644 3703
3645 ASSERT_WDEV_LOCK(wdev); 3704 ASSERT_WDEV_LOCK(wdev);
3646 3705
3647 hdr = nl80211hdr_put(msg, pid, seq, flags, 3706 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags,
3648 NL80211_CMD_NEW_SCAN_RESULTS); 3707 NL80211_CMD_NEW_SCAN_RESULTS);
3649 if (!hdr) 3708 if (!hdr)
3650 return -1; 3709 return -1;
3651 3710
3711 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
3712
3652 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation); 3713 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
3653 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex); 3714 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
3654 3715
@@ -3737,11 +3798,12 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3737 spin_lock_bh(&rdev->bss_lock); 3798 spin_lock_bh(&rdev->bss_lock);
3738 cfg80211_bss_expire(rdev); 3799 cfg80211_bss_expire(rdev);
3739 3800
3801 cb->seq = rdev->bss_generation;
3802
3740 list_for_each_entry(scan, &rdev->bss_list, list) { 3803 list_for_each_entry(scan, &rdev->bss_list, list) {
3741 if (++idx <= start) 3804 if (++idx <= start)
3742 continue; 3805 continue;
3743 if (nl80211_send_bss(skb, 3806 if (nl80211_send_bss(skb, cb,
3744 NETLINK_CB(cb->skb).pid,
3745 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3807 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3746 rdev, wdev, scan) < 0) { 3808 rdev, wdev, scan) < 0) {
3747 idx--; 3809 idx--;
@@ -3765,10 +3827,6 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3765 void *hdr; 3827 void *hdr;
3766 struct nlattr *infoattr; 3828 struct nlattr *infoattr;
3767 3829
3768 /* Survey without a channel doesn't make sense */
3769 if (!survey->channel)
3770 return -EINVAL;
3771
3772 hdr = nl80211hdr_put(msg, pid, seq, flags, 3830 hdr = nl80211hdr_put(msg, pid, seq, flags,
3773 NL80211_CMD_NEW_SURVEY_RESULTS); 3831 NL80211_CMD_NEW_SURVEY_RESULTS);
3774 if (!hdr) 3832 if (!hdr)
@@ -3831,6 +3889,8 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3831 } 3889 }
3832 3890
3833 while (1) { 3891 while (1) {
3892 struct ieee80211_channel *chan;
3893
3834 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, 3894 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
3835 &survey); 3895 &survey);
3836 if (res == -ENOENT) 3896 if (res == -ENOENT)
@@ -3838,6 +3898,19 @@ static int nl80211_dump_survey(struct sk_buff *skb,
3838 if (res) 3898 if (res)
3839 goto out_err; 3899 goto out_err;
3840 3900
3901 /* Survey without a channel doesn't make sense */
3902 if (!survey.channel) {
3903 res = -EINVAL;
3904 goto out;
3905 }
3906
3907 chan = ieee80211_get_channel(&dev->wiphy,
3908 survey.channel->center_freq);
3909 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
3910 survey_idx++;
3911 continue;
3912 }
3913
3841 if (nl80211_send_survey(skb, 3914 if (nl80211_send_survey(skb,
3842 NETLINK_CB(cb->skb).pid, 3915 NETLINK_CB(cb->skb).pid,
3843 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3916 cb->nlh->nlmsg_seq, NLM_F_MULTI,
@@ -4044,9 +4117,12 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4044 if (len % sizeof(u32)) 4117 if (len % sizeof(u32))
4045 return -EINVAL; 4118 return -EINVAL;
4046 4119
4120 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
4121 return -EINVAL;
4122
4047 memcpy(settings->akm_suites, data, len); 4123 memcpy(settings->akm_suites, data, len);
4048 4124
4049 for (i = 0; i < settings->n_ciphers_pairwise; i++) 4125 for (i = 0; i < settings->n_akm_suites; i++)
4050 if (!nl80211_valid_akm_suite(settings->akm_suites[i])) 4126 if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
4051 return -EINVAL; 4127 return -EINVAL;
4052 } 4128 }
@@ -4294,25 +4370,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
4294 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 4370 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
4295 struct ieee80211_supported_band *sband = 4371 struct ieee80211_supported_band *sband =
4296 wiphy->bands[ibss.channel->band]; 4372 wiphy->bands[ibss.channel->band];
4297 int i, j; 4373 int err;
4298
4299 if (n_rates == 0)
4300 return -EINVAL;
4301 4374
4302 for (i = 0; i < n_rates; i++) { 4375 err = ieee80211_get_ratemask(sband, rates, n_rates,
4303 int rate = (rates[i] & 0x7f) * 5; 4376 &ibss.basic_rates);
4304 bool found = false; 4377 if (err)
4305 4378 return err;
4306 for (j = 0; j < sband->n_bitrates; j++) {
4307 if (sband->bitrates[j].bitrate == rate) {
4308 found = true;
4309 ibss.basic_rates |= BIT(j);
4310 break;
4311 }
4312 }
4313 if (!found)
4314 return -EINVAL;
4315 }
4316 } 4379 }
4317 4380
4318 if (info->attrs[NL80211_ATTR_MCAST_RATE] && 4381 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
@@ -4372,6 +4435,93 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4372 return err; 4435 return err;
4373} 4436}
4374 4437
4438static int nl80211_testmode_dump(struct sk_buff *skb,
4439 struct netlink_callback *cb)
4440{
4441 struct cfg80211_registered_device *dev;
4442 int err;
4443 long phy_idx;
4444 void *data = NULL;
4445 int data_len = 0;
4446
4447 if (cb->args[0]) {
4448 /*
4449 * 0 is a valid index, but not valid for args[0],
4450 * so we need to offset by 1.
4451 */
4452 phy_idx = cb->args[0] - 1;
4453 } else {
4454 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
4455 nl80211_fam.attrbuf, nl80211_fam.maxattr,
4456 nl80211_policy);
4457 if (err)
4458 return err;
4459 if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY])
4460 return -EINVAL;
4461 phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
4462 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
4463 cb->args[1] =
4464 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
4465 }
4466
4467 if (cb->args[1]) {
4468 data = nla_data((void *)cb->args[1]);
4469 data_len = nla_len((void *)cb->args[1]);
4470 }
4471
4472 mutex_lock(&cfg80211_mutex);
4473 dev = cfg80211_rdev_by_wiphy_idx(phy_idx);
4474 if (!dev) {
4475 mutex_unlock(&cfg80211_mutex);
4476 return -ENOENT;
4477 }
4478 cfg80211_lock_rdev(dev);
4479 mutex_unlock(&cfg80211_mutex);
4480
4481 if (!dev->ops->testmode_dump) {
4482 err = -EOPNOTSUPP;
4483 goto out_err;
4484 }
4485
4486 while (1) {
4487 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
4488 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4489 NL80211_CMD_TESTMODE);
4490 struct nlattr *tmdata;
4491
4492 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) {
4493 genlmsg_cancel(skb, hdr);
4494 break;
4495 }
4496
4497 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
4498 if (!tmdata) {
4499 genlmsg_cancel(skb, hdr);
4500 break;
4501 }
4502 err = dev->ops->testmode_dump(&dev->wiphy, skb, cb,
4503 data, data_len);
4504 nla_nest_end(skb, tmdata);
4505
4506 if (err == -ENOBUFS || err == -ENOENT) {
4507 genlmsg_cancel(skb, hdr);
4508 break;
4509 } else if (err) {
4510 genlmsg_cancel(skb, hdr);
4511 goto out_err;
4512 }
4513
4514 genlmsg_end(skb, hdr);
4515 }
4516
4517 err = skb->len;
4518 /* see above */
4519 cb->args[0] = phy_idx + 1;
4520 out_err:
4521 cfg80211_unlock_rdev(dev);
4522 return err;
4523}
4524
4375static struct sk_buff * 4525static struct sk_buff *
4376__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, 4526__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
4377 int approxlen, u32 pid, u32 seq, gfp_t gfp) 4527 int approxlen, u32 pid, u32 seq, gfp_t gfp)
@@ -5161,6 +5311,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
5161 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); 5311 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
5162 if (rdev->wowlan->magic_pkt) 5312 if (rdev->wowlan->magic_pkt)
5163 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); 5313 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
5314 if (rdev->wowlan->gtk_rekey_failure)
5315 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
5316 if (rdev->wowlan->eap_identity_req)
5317 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
5318 if (rdev->wowlan->four_way_handshake)
5319 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
5320 if (rdev->wowlan->rfkill_release)
5321 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
5164 if (rdev->wowlan->n_patterns) { 5322 if (rdev->wowlan->n_patterns) {
5165 struct nlattr *nl_pats, *nl_pat; 5323 struct nlattr *nl_pats, *nl_pat;
5166 int i, pat_len; 5324 int i, pat_len;
@@ -5237,6 +5395,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5237 new_triggers.magic_pkt = true; 5395 new_triggers.magic_pkt = true;
5238 } 5396 }
5239 5397
5398 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
5399 return -EINVAL;
5400
5401 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
5402 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
5403 return -EINVAL;
5404 new_triggers.gtk_rekey_failure = true;
5405 }
5406
5407 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
5408 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
5409 return -EINVAL;
5410 new_triggers.eap_identity_req = true;
5411 }
5412
5413 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
5414 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
5415 return -EINVAL;
5416 new_triggers.four_way_handshake = true;
5417 }
5418
5419 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
5420 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
5421 return -EINVAL;
5422 new_triggers.rfkill_release = true;
5423 }
5424
5240 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { 5425 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
5241 struct nlattr *pat; 5426 struct nlattr *pat;
5242 int n_patterns = 0; 5427 int n_patterns = 0;
@@ -5318,6 +5503,57 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5318 return err; 5503 return err;
5319} 5504}
5320 5505
5506static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
5507{
5508 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5509 struct net_device *dev = info->user_ptr[1];
5510 struct wireless_dev *wdev = dev->ieee80211_ptr;
5511 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
5512 struct cfg80211_gtk_rekey_data rekey_data;
5513 int err;
5514
5515 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
5516 return -EINVAL;
5517
5518 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
5519 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
5520 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
5521 nl80211_rekey_policy);
5522 if (err)
5523 return err;
5524
5525 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
5526 return -ERANGE;
5527 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
5528 return -ERANGE;
5529 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
5530 return -ERANGE;
5531
5532 memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
5533 NL80211_KEK_LEN);
5534 memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
5535 NL80211_KCK_LEN);
5536 memcpy(rekey_data.replay_ctr,
5537 nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
5538 NL80211_REPLAY_CTR_LEN);
5539
5540 wdev_lock(wdev);
5541 if (!wdev->current_bss) {
5542 err = -ENOTCONN;
5543 goto out;
5544 }
5545
5546 if (!rdev->ops->set_rekey_data) {
5547 err = -EOPNOTSUPP;
5548 goto out;
5549 }
5550
5551 err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data);
5552 out:
5553 wdev_unlock(wdev);
5554 return err;
5555}
5556
5321#define NL80211_FLAG_NEED_WIPHY 0x01 5557#define NL80211_FLAG_NEED_WIPHY 0x01
5322#define NL80211_FLAG_NEED_NETDEV 0x02 5558#define NL80211_FLAG_NEED_NETDEV 0x02
5323#define NL80211_FLAG_NEED_RTNL 0x04 5559#define NL80211_FLAG_NEED_RTNL 0x04
@@ -5669,6 +5905,7 @@ static struct genl_ops nl80211_ops[] = {
5669 { 5905 {
5670 .cmd = NL80211_CMD_TESTMODE, 5906 .cmd = NL80211_CMD_TESTMODE,
5671 .doit = nl80211_testmode_do, 5907 .doit = nl80211_testmode_do,
5908 .dumpit = nl80211_testmode_dump,
5672 .policy = nl80211_policy, 5909 .policy = nl80211_policy,
5673 .flags = GENL_ADMIN_PERM, 5910 .flags = GENL_ADMIN_PERM,
5674 .internal_flags = NL80211_FLAG_NEED_WIPHY | 5911 .internal_flags = NL80211_FLAG_NEED_WIPHY |
@@ -5848,6 +6085,14 @@ static struct genl_ops nl80211_ops[] = {
5848 .internal_flags = NL80211_FLAG_NEED_WIPHY | 6085 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5849 NL80211_FLAG_NEED_RTNL, 6086 NL80211_FLAG_NEED_RTNL,
5850 }, 6087 },
6088 {
6089 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
6090 .doit = nl80211_set_rekey_data,
6091 .policy = nl80211_policy,
6092 .flags = GENL_ADMIN_PERM,
6093 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6094 NL80211_FLAG_NEED_RTNL,
6095 },
5851}; 6096};
5852 6097
5853static struct genl_multicast_group nl80211_mlme_mcgrp = { 6098static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -6792,6 +7037,51 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
6792 nlmsg_free(msg); 7037 nlmsg_free(msg);
6793} 7038}
6794 7039
7040void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
7041 struct net_device *netdev, const u8 *bssid,
7042 const u8 *replay_ctr, gfp_t gfp)
7043{
7044 struct sk_buff *msg;
7045 struct nlattr *rekey_attr;
7046 void *hdr;
7047
7048 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7049 if (!msg)
7050 return;
7051
7052 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
7053 if (!hdr) {
7054 nlmsg_free(msg);
7055 return;
7056 }
7057
7058 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
7059 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
7060 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
7061
7062 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
7063 if (!rekey_attr)
7064 goto nla_put_failure;
7065
7066 NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR,
7067 NL80211_REPLAY_CTR_LEN, replay_ctr);
7068
7069 nla_nest_end(msg, rekey_attr);
7070
7071 if (genlmsg_end(msg, hdr) < 0) {
7072 nlmsg_free(msg);
7073 return;
7074 }
7075
7076 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7077 nl80211_mlme_mcgrp.id, gfp);
7078 return;
7079
7080 nla_put_failure:
7081 genlmsg_cancel(msg, hdr);
7082 nlmsg_free(msg);
7083}
7084
6795void 7085void
6796nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 7086nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
6797 struct net_device *netdev, const u8 *peer, 7087 struct net_device *netdev, const u8 *peer,