aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/scan.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-06-30 08:08:12 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-30 08:08:12 -0400
commit8365da2c0570f02615e7f1d2d729d854029202b0 (patch)
tree223ab9641411c401269e5da80f260cafaf40eedc /net/mac80211/scan.c
parenta1be5a20f137bdf436bab86c18998229908ce951 (diff)
parenta4217750586975dee7d6dd8829a1be24a7678b3d (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.c56
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
537static 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
531static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, 566static 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) {