summaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-06-13 16:27:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-06-13 16:27:13 -0700
commit96144c58abe7ff767e754b5b80995f7b8846d49b (patch)
tree7fcc47090ced9be71fa35cbf5e00d0160b04a2d1 /net/wireless
parentf82e7b57b5fc48199e2f26ffafe2f96f7338ad3d (diff)
parentbc139119a1708ae3db1ebb379630f286e28d06e8 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from David Miller: 1) Fix cfg80211 deadlock, from Johannes Berg. 2) RXRPC fails to send norigications, from David Howells. 3) MPTCP RM_ADDR parsing has an off by one pointer error, fix from Geliang Tang. 4) Fix crash when using MSG_PEEK with sockmap, from Anny Hu. 5) The ucc_geth driver needs __netdev_watchdog_up exported, from Valentin Longchamp. 6) Fix hashtable memory leak in dccp, from Wang Hai. 7) Fix how nexthops are marked as FDB nexthops, from David Ahern. 8) Fix mptcp races between shutdown and recvmsg, from Paolo Abeni. 9) Fix crashes in tipc_disc_rcv(), from Tuong Lien. 10) Fix link speed reporting in iavf driver, from Brett Creeley. 11) When a channel is used for XSK and then reused again later for XSK, we forget to clear out the relevant data structures in mlx5 which causes all kinds of problems. Fix from Maxim Mikityanskiy. 12) Fix memory leak in genetlink, from Cong Wang. 13) Disallow sockmap attachments to UDP sockets, it simply won't work. From Lorenz Bauer. * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (83 commits) net: ethernet: ti: ale: fix allmulti for nu type ale net: ethernet: ti: am65-cpsw-nuss: fix ale parameters init net: atm: Remove the error message according to the atomic context bpf: Undo internal BPF_PROBE_MEM in BPF insns dump libbpf: Support pre-initializing .bss global variables tools/bpftool: Fix skeleton codegen bpf: Fix memlock accounting for sock_hash bpf: sockmap: Don't attach programs to UDP sockets bpf: tcp: Recv() should return 0 when the peer socket is closed ibmvnic: Flush existing work items before device removal genetlink: clean up family attributes allocations net: ipa: header pad field only valid for AP->modem endpoint net: ipa: program upper nibbles of sequencer type net: ipa: fix modem LAN RX endpoint id net: ipa: program metadata mask differently ionic: add pcie_print_link_status rxrpc: Fix race between incoming ACK parser and retransmitter net/mlx5: E-Switch, Fix some error pointer dereferences net/mlx5: Don't fail driver on failure to create debugfs net/mlx5e: CT: Fix ipv6 nat header rewrite actions ...
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/Kconfig2
-rw-r--r--net/wireless/core.c6
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mlme.c26
4 files changed, 27 insertions, 9 deletions
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index e9a712fb2392..faf74850a1b5 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -31,7 +31,7 @@ config CFG80211
For more information refer to documentation on the wireless wiki:
- http://wireless.kernel.org/en/developers/Documentation/cfg80211
+ https://wireless.wiki.kernel.org/en/developers/Documentation/cfg80211
When built as a module it will be called cfg80211.
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f0226ae9561c..c623d9bf5096 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -497,6 +497,8 @@ use_default_name:
INIT_WORK(&rdev->propagate_radar_detect_wk,
cfg80211_propagate_radar_detect_wk);
INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
+ INIT_WORK(&rdev->mgmt_registrations_update_wk,
+ cfg80211_mgmt_registrations_update_wk);
#ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -1047,6 +1049,7 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(&rdev->sched_scan_stop_wk);
flush_work(&rdev->propagate_radar_detect_wk);
flush_work(&rdev->propagate_cac_done_wk);
+ flush_work(&rdev->mgmt_registrations_update_wk);
#ifdef CONFIG_PM
if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
@@ -1108,7 +1111,6 @@ static void __cfg80211_unregister_wdev(struct wireless_dev *wdev, bool sync)
rdev->devlist_generation++;
cfg80211_mlme_purge_registrations(wdev);
- flush_work(&wdev->mgmt_registrations_update_wk);
switch (wdev->iftype) {
case NL80211_IFTYPE_P2P_DEVICE:
@@ -1253,8 +1255,6 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
spin_lock_init(&wdev->event_lock);
INIT_LIST_HEAD(&wdev->mgmt_registrations);
spin_lock_init(&wdev->mgmt_registrations_lock);
- INIT_WORK(&wdev->mgmt_registrations_update_wk,
- cfg80211_mgmt_registrations_update_wk);
INIT_LIST_HEAD(&wdev->pmsr_list);
spin_lock_init(&wdev->pmsr_lock);
INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index e0e5b3ee9699..67b0389fca4d 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -99,6 +99,8 @@ struct cfg80211_registered_device {
struct cfg80211_chan_def cac_done_chandef;
struct work_struct propagate_cac_done_wk;
+ struct work_struct mgmt_registrations_update_wk;
+
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __aligned(NETDEV_ALIGN);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 189334314cba..a6c61a2e6569 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -440,9 +440,15 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
ASSERT_RTNL();
+ spin_lock_bh(&wdev->mgmt_registrations_lock);
+ if (!wdev->mgmt_registrations_need_update) {
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
+ return;
+ }
+
rcu_read_lock();
list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
- list_for_each_entry_rcu(reg, &tmp->mgmt_registrations, list) {
+ list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
u32 mcast_mask = 0;
@@ -460,16 +466,23 @@ static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
}
rcu_read_unlock();
+ wdev->mgmt_registrations_need_update = 0;
+ spin_unlock_bh(&wdev->mgmt_registrations_lock);
+
rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
}
void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
{
- struct wireless_dev *wdev = container_of(wk, struct wireless_dev,
- mgmt_registrations_update_wk);
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+
+ rdev = container_of(wk, struct cfg80211_registered_device,
+ mgmt_registrations_update_wk);
rtnl_lock();
- cfg80211_mgmt_registrations_update(wdev);
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
+ cfg80211_mgmt_registrations_update(wdev);
rtnl_unlock();
}
@@ -557,6 +570,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
nreg->multicast_rx = multicast_rx;
list_add(&nreg->list, &wdev->mgmt_registrations);
}
+ wdev->mgmt_registrations_need_update = 1;
spin_unlock_bh(&wdev->mgmt_registrations_lock);
cfg80211_mgmt_registrations_update(wdev);
@@ -585,7 +599,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
list_del(&reg->list);
kfree(reg);
- schedule_work(&wdev->mgmt_registrations_update_wk);
+ wdev->mgmt_registrations_need_update = 1;
+ schedule_work(&rdev->mgmt_registrations_update_wk);
}
spin_unlock_bh(&wdev->mgmt_registrations_lock);
@@ -608,6 +623,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
list_del(&reg->list);
kfree(reg);
}
+ wdev->mgmt_registrations_need_update = 1;
spin_unlock_bh(&wdev->mgmt_registrations_lock);
cfg80211_mgmt_registrations_update(wdev);