wifi: cfg80211: restrict operation during radar detection
authorJohannes Berg <johannes.berg@intel.com>
Mon, 6 May 2024 19:11:59 +0000 (21:11 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 23 May 2024 09:28:48 +0000 (11:28 +0200)
Just like it's not currently possible to start radar
detection while already operating, it shouldn't be
possible to start operating while radar detection is
running. Fix that.

Also, improve the check whether operating (carrier
might not be up if e.g. attempting to join IBSS).

Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240506211158.ae8dca3d0d6c.I7c70a66a5fbdbc63a78fee8a34f31d1995491bc3@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/ibss.c
net/wireless/mesh.c
net/wireless/nl80211.c

index 9f02ee5f08beb40a83f6133f22c5f90343cdf442..34e5acff393510f5622d8891f68a1dd0bf3ab27e 100644 (file)
@@ -3,7 +3,7 @@
  * Some IBSS support code for cfg80211.
  *
  * Copyright 2009      Johannes Berg <johannes@sipsolutions.net>
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #include <linux/etherdevice.h>
@@ -94,6 +94,9 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 
        lockdep_assert_held(&rdev->wiphy.mtx);
 
+       if (wdev->cac_started)
+               return -EBUSY;
+
        if (wdev->u.ibss.ssid_len)
                return -EALREADY;
 
index 83306979fbe21894d51ea117b2c077635e076f58..aaca65b66af48e2c27c748c971265304d402e305 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Portions
- * Copyright (C) 2022-2023 Intel Corporation
+ * Copyright (C) 2022-2024 Intel Corporation
  */
 #include <linux/ieee80211.h>
 #include <linux/export.h>
@@ -127,6 +127,9 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
        if (!rdev->ops->join_mesh)
                return -EOPNOTSUPP;
 
+       if (wdev->cac_started)
+               return -EBUSY;
+
        if (!setup->chandef.chan) {
                /* if no channel explicitly given, use preset channel */
                setup->chandef = wdev->u.mesh.preset_chandef;
index 93c313149f571bba9babd926a8b55b02cdcbf737..6ba988a6f5a22b0710d1fc2274c1f7c91f3907a7 100644 (file)
@@ -5964,6 +5964,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
        if (!rdev->ops->start_ap)
                return -EOPNOTSUPP;
 
+       if (wdev->cac_started)
+               return -EBUSY;
+
        if (wdev->links[link_id].ap.beacon_interval)
                return -EALREADY;
 
@@ -9956,6 +9959,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
 
        flush_delayed_work(&rdev->dfs_update_channels_wk);
 
+       switch (wdev->iftype) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_P2P_GO:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_ADHOC:
+               break;
+       default:
+               /* caution - see cfg80211_beaconing_iface_active() below */
+               return -EINVAL;
+       }
+
        wiphy_lock(wiphy);
 
        dfs_region = reg_get_dfs_region(wiphy);
@@ -9986,12 +10000,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
                goto unlock;
        }
 
-       if (netif_carrier_ok(dev)) {
-               err = -EBUSY;
-               goto unlock;
-       }
-
-       if (wdev->cac_started) {
+       if (cfg80211_beaconing_iface_active(wdev) || wdev->cac_started) {
                err = -EBUSY;
                goto unlock;
        }