diff options
author | David S. Miller <davem@davemloft.net> | 2018-06-30 08:08:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-06-30 08:08:12 -0400 |
commit | 8365da2c0570f02615e7f1d2d729d854029202b0 (patch) | |
tree | 223ab9641411c401269e5da80f260cafaf40eedc /net/mac80211/scan.c | |
parent | a1be5a20f137bdf436bab86c18998229908ce951 (diff) | |
parent | a4217750586975dee7d6dd8829a1be24a7678b3d (diff) |
Merge tag 'mac80211-next-for-davem-2018-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Small merge conflict in net/mac80211/scan.c, I preserved
the kcalloc() conversion. -DaveM
Johannes Berg says:
====================
This round's updates:
* finally some of the promised HE code, but it turns
out to be small - but everything kept changing, so
one part I did in the driver was >30 patches for
what was ultimately <200 lines of code ... similar
here for this code.
* improved scan privacy support - can now specify scan
flags for randomizing the sequence number as well as
reducing the probe request element content
* rfkill cleanups
* a timekeeping cleanup from Arnd
* various other cleanups
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 2e917a6d239d..5d2a11777718 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/sch_generic.h> | 20 | #include <net/sch_generic.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/export.h> | 22 | #include <linux/export.h> |
23 | #include <linux/random.h> | ||
23 | #include <net/mac80211.h> | 24 | #include <net/mac80211.h> |
24 | 25 | ||
25 | #include "ieee80211_i.h" | 26 | #include "ieee80211_i.h" |
@@ -293,6 +294,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
293 | struct cfg80211_chan_def chandef; | 294 | struct cfg80211_chan_def chandef; |
294 | u8 bands_used = 0; | 295 | u8 bands_used = 0; |
295 | int i, ielen, n_chans; | 296 | int i, ielen, n_chans; |
297 | u32 flags = 0; | ||
296 | 298 | ||
297 | req = rcu_dereference_protected(local->scan_req, | 299 | req = rcu_dereference_protected(local->scan_req, |
298 | lockdep_is_held(&local->mtx)); | 300 | lockdep_is_held(&local->mtx)); |
@@ -331,12 +333,16 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
331 | local->hw_scan_req->req.n_channels = n_chans; | 333 | local->hw_scan_req->req.n_channels = n_chans; |
332 | ieee80211_prepare_scan_chandef(&chandef, req->scan_width); | 334 | ieee80211_prepare_scan_chandef(&chandef, req->scan_width); |
333 | 335 | ||
336 | if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) | ||
337 | flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; | ||
338 | |||
334 | ielen = ieee80211_build_preq_ies(local, | 339 | ielen = ieee80211_build_preq_ies(local, |
335 | (u8 *)local->hw_scan_req->req.ie, | 340 | (u8 *)local->hw_scan_req->req.ie, |
336 | local->hw_scan_ies_bufsize, | 341 | local->hw_scan_ies_bufsize, |
337 | &local->hw_scan_req->ies, | 342 | &local->hw_scan_req->ies, |
338 | req->ie, req->ie_len, | 343 | req->ie, req->ie_len, |
339 | bands_used, req->rates, &chandef); | 344 | bands_used, req->rates, &chandef, |
345 | flags); | ||
340 | local->hw_scan_req->req.ie_len = ielen; | 346 | local->hw_scan_req->req.ie_len = ielen; |
341 | local->hw_scan_req->req.no_cck = req->no_cck; | 347 | local->hw_scan_req->req.no_cck = req->no_cck; |
342 | ether_addr_copy(local->hw_scan_req->req.mac_addr, req->mac_addr); | 348 | ether_addr_copy(local->hw_scan_req->req.mac_addr, req->mac_addr); |
@@ -528,6 +534,35 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local) | |||
528 | round_jiffies_relative(0)); | 534 | round_jiffies_relative(0)); |
529 | } | 535 | } |
530 | 536 | ||
537 | static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata, | ||
538 | const u8 *src, const u8 *dst, | ||
539 | const u8 *ssid, size_t ssid_len, | ||
540 | const u8 *ie, size_t ie_len, | ||
541 | u32 ratemask, u32 flags, u32 tx_flags, | ||
542 | struct ieee80211_channel *channel) | ||
543 | { | ||
544 | struct sk_buff *skb; | ||
545 | u32 txdata_flags = 0; | ||
546 | |||
547 | skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel, | ||
548 | ssid, ssid_len, | ||
549 | ie, ie_len, flags); | ||
550 | |||
551 | if (skb) { | ||
552 | if (flags & IEEE80211_PROBE_FLAG_RANDOM_SN) { | ||
553 | struct ieee80211_hdr *hdr = (void *)skb->data; | ||
554 | u16 sn = get_random_u32(); | ||
555 | |||
556 | txdata_flags |= IEEE80211_TX_NO_SEQNO; | ||
557 | hdr->seq_ctrl = | ||
558 | cpu_to_le16(IEEE80211_SN_TO_SEQ(sn)); | ||
559 | } | ||
560 | IEEE80211_SKB_CB(skb)->flags |= tx_flags; | ||
561 | ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band, | ||
562 | txdata_flags); | ||
563 | } | ||
564 | } | ||
565 | |||
531 | static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | 566 | static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, |
532 | unsigned long *next_delay) | 567 | unsigned long *next_delay) |
533 | { | 568 | { |
@@ -535,7 +570,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
535 | struct ieee80211_sub_if_data *sdata; | 570 | struct ieee80211_sub_if_data *sdata; |
536 | struct cfg80211_scan_request *scan_req; | 571 | struct cfg80211_scan_request *scan_req; |
537 | enum nl80211_band band = local->hw.conf.chandef.chan->band; | 572 | enum nl80211_band band = local->hw.conf.chandef.chan->band; |
538 | u32 tx_flags; | 573 | u32 flags = 0, tx_flags; |
539 | 574 | ||
540 | scan_req = rcu_dereference_protected(local->scan_req, | 575 | scan_req = rcu_dereference_protected(local->scan_req, |
541 | lockdep_is_held(&local->mtx)); | 576 | lockdep_is_held(&local->mtx)); |
@@ -543,17 +578,21 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
543 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; | 578 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; |
544 | if (scan_req->no_cck) | 579 | if (scan_req->no_cck) |
545 | tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | 580 | tx_flags |= IEEE80211_TX_CTL_NO_CCK_RATE; |
581 | if (scan_req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) | ||
582 | flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; | ||
583 | if (scan_req->flags & NL80211_SCAN_FLAG_RANDOM_SN) | ||
584 | flags |= IEEE80211_PROBE_FLAG_RANDOM_SN; | ||
546 | 585 | ||
547 | sdata = rcu_dereference_protected(local->scan_sdata, | 586 | sdata = rcu_dereference_protected(local->scan_sdata, |
548 | lockdep_is_held(&local->mtx)); | 587 | lockdep_is_held(&local->mtx)); |
549 | 588 | ||
550 | for (i = 0; i < scan_req->n_ssids; i++) | 589 | for (i = 0; i < scan_req->n_ssids; i++) |
551 | ieee80211_send_probe_req( | 590 | ieee80211_send_scan_probe_req( |
552 | sdata, local->scan_addr, scan_req->bssid, | 591 | sdata, local->scan_addr, scan_req->bssid, |
553 | scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, | 592 | scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, |
554 | scan_req->ie, scan_req->ie_len, | 593 | scan_req->ie, scan_req->ie_len, |
555 | scan_req->rates[band], false, | 594 | scan_req->rates[band], flags, |
556 | tx_flags, local->hw.conf.chandef.chan, true); | 595 | tx_flags, local->hw.conf.chandef.chan); |
557 | 596 | ||
558 | /* | 597 | /* |
559 | * After sending probe requests, wait for probe responses | 598 | * After sending probe requests, wait for probe responses |
@@ -1141,6 +1180,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1141 | u32 rate_masks[NUM_NL80211_BANDS] = {}; | 1180 | u32 rate_masks[NUM_NL80211_BANDS] = {}; |
1142 | u8 bands_used = 0; | 1181 | u8 bands_used = 0; |
1143 | u8 *ie; | 1182 | u8 *ie; |
1183 | u32 flags = 0; | ||
1144 | 1184 | ||
1145 | iebufsz = local->scan_ies_len + req->ie_len; | 1185 | iebufsz = local->scan_ies_len + req->ie_len; |
1146 | 1186 | ||
@@ -1157,6 +1197,9 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1157 | } | 1197 | } |
1158 | } | 1198 | } |
1159 | 1199 | ||
1200 | if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) | ||
1201 | flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; | ||
1202 | |||
1160 | ie = kcalloc(iebufsz, num_bands, GFP_KERNEL); | 1203 | ie = kcalloc(iebufsz, num_bands, GFP_KERNEL); |
1161 | if (!ie) { | 1204 | if (!ie) { |
1162 | ret = -ENOMEM; | 1205 | ret = -ENOMEM; |
@@ -1167,7 +1210,8 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1167 | 1210 | ||
1168 | ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, | 1211 | ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, |
1169 | &sched_scan_ies, req->ie, | 1212 | &sched_scan_ies, req->ie, |
1170 | req->ie_len, bands_used, rate_masks, &chandef); | 1213 | req->ie_len, bands_used, rate_masks, &chandef, |
1214 | flags); | ||
1171 | 1215 | ||
1172 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); | 1216 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); |
1173 | if (ret == 0) { | 1217 | if (ret == 0) { |