mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
wifi: mac80211: Add counter for all monitor interfaces
Count open monitor interfaces regardless of the monitor interface type.
The new counter virt_monitors takes over counting interfaces depending
on the virtual monitor interface while monitors is used for all active
monitor interfaces.
This fixes monitor packet mirroring when using MONITOR_FLAG_ACTIVE or
NO_VIRTUAL_MONITOR interfaces.
Fixes: 286e696770
("wifi: mac80211: Drop cooked monitor support")
Reported-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Closes: https://lore.kernel.org/r/cc715114-4e3b-619a-49dc-a4878075e1dc@quicinc.com
Signed-off-by: Alexander Wetzel <Alexander@wetzel-home.de>
Tested-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Link: https://patch.msgid.link/20250220094139.61459-1-Alexander@wetzel-home.de
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
cf6b9ba172
commit
129860044c
5 changed files with 19 additions and 15 deletions
|
@ -4370,9 +4370,8 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
|
||||||
if (chanctx_conf) {
|
if (chanctx_conf) {
|
||||||
*chandef = link->conf->chanreq.oper;
|
*chandef = link->conf->chanreq.oper;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
|
} else if (local->open_count > 0 &&
|
||||||
local->open_count > 0 &&
|
local->open_count == local->virt_monitors &&
|
||||||
local->open_count == local->monitors &&
|
|
||||||
sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
sdata->vif.type == NL80211_IFTYPE_MONITOR) {
|
||||||
*chandef = local->monitor_chanreq.oper;
|
*chandef = local->monitor_chanreq.oper;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
|
@ -158,7 +158,7 @@ do_survey:
|
||||||
if (chanctx_conf)
|
if (chanctx_conf)
|
||||||
channel = chanctx_conf->def.chan;
|
channel = chanctx_conf->def.chan;
|
||||||
else if (local->open_count > 0 &&
|
else if (local->open_count > 0 &&
|
||||||
local->open_count == local->monitors &&
|
local->open_count == local->virt_monitors &&
|
||||||
sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
||||||
channel = local->monitor_chanreq.oper.chan;
|
channel = local->monitor_chanreq.oper.chan;
|
||||||
else
|
else
|
||||||
|
|
|
@ -1384,7 +1384,7 @@ struct ieee80211_local {
|
||||||
spinlock_t queue_stop_reason_lock;
|
spinlock_t queue_stop_reason_lock;
|
||||||
|
|
||||||
int open_count;
|
int open_count;
|
||||||
int monitors, tx_mntrs;
|
int monitors, virt_monitors, tx_mntrs;
|
||||||
/* number of interfaces with corresponding FIF_ flags */
|
/* number of interfaces with corresponding FIF_ flags */
|
||||||
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
|
int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
|
||||||
fif_probe_req;
|
fif_probe_req;
|
||||||
|
|
|
@ -582,11 +582,13 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
|
||||||
/* no need to tell driver */
|
/* no need to tell driver */
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
|
local->monitors--;
|
||||||
|
|
||||||
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
|
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
|
||||||
!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
|
||||||
|
|
||||||
local->monitors--;
|
local->virt_monitors--;
|
||||||
if (local->monitors == 0) {
|
if (local->virt_monitors == 0) {
|
||||||
local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
|
local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
|
||||||
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
|
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +685,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
|
||||||
case NL80211_IFTYPE_AP_VLAN:
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
if (local->monitors == 0)
|
if (local->virt_monitors == 0)
|
||||||
ieee80211_del_virtual_monitor(local);
|
ieee80211_del_virtual_monitor(local);
|
||||||
|
|
||||||
ieee80211_recalc_idle(local);
|
ieee80211_recalc_idle(local);
|
||||||
|
@ -720,7 +722,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
|
||||||
ieee80211_configure_filter(local);
|
ieee80211_configure_filter(local);
|
||||||
ieee80211_hw_config(local, hw_reconf_flags);
|
ieee80211_hw_config(local, hw_reconf_flags);
|
||||||
|
|
||||||
if (local->monitors == local->open_count)
|
if (local->virt_monitors == local->open_count)
|
||||||
ieee80211_add_virtual_monitor(local);
|
ieee80211_add_virtual_monitor(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +981,7 @@ static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdat
|
||||||
local->hw.wiphy->frag_threshold != (u32)-1)
|
local->hw.wiphy->frag_threshold != (u32)-1)
|
||||||
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||||
|
|
||||||
if (local->monitors)
|
if (local->virt_monitors)
|
||||||
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||||
} else {
|
} else {
|
||||||
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||||
|
@ -989,7 +991,7 @@ static bool ieee80211_set_sdata_offload_flags(struct ieee80211_sub_if_data *sdat
|
||||||
ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
|
ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
|
||||||
flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
|
flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||||
|
|
||||||
if (local->monitors &&
|
if (local->virt_monitors &&
|
||||||
!ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))
|
!ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))
|
||||||
flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1332,20 +1334,22 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||||
if (res)
|
if (res)
|
||||||
goto err_stop;
|
goto err_stop;
|
||||||
} else {
|
} else {
|
||||||
if (local->monitors == 0 && local->open_count == 0) {
|
if (local->virt_monitors == 0 && local->open_count == 0) {
|
||||||
res = ieee80211_add_virtual_monitor(local);
|
res = ieee80211_add_virtual_monitor(local);
|
||||||
if (res)
|
if (res)
|
||||||
goto err_stop;
|
goto err_stop;
|
||||||
}
|
}
|
||||||
local->monitors++;
|
local->virt_monitors++;
|
||||||
|
|
||||||
/* must be before the call to ieee80211_configure_filter */
|
/* must be before the call to ieee80211_configure_filter */
|
||||||
if (local->monitors == 1) {
|
if (local->virt_monitors == 1) {
|
||||||
local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
|
local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
|
||||||
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
|
hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local->monitors++;
|
||||||
|
|
||||||
ieee80211_adjust_monitor_flags(sdata, 1);
|
ieee80211_adjust_monitor_flags(sdata, 1);
|
||||||
ieee80211_configure_filter(local);
|
ieee80211_configure_filter(local);
|
||||||
ieee80211_recalc_offload(local);
|
ieee80211_recalc_offload(local);
|
||||||
|
|
|
@ -2155,7 +2155,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||||
|
|
||||||
wake_up:
|
wake_up:
|
||||||
|
|
||||||
if (local->monitors == local->open_count && local->monitors > 0)
|
if (local->virt_monitors > 0 &&
|
||||||
|
local->virt_monitors == local->open_count)
|
||||||
ieee80211_add_virtual_monitor(local);
|
ieee80211_add_virtual_monitor(local);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue