diff options
author | David S. Miller <davem@davemloft.net> | 2018-02-22 15:17:01 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-22 15:17:01 -0500 |
commit | ed04c46d4e70007e102d88dd2ee648008f7f634d (patch) | |
tree | cf2be2159c7d7ffb2004e7b9107ec1a6039b1e2c | |
parent | a2c0f039bbd0f9ebf375176d05b056e3f3b5c4f7 (diff) | |
parent | 657308f73e674e86b60509a430a46e569bf02846 (diff) |
Merge tag 'mac80211-for-davem-2018-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says:
====================
Various fixes across the tree, the shortlog basically says it all:
cfg80211: fix cfg80211_beacon_dup
-> old bug in this code
cfg80211: clear wep keys after disconnection
-> certain ways of disconnecting left the keys
mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4
-> alignment issues with using 14 bytes
mac80211: Do not disconnect on invalid operating class
-> if the AP has a bogus operating class, let it be
mac80211: Fix sending ADDBA response for an ongoing session
-> don't send the same frame twice
cfg80211: use only 1Mbps for basic rates in mesh
-> interop issue with old versions of our code
mac80211_hwsim: don't use WQ_MEM_RECLAIM
-> it causes splats because it flushes work on a non-reclaim WQ
regulatory: add NUL to request alpha2
-> nla_put_string() issue from Kees
mac80211: mesh: fix wrong mesh TTL offset calculation
-> protocol issue
mac80211: fix a possible leak of station stats
-> error path might leak memory
mac80211: fix calling sleeping function in atomic context
-> percpu allocations need to be made with gfp flags
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 2 | ||||
-rw-r--r-- | include/net/mac80211.h | 2 | ||||
-rw-r--r-- | include/net/regulatory.h | 2 | ||||
-rw-r--r-- | net/mac80211/agg-rx.c | 4 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 17 | ||||
-rw-r--r-- | net/mac80211/spectmgmt.c | 7 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 3 | ||||
-rw-r--r-- | net/wireless/mesh.c | 25 | ||||
-rw-r--r-- | net/wireless/sme.c | 2 |
11 files changed, 41 insertions, 27 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 1cf22e62e3dd..6e0af815f25e 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -3516,7 +3516,7 @@ static int __init init_mac80211_hwsim(void) | |||
3516 | 3516 | ||
3517 | spin_lock_init(&hwsim_radio_lock); | 3517 | spin_lock_init(&hwsim_radio_lock); |
3518 | 3518 | ||
3519 | hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0); | 3519 | hwsim_wq = alloc_workqueue("hwsim_wq", 0, 0); |
3520 | if (!hwsim_wq) | 3520 | if (!hwsim_wq) |
3521 | return -ENOMEM; | 3521 | return -ENOMEM; |
3522 | rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params); | 3522 | rhashtable_init(&hwsim_radios_rht, &hwsim_rht_params); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 906e90223066..c96511fa9198 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -4149,7 +4149,7 @@ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid); | |||
4149 | * The TX headroom reserved by mac80211 for its own tx_status functions. | 4149 | * The TX headroom reserved by mac80211 for its own tx_status functions. |
4150 | * This is enough for the radiotap header. | 4150 | * This is enough for the radiotap header. |
4151 | */ | 4151 | */ |
4152 | #define IEEE80211_TX_STATUS_HEADROOM 14 | 4152 | #define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4) |
4153 | 4153 | ||
4154 | /** | 4154 | /** |
4155 | * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames | 4155 | * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames |
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index ebc5a2ed8631..f83cacce3308 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h | |||
@@ -78,7 +78,7 @@ struct regulatory_request { | |||
78 | int wiphy_idx; | 78 | int wiphy_idx; |
79 | enum nl80211_reg_initiator initiator; | 79 | enum nl80211_reg_initiator initiator; |
80 | enum nl80211_user_reg_hint_type user_reg_hint_type; | 80 | enum nl80211_user_reg_hint_type user_reg_hint_type; |
81 | char alpha2[2]; | 81 | char alpha2[3]; |
82 | enum nl80211_dfs_regions dfs_region; | 82 | enum nl80211_dfs_regions dfs_region; |
83 | bool intersect; | 83 | bool intersect; |
84 | bool processed; | 84 | bool processed; |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a8b1616cec41..1f3188d03840 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright 2007-2010, Intel Corporation | 9 | * Copyright 2007-2010, Intel Corporation |
10 | * Copyright(c) 2015-2017 Intel Deutschland GmbH | 10 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
11 | * Copyright (C) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
@@ -304,9 +305,6 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta, | |||
304 | * driver so reject the timeout update. | 305 | * driver so reject the timeout update. |
305 | */ | 306 | */ |
306 | status = WLAN_STATUS_REQUEST_DECLINED; | 307 | status = WLAN_STATUS_REQUEST_DECLINED; |
307 | ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, | ||
308 | tid, dialog_token, status, | ||
309 | 1, buf_size, timeout); | ||
310 | goto end; | 308 | goto end; |
311 | } | 309 | } |
312 | 310 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 46028e12e216..f4195a0f0279 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2892,7 +2892,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) | |||
2892 | } | 2892 | } |
2893 | if (beacon->probe_resp_len) { | 2893 | if (beacon->probe_resp_len) { |
2894 | new_beacon->probe_resp_len = beacon->probe_resp_len; | 2894 | new_beacon->probe_resp_len = beacon->probe_resp_len; |
2895 | beacon->probe_resp = pos; | 2895 | new_beacon->probe_resp = pos; |
2896 | memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); | 2896 | memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); |
2897 | pos += beacon->probe_resp_len; | 2897 | pos += beacon->probe_resp_len; |
2898 | } | 2898 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 26900025de2f..ae9c33cd8ada 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1467,7 +1467,7 @@ struct ieee802_11_elems { | |||
1467 | const struct ieee80211_timeout_interval_ie *timeout_int; | 1467 | const struct ieee80211_timeout_interval_ie *timeout_int; |
1468 | const u8 *opmode_notif; | 1468 | const u8 *opmode_notif; |
1469 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | 1469 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; |
1470 | const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; | 1470 | struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; |
1471 | const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie; | 1471 | const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie; |
1472 | 1472 | ||
1473 | /* length of them, respectively */ | 1473 | /* length of them, respectively */ |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 73ac607beb5d..6a381cbe1e33 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -1255,13 +1255,12 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, | |||
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | 1257 | static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, |
1258 | struct ieee80211_mgmt *mgmt, size_t len) | 1258 | struct ieee80211_mgmt *mgmt, size_t len, |
1259 | struct ieee802_11_elems *elems) | ||
1259 | { | 1260 | { |
1260 | struct ieee80211_mgmt *mgmt_fwd; | 1261 | struct ieee80211_mgmt *mgmt_fwd; |
1261 | struct sk_buff *skb; | 1262 | struct sk_buff *skb; |
1262 | struct ieee80211_local *local = sdata->local; | 1263 | struct ieee80211_local *local = sdata->local; |
1263 | u8 *pos = mgmt->u.action.u.chan_switch.variable; | ||
1264 | size_t offset_ttl; | ||
1265 | 1264 | ||
1266 | skb = dev_alloc_skb(local->tx_headroom + len); | 1265 | skb = dev_alloc_skb(local->tx_headroom + len); |
1267 | if (!skb) | 1266 | if (!skb) |
@@ -1269,13 +1268,9 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
1269 | skb_reserve(skb, local->tx_headroom); | 1268 | skb_reserve(skb, local->tx_headroom); |
1270 | mgmt_fwd = skb_put(skb, len); | 1269 | mgmt_fwd = skb_put(skb, len); |
1271 | 1270 | ||
1272 | /* offset_ttl is based on whether the secondary channel | 1271 | elems->mesh_chansw_params_ie->mesh_ttl--; |
1273 | * offset is available or not. Subtract 1 from the mesh TTL | 1272 | elems->mesh_chansw_params_ie->mesh_flags &= |
1274 | * and disable the initiator flag before forwarding. | 1273 | ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; |
1275 | */ | ||
1276 | offset_ttl = (len < 42) ? 7 : 10; | ||
1277 | *(pos + offset_ttl) -= 1; | ||
1278 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | ||
1279 | 1274 | ||
1280 | memcpy(mgmt_fwd, mgmt, len); | 1275 | memcpy(mgmt_fwd, mgmt, len); |
1281 | eth_broadcast_addr(mgmt_fwd->da); | 1276 | eth_broadcast_addr(mgmt_fwd->da); |
@@ -1323,7 +1318,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
1323 | 1318 | ||
1324 | /* forward or re-broadcast the CSA frame */ | 1319 | /* forward or re-broadcast the CSA frame */ |
1325 | if (fwd_csa) { | 1320 | if (fwd_csa) { |
1326 | if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0) | 1321 | if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0) |
1327 | mcsa_dbg(sdata, "Failed to forward the CSA frame"); | 1322 | mcsa_dbg(sdata, "Failed to forward the CSA frame"); |
1328 | } | 1323 | } |
1329 | } | 1324 | } |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index ee0181778a42..029334835747 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright 2007-2008, Intel Corporation | 9 | * Copyright 2007-2008, Intel Corporation |
10 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | 10 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
11 | * Copyright (C) 2018 Intel Corporation | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | 14 | * it under the terms of the GNU General Public License version 2 as |
@@ -27,7 +28,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
27 | u32 sta_flags, u8 *bssid, | 28 | u32 sta_flags, u8 *bssid, |
28 | struct ieee80211_csa_ie *csa_ie) | 29 | struct ieee80211_csa_ie *csa_ie) |
29 | { | 30 | { |
30 | enum nl80211_band new_band; | 31 | enum nl80211_band new_band = current_band; |
31 | int new_freq; | 32 | int new_freq; |
32 | u8 new_chan_no; | 33 | u8 new_chan_no; |
33 | struct ieee80211_channel *new_chan; | 34 | struct ieee80211_channel *new_chan; |
@@ -55,15 +56,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
55 | elems->ext_chansw_ie->new_operating_class, | 56 | elems->ext_chansw_ie->new_operating_class, |
56 | &new_band)) { | 57 | &new_band)) { |
57 | sdata_info(sdata, | 58 | sdata_info(sdata, |
58 | "cannot understand ECSA IE operating class %d, disconnecting\n", | 59 | "cannot understand ECSA IE operating class, %d, ignoring\n", |
59 | elems->ext_chansw_ie->new_operating_class); | 60 | elems->ext_chansw_ie->new_operating_class); |
60 | return -EINVAL; | ||
61 | } | 61 | } |
62 | new_chan_no = elems->ext_chansw_ie->new_ch_num; | 62 | new_chan_no = elems->ext_chansw_ie->new_ch_num; |
63 | csa_ie->count = elems->ext_chansw_ie->count; | 63 | csa_ie->count = elems->ext_chansw_ie->count; |
64 | csa_ie->mode = elems->ext_chansw_ie->mode; | 64 | csa_ie->mode = elems->ext_chansw_ie->mode; |
65 | } else if (elems->ch_switch_ie) { | 65 | } else if (elems->ch_switch_ie) { |
66 | new_band = current_band; | ||
67 | new_chan_no = elems->ch_switch_ie->new_ch_num; | 66 | new_chan_no = elems->ch_switch_ie->new_ch_num; |
68 | csa_ie->count = elems->ch_switch_ie->count; | 67 | csa_ie->count = elems->ch_switch_ie->count; |
69 | csa_ie->mode = elems->ch_switch_ie->mode; | 68 | csa_ie->mode = elems->ch_switch_ie->mode; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 0c5627f8a104..af0b608ee8ed 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -314,7 +314,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
314 | 314 | ||
315 | if (ieee80211_hw_check(hw, USES_RSS)) { | 315 | if (ieee80211_hw_check(hw, USES_RSS)) { |
316 | sta->pcpu_rx_stats = | 316 | sta->pcpu_rx_stats = |
317 | alloc_percpu(struct ieee80211_sta_rx_stats); | 317 | alloc_percpu_gfp(struct ieee80211_sta_rx_stats, gfp); |
318 | if (!sta->pcpu_rx_stats) | 318 | if (!sta->pcpu_rx_stats) |
319 | goto free; | 319 | goto free; |
320 | } | 320 | } |
@@ -433,6 +433,7 @@ free_txq: | |||
433 | if (sta->sta.txq[0]) | 433 | if (sta->sta.txq[0]) |
434 | kfree(to_txq_info(sta->sta.txq[0])); | 434 | kfree(to_txq_info(sta->sta.txq[0])); |
435 | free: | 435 | free: |
436 | free_percpu(sta->pcpu_rx_stats); | ||
436 | #ifdef CONFIG_MAC80211_MESH | 437 | #ifdef CONFIG_MAC80211_MESH |
437 | kfree(sta->mesh); | 438 | kfree(sta->mesh); |
438 | #endif | 439 | #endif |
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c index 51aa55618ef7..b12da6ef3c12 100644 --- a/net/wireless/mesh.c +++ b/net/wireless/mesh.c | |||
@@ -170,9 +170,28 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | |||
170 | enum nl80211_bss_scan_width scan_width; | 170 | enum nl80211_bss_scan_width scan_width; |
171 | struct ieee80211_supported_band *sband = | 171 | struct ieee80211_supported_band *sband = |
172 | rdev->wiphy.bands[setup->chandef.chan->band]; | 172 | rdev->wiphy.bands[setup->chandef.chan->band]; |
173 | scan_width = cfg80211_chandef_to_scan_width(&setup->chandef); | 173 | |
174 | setup->basic_rates = ieee80211_mandatory_rates(sband, | 174 | if (setup->chandef.chan->band == NL80211_BAND_2GHZ) { |
175 | scan_width); | 175 | int i; |
176 | |||
177 | /* | ||
178 | * Older versions selected the mandatory rates for | ||
179 | * 2.4 GHz as well, but were broken in that only | ||
180 | * 1 Mbps was regarded as a mandatory rate. Keep | ||
181 | * using just 1 Mbps as the default basic rate for | ||
182 | * mesh to be interoperable with older versions. | ||
183 | */ | ||
184 | for (i = 0; i < sband->n_bitrates; i++) { | ||
185 | if (sband->bitrates[i].bitrate == 10) { | ||
186 | setup->basic_rates = BIT(i); | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | } else { | ||
191 | scan_width = cfg80211_chandef_to_scan_width(&setup->chandef); | ||
192 | setup->basic_rates = ieee80211_mandatory_rates(sband, | ||
193 | scan_width); | ||
194 | } | ||
176 | } | 195 | } |
177 | 196 | ||
178 | err = cfg80211_chandef_dfs_required(&rdev->wiphy, | 197 | err = cfg80211_chandef_dfs_required(&rdev->wiphy, |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index fdb3646274a5..701cfd7acc1b 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -1032,6 +1032,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
1032 | wdev->current_bss = NULL; | 1032 | wdev->current_bss = NULL; |
1033 | wdev->ssid_len = 0; | 1033 | wdev->ssid_len = 0; |
1034 | wdev->conn_owner_nlportid = 0; | 1034 | wdev->conn_owner_nlportid = 0; |
1035 | kzfree(wdev->connect_keys); | ||
1036 | wdev->connect_keys = NULL; | ||
1035 | 1037 | ||
1036 | nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); | 1038 | nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); |
1037 | 1039 | ||