diff options
author | Johannes Berg <johannes.berg@intel.com> | 2018-05-28 09:47:41 -0400 |
---|---|---|
committer | Johannes Berg <johannes@sipsolutions.net> | 2018-06-15 07:34:40 -0400 |
commit | b9771d41aee7aa3207b985422a1cc19e8342bc50 (patch) | |
tree | 13413533108492a4bb95aa282abf426fab1d707e | |
parent | 2e076f199097d670ce5e5492cea57f552b93bba9 (diff) |
mac80211: support scan features for improved scan privacy
Support the new random SN and minimal probe request contents
scan flags for the case of software scan - for hardware scan
the drivers need to opt in, but may need to do only that,
depending on their implementation.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 14 | ||||
-rw-r--r-- | net/mac80211/main.c | 13 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 2 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/scan.c | 35 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 21 | ||||
-rw-r--r-- | net/mac80211/util.c | 4 |
9 files changed, 71 insertions, 24 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bdf6fa78d0d2..c4e2f7d2bcb8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -3486,7 +3486,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
3486 | } | 3486 | } |
3487 | 3487 | ||
3488 | local_bh_disable(); | 3488 | local_bh_disable(); |
3489 | ieee80211_xmit(sdata, sta, skb); | 3489 | ieee80211_xmit(sdata, sta, skb, 0); |
3490 | local_bh_enable(); | 3490 | local_bh_enable(); |
3491 | 3491 | ||
3492 | ret = 0; | 3492 | ret = 0; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2851245c569a..a6c12c104c38 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -165,6 +165,7 @@ typedef unsigned __bitwise ieee80211_tx_result; | |||
165 | #define TX_DROP ((__force ieee80211_tx_result) 1u) | 165 | #define TX_DROP ((__force ieee80211_tx_result) 1u) |
166 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) | 166 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) |
167 | 167 | ||
168 | #define IEEE80211_TX_NO_SEQNO BIT(0) | ||
168 | #define IEEE80211_TX_UNICAST BIT(1) | 169 | #define IEEE80211_TX_UNICAST BIT(1) |
169 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 170 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
170 | 171 | ||
@@ -1880,19 +1881,20 @@ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, | |||
1880 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | 1881 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, |
1881 | bool bss_notify, bool enable_qos); | 1882 | bool bss_notify, bool enable_qos); |
1882 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | 1883 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1883 | struct sta_info *sta, struct sk_buff *skb); | 1884 | struct sta_info *sta, struct sk_buff *skb, |
1885 | u32 txdata_flags); | ||
1884 | 1886 | ||
1885 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | 1887 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
1886 | struct sk_buff *skb, int tid, | 1888 | struct sk_buff *skb, int tid, |
1887 | enum nl80211_band band); | 1889 | enum nl80211_band band, u32 txdata_flags); |
1888 | 1890 | ||
1889 | static inline void | 1891 | static inline void |
1890 | ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | 1892 | ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
1891 | struct sk_buff *skb, int tid, | 1893 | struct sk_buff *skb, int tid, |
1892 | enum nl80211_band band) | 1894 | enum nl80211_band band, u32 txdata_flags) |
1893 | { | 1895 | { |
1894 | rcu_read_lock(); | 1896 | rcu_read_lock(); |
1895 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, band); | 1897 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, band, txdata_flags); |
1896 | rcu_read_unlock(); | 1898 | rcu_read_unlock(); |
1897 | } | 1899 | } |
1898 | 1900 | ||
@@ -1910,7 +1912,7 @@ static inline void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | |||
1910 | } | 1912 | } |
1911 | 1913 | ||
1912 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, | 1914 | __ieee80211_tx_skb_tid_band(sdata, skb, tid, |
1913 | chanctx_conf->def.chan->band); | 1915 | chanctx_conf->def.chan->band, 0); |
1914 | rcu_read_unlock(); | 1916 | rcu_read_unlock(); |
1915 | } | 1917 | } |
1916 | 1918 | ||
@@ -2034,6 +2036,8 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2034 | 2036 | ||
2035 | enum { | 2037 | enum { |
2036 | IEEE80211_PROBE_FLAG_DIRECTED = BIT(0), | 2038 | IEEE80211_PROBE_FLAG_DIRECTED = BIT(0), |
2039 | IEEE80211_PROBE_FLAG_MIN_CONTENT = BIT(1), | ||
2040 | IEEE80211_PROBE_FLAG_RANDOM_SN = BIT(2), | ||
2037 | }; | 2041 | }; |
2038 | 2042 | ||
2039 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 2043 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4d2e797e3f16..a6f8e3a646d4 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -557,10 +557,19 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, | |||
557 | wiphy_ext_feature_set(wiphy, | 557 | wiphy_ext_feature_set(wiphy, |
558 | NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); | 558 | NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211); |
559 | 559 | ||
560 | if (!ops->hw_scan) | 560 | if (!ops->hw_scan) { |
561 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | | 561 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | |
562 | NL80211_FEATURE_AP_SCAN; | 562 | NL80211_FEATURE_AP_SCAN; |
563 | 563 | /* | |
564 | * if the driver behaves correctly using the probe request | ||
565 | * (template) from mac80211, then both of these should be | ||
566 | * supported even with hw scan - but let drivers opt in. | ||
567 | */ | ||
568 | wiphy_ext_feature_set(wiphy, | ||
569 | NL80211_EXT_FEATURE_SCAN_RANDOM_SN); | ||
570 | wiphy_ext_feature_set(wiphy, | ||
571 | NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT); | ||
572 | } | ||
564 | 573 | ||
565 | if (!ops->set_key) | 574 | if (!ops->set_key) |
566 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 575 | wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index f1d40b6645ff..8ef4153cd299 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -262,7 +262,7 @@ static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc, | |||
262 | if (roc->mgmt_tx_cookie) { | 262 | if (roc->mgmt_tx_cookie) { |
263 | if (!WARN_ON(!roc->frame)) { | 263 | if (!WARN_ON(!roc->frame)) { |
264 | ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7, | 264 | ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7, |
265 | roc->chan->band); | 265 | roc->chan->band, 0); |
266 | roc->frame = NULL; | 266 | roc->frame = NULL; |
267 | } | 267 | } |
268 | } else { | 268 | } else { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0a38cc1cbebc..756ba176db1e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3241,7 +3241,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
3241 | } | 3241 | } |
3242 | 3242 | ||
3243 | __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, | 3243 | __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, |
3244 | status->band); | 3244 | status->band, 0); |
3245 | } | 3245 | } |
3246 | dev_kfree_skb(rx->skb); | 3246 | dev_kfree_skb(rx->skb); |
3247 | return RX_QUEUED; | 3247 | return RX_QUEUED; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 03f66f31c5b4..ae77d1c12856 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, 0); | 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); |
@@ -536,13 +542,24 @@ static void ieee80211_send_scan_probe_req(struct ieee80211_sub_if_data *sdata, | |||
536 | struct ieee80211_channel *channel) | 542 | struct ieee80211_channel *channel) |
537 | { | 543 | { |
538 | struct sk_buff *skb; | 544 | struct sk_buff *skb; |
545 | u32 txdata_flags = 0; | ||
539 | 546 | ||
540 | skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel, | 547 | skb = ieee80211_build_probe_req(sdata, src, dst, ratemask, channel, |
541 | ssid, ssid_len, | 548 | ssid, ssid_len, |
542 | ie, ie_len, flags); | 549 | ie, ie_len, flags); |
550 | |||
543 | if (skb) { | 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 | } | ||
544 | IEEE80211_SKB_CB(skb)->flags |= tx_flags; | 560 | IEEE80211_SKB_CB(skb)->flags |= tx_flags; |
545 | ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band); | 561 | ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band, |
562 | txdata_flags); | ||
546 | } | 563 | } |
547 | } | 564 | } |
548 | 565 | ||
@@ -553,7 +570,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
553 | struct ieee80211_sub_if_data *sdata; | 570 | struct ieee80211_sub_if_data *sdata; |
554 | struct cfg80211_scan_request *scan_req; | 571 | struct cfg80211_scan_request *scan_req; |
555 | enum nl80211_band band = local->hw.conf.chandef.chan->band; | 572 | enum nl80211_band band = local->hw.conf.chandef.chan->band; |
556 | u32 tx_flags; | 573 | u32 flags = 0, tx_flags; |
557 | 574 | ||
558 | scan_req = rcu_dereference_protected(local->scan_req, | 575 | scan_req = rcu_dereference_protected(local->scan_req, |
559 | lockdep_is_held(&local->mtx)); | 576 | lockdep_is_held(&local->mtx)); |
@@ -561,6 +578,10 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
561 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; | 578 | tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK; |
562 | if (scan_req->no_cck) | 579 | if (scan_req->no_cck) |
563 | 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; | ||
564 | 585 | ||
565 | sdata = rcu_dereference_protected(local->scan_sdata, | 586 | sdata = rcu_dereference_protected(local->scan_sdata, |
566 | lockdep_is_held(&local->mtx)); | 587 | lockdep_is_held(&local->mtx)); |
@@ -570,7 +591,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
570 | sdata, local->scan_addr, scan_req->bssid, | 591 | sdata, local->scan_addr, scan_req->bssid, |
571 | scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, | 592 | scan_req->ssids[i].ssid, scan_req->ssids[i].ssid_len, |
572 | scan_req->ie, scan_req->ie_len, | 593 | scan_req->ie, scan_req->ie_len, |
573 | scan_req->rates[band], 0, | 594 | scan_req->rates[band], flags, |
574 | tx_flags, local->hw.conf.chandef.chan); | 595 | tx_flags, local->hw.conf.chandef.chan); |
575 | 596 | ||
576 | /* | 597 | /* |
@@ -1159,6 +1180,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1159 | u32 rate_masks[NUM_NL80211_BANDS] = {}; | 1180 | u32 rate_masks[NUM_NL80211_BANDS] = {}; |
1160 | u8 bands_used = 0; | 1181 | u8 bands_used = 0; |
1161 | u8 *ie; | 1182 | u8 *ie; |
1183 | u32 flags = 0; | ||
1162 | 1184 | ||
1163 | iebufsz = local->scan_ies_len + req->ie_len; | 1185 | iebufsz = local->scan_ies_len + req->ie_len; |
1164 | 1186 | ||
@@ -1175,6 +1197,9 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1175 | } | 1197 | } |
1176 | } | 1198 | } |
1177 | 1199 | ||
1200 | if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT) | ||
1201 | flags |= IEEE80211_PROBE_FLAG_MIN_CONTENT; | ||
1202 | |||
1178 | ie = kzalloc(num_bands * iebufsz, GFP_KERNEL); | 1203 | ie = kzalloc(num_bands * iebufsz, GFP_KERNEL); |
1179 | if (!ie) { | 1204 | if (!ie) { |
1180 | ret = -ENOMEM; | 1205 | ret = -ENOMEM; |
@@ -1186,7 +1211,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
1186 | ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, | 1211 | ieee80211_build_preq_ies(local, ie, num_bands * iebufsz, |
1187 | &sched_scan_ies, req->ie, | 1212 | &sched_scan_ies, req->ie, |
1188 | req->ie_len, bands_used, rate_masks, &chandef, | 1213 | req->ie_len, bands_used, rate_masks, &chandef, |
1189 | 0); | 1214 | flags); |
1190 | 1215 | ||
1191 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); | 1216 | ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); |
1192 | if (ret == 0) { | 1217 | if (ret == 0) { |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6428f1ac37b6..aa96fddfbfc2 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1391,7 +1391,7 @@ static void ieee80211_send_null_response(struct sta_info *sta, int tid, | |||
1391 | } | 1391 | } |
1392 | 1392 | ||
1393 | info->band = chanctx_conf->def.chan->band; | 1393 | info->band = chanctx_conf->def.chan->band; |
1394 | ieee80211_xmit(sdata, sta, skb); | 1394 | ieee80211_xmit(sdata, sta, skb, 0); |
1395 | rcu_read_unlock(); | 1395 | rcu_read_unlock(); |
1396 | } | 1396 | } |
1397 | 1397 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 44b5dfe8727d..5b93bde248fd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -825,6 +825,8 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
825 | */ | 825 | */ |
826 | if (!ieee80211_is_data_qos(hdr->frame_control) || | 826 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
827 | is_multicast_ether_addr(hdr->addr1)) { | 827 | is_multicast_ether_addr(hdr->addr1)) { |
828 | if (tx->flags & IEEE80211_TX_NO_SEQNO) | ||
829 | return TX_CONTINUE; | ||
828 | /* driver should assign sequence number */ | 830 | /* driver should assign sequence number */ |
829 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 831 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
830 | /* for pure STA mode without beacons, we can do it */ | 832 | /* for pure STA mode without beacons, we can do it */ |
@@ -1854,7 +1856,7 @@ EXPORT_SYMBOL(ieee80211_tx_prepare_skb); | |||
1854 | */ | 1856 | */ |
1855 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | 1857 | static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, |
1856 | struct sta_info *sta, struct sk_buff *skb, | 1858 | struct sta_info *sta, struct sk_buff *skb, |
1857 | bool txpending) | 1859 | bool txpending, u32 txdata_flags) |
1858 | { | 1860 | { |
1859 | struct ieee80211_local *local = sdata->local; | 1861 | struct ieee80211_local *local = sdata->local; |
1860 | struct ieee80211_tx_data tx; | 1862 | struct ieee80211_tx_data tx; |
@@ -1872,6 +1874,8 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata, | |||
1872 | led_len = skb->len; | 1874 | led_len = skb->len; |
1873 | res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb); | 1875 | res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb); |
1874 | 1876 | ||
1877 | tx.flags |= txdata_flags; | ||
1878 | |||
1875 | if (unlikely(res_prepare == TX_DROP)) { | 1879 | if (unlikely(res_prepare == TX_DROP)) { |
1876 | ieee80211_free_txskb(&local->hw, skb); | 1880 | ieee80211_free_txskb(&local->hw, skb); |
1877 | return true; | 1881 | return true; |
@@ -1933,7 +1937,8 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata, | |||
1933 | } | 1937 | } |
1934 | 1938 | ||
1935 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | 1939 | void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1936 | struct sta_info *sta, struct sk_buff *skb) | 1940 | struct sta_info *sta, struct sk_buff *skb, |
1941 | u32 txdata_flags) | ||
1937 | { | 1942 | { |
1938 | struct ieee80211_local *local = sdata->local; | 1943 | struct ieee80211_local *local = sdata->local; |
1939 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1944 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -1968,7 +1973,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1968 | } | 1973 | } |
1969 | 1974 | ||
1970 | ieee80211_set_qos_hdr(sdata, skb); | 1975 | ieee80211_set_qos_hdr(sdata, skb); |
1971 | ieee80211_tx(sdata, sta, skb, false); | 1976 | ieee80211_tx(sdata, sta, skb, false, txdata_flags); |
1972 | } | 1977 | } |
1973 | 1978 | ||
1974 | static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local, | 1979 | static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local, |
@@ -2289,7 +2294,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
2289 | if (!ieee80211_parse_tx_radiotap(local, skb)) | 2294 | if (!ieee80211_parse_tx_radiotap(local, skb)) |
2290 | goto fail_rcu; | 2295 | goto fail_rcu; |
2291 | 2296 | ||
2292 | ieee80211_xmit(sdata, NULL, skb); | 2297 | ieee80211_xmit(sdata, NULL, skb, 0); |
2293 | rcu_read_unlock(); | 2298 | rcu_read_unlock(); |
2294 | 2299 | ||
2295 | return NETDEV_TX_OK; | 2300 | return NETDEV_TX_OK; |
@@ -3648,7 +3653,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
3648 | 3653 | ||
3649 | ieee80211_tx_stats(dev, skb->len); | 3654 | ieee80211_tx_stats(dev, skb->len); |
3650 | 3655 | ||
3651 | ieee80211_xmit(sdata, sta, skb); | 3656 | ieee80211_xmit(sdata, sta, skb, 0); |
3652 | } | 3657 | } |
3653 | goto out; | 3658 | goto out; |
3654 | out_free: | 3659 | out_free: |
@@ -3867,7 +3872,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, | |||
3867 | return true; | 3872 | return true; |
3868 | } | 3873 | } |
3869 | info->band = chanctx_conf->def.chan->band; | 3874 | info->band = chanctx_conf->def.chan->band; |
3870 | result = ieee80211_tx(sdata, NULL, skb, true); | 3875 | result = ieee80211_tx(sdata, NULL, skb, true, 0); |
3871 | } else { | 3876 | } else { |
3872 | struct sk_buff_head skbs; | 3877 | struct sk_buff_head skbs; |
3873 | 3878 | ||
@@ -4783,7 +4788,7 @@ EXPORT_SYMBOL(ieee80211_unreserve_tid); | |||
4783 | 4788 | ||
4784 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | 4789 | void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, |
4785 | struct sk_buff *skb, int tid, | 4790 | struct sk_buff *skb, int tid, |
4786 | enum nl80211_band band) | 4791 | enum nl80211_band band, u32 txdata_flags) |
4787 | { | 4792 | { |
4788 | int ac = ieee80211_ac_from_tid(tid); | 4793 | int ac = ieee80211_ac_from_tid(tid); |
4789 | 4794 | ||
@@ -4800,7 +4805,7 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | |||
4800 | */ | 4805 | */ |
4801 | local_bh_disable(); | 4806 | local_bh_disable(); |
4802 | IEEE80211_SKB_CB(skb)->band = band; | 4807 | IEEE80211_SKB_CB(skb)->band = band; |
4803 | ieee80211_xmit(sdata, NULL, skb); | 4808 | ieee80211_xmit(sdata, NULL, skb, txdata_flags); |
4804 | local_bh_enable(); | 4809 | local_bh_enable(); |
4805 | } | 4810 | } |
4806 | 4811 | ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 0325133552ad..b744b10465c3 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1433,6 +1433,9 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, | |||
1433 | chandef->chan->center_freq); | 1433 | chandef->chan->center_freq); |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | if (flags & IEEE80211_PROBE_FLAG_MIN_CONTENT) | ||
1437 | goto done; | ||
1438 | |||
1436 | /* insert custom IEs that go before HT */ | 1439 | /* insert custom IEs that go before HT */ |
1437 | if (ie && ie_len) { | 1440 | if (ie && ie_len) { |
1438 | static const u8 before_ht[] = { | 1441 | static const u8 before_ht[] = { |
@@ -1510,6 +1513,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, | |||
1510 | return pos - buffer; | 1513 | return pos - buffer; |
1511 | out_err: | 1514 | out_err: |
1512 | WARN_ONCE(1, "not enough space for preq IEs\n"); | 1515 | WARN_ONCE(1, "not enough space for preq IEs\n"); |
1516 | done: | ||
1513 | return pos - buffer; | 1517 | return pos - buffer; |
1514 | } | 1518 | } |
1515 | 1519 | ||