mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
wifi: cfg80211: validate monitor channel set against radio usage
Current logic only looks globally at interface counts to validate that a monitor can have its channel configured. This works to ensure that the wiphy is not pulled off the channel currently being used by another active interface, but fails to allow for the case where the channels in use on the other active interface and the desired channel for the monitor fall on disjoint sets of radios. Instead, search for any interface which would cause conflict, otherwise allowing for the configuration. Suggested-by: Dylan Eskew <dylan.eskew@candelatech.com> Signed-off-by: Rory Little <roryl@candelatech.com> Link: https://patch.msgid.link/20260921210441.3137-1-roryl@candelatech.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
e01f1c70e4
commit
12bc27e79a
|
|
@ -1810,13 +1810,44 @@ bool cfg80211_reg_check_beaconing(struct wiphy *wiphy,
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_reg_check_beaconing);
|
||||
|
||||
static bool cfg80211_can_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct wireless_dev *wdev;
|
||||
int radio_idx;
|
||||
|
||||
lockdep_assert_held(&rdev->wiphy.mtx);
|
||||
|
||||
if (rdev->num_running_monitor_ifaces < 1)
|
||||
return false;
|
||||
|
||||
if (cfg80211_has_monitors_only(rdev))
|
||||
return true;
|
||||
|
||||
radio_idx = cfg80211_get_radio_idx_by_chan(&rdev->wiphy, chandef->chan);
|
||||
/* No defined radio covers this channel. Fall back on global behavior */
|
||||
if (radio_idx < 0)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->iftype == NL80211_IFTYPE_MONITOR)
|
||||
continue;
|
||||
if (!wdev->netdev)
|
||||
continue;
|
||||
if (rdev_get_radio_mask(rdev, wdev->netdev) & BIT(radio_idx))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
if (!rdev->ops->set_monitor_channel)
|
||||
return -EOPNOTSUPP;
|
||||
if (!cfg80211_has_monitors_only(rdev))
|
||||
if (!cfg80211_can_set_monitor_channel(rdev, chandef))
|
||||
return -EBUSY;
|
||||
|
||||
return rdev_set_monitor_channel(rdev, dev, chandef);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user