diff mbox series

wifi: mac80211: Add counter for all monitor interfaces

Message ID 20250220094139.61459-1-Alexander@wetzel-home.de (mailing list archive)
State New
Delegated to: Johannes Berg
Headers show
Series wifi: mac80211: Add counter for all monitor interfaces | expand

Checks

Context Check Description
jmberg/tree_selection success Series ignored based on subject

Commit Message

Alexander Wetzel Feb. 20, 2025, 9:41 a.m. UTC
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: 286e69677065 ("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>
---
This should fix the issue from the Reported-by above.
I can't verify that myself, though. Can you confirm that solves the
issue?

Alexander
---
 net/mac80211/cfg.c         |  5 ++---
 net/mac80211/ethtool.c     |  2 +-
 net/mac80211/ieee80211_i.h |  2 +-
 net/mac80211/iface.c       | 22 +++++++++++++---------
 net/mac80211/util.c        |  3 ++-
 5 files changed, 19 insertions(+), 15 deletions(-)

Comments

Karthikeyan Periyasamy Feb. 21, 2025, 4:30 a.m. UTC | #1
On 2/20/2025 3:11 PM, Alexander Wetzel wrote:
> 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: 286e69677065 ("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>
> ---
> This should fix the issue from the Reported-by above.
> I can't verify that myself, though. Can you confirm that solves the
> issue?
> 

Yes its working, no problem so far.


Tested-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
diff mbox series

Patch

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5785fe30adaa..09708a060bb7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -4370,9 +4370,8 @@  static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
 	if (chanctx_conf) {
 		*chandef = link->conf->chanreq.oper;
 		ret = 0;
-	} else if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
-		   local->open_count > 0 &&
-		   local->open_count == local->monitors &&
+	} else if (local->open_count > 0 &&
+		   local->open_count == local->virt_monitors &&
 		   sdata->vif.type == NL80211_IFTYPE_MONITOR) {
 		*chandef = local->monitor_chanreq.oper;
 		ret = 0;
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c
index 42f7ee142ce3..0397755a3bd1 100644
--- a/net/mac80211/ethtool.c
+++ b/net/mac80211/ethtool.c
@@ -158,7 +158,7 @@  static void ieee80211_get_stats(struct net_device *dev,
 	if (chanctx_conf)
 		channel = chanctx_conf->def.chan;
 	else if (local->open_count > 0 &&
-		 local->open_count == local->monitors &&
+		 local->open_count == local->virt_monitors &&
 		 sdata->vif.type == NL80211_IFTYPE_MONITOR)
 		channel = local->monitor_chanreq.oper.chan;
 	else
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f23be8b5d0d8..845888ac3d2c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1384,7 +1384,7 @@  struct ieee80211_local {
 	spinlock_t queue_stop_reason_lock;
 
 	int open_count;
-	int monitors, tx_mntrs;
+	int monitors, virt_monitors, tx_mntrs;
 	/* number of interfaces with corresponding FIF_ flags */
 	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
 	    fif_probe_req;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 77d0078616fb..b0423046028c 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -582,11 +582,13 @@  static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 		/* no need to tell driver */
 		break;
 	case NL80211_IFTYPE_MONITOR:
+		local->monitors--;
+
 		if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
 		    !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
 
-			local->monitors--;
-			if (local->monitors == 0) {
+			local->virt_monitors--;
+			if (local->virt_monitors == 0) {
 				local->hw.conf.flags &= ~IEEE80211_CONF_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:
 		break;
 	case NL80211_IFTYPE_MONITOR:
-		if (local->monitors == 0)
+		if (local->virt_monitors == 0)
 			ieee80211_del_virtual_monitor(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_hw_config(local, hw_reconf_flags);
 
-	if (local->monitors == local->open_count)
+	if (local->virt_monitors == local->open_count)
 		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)
 			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
 
-		if (local->monitors)
+		if (local->virt_monitors)
 			flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
 	} else {
 		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)) {
 		flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
 
-		if (local->monitors &&
+		if (local->virt_monitors &&
 		    !ieee80211_hw_check(&local->hw, SUPPORTS_CONC_MON_RX_DECAP))
 			flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
 	} else {
@@ -1333,20 +1335,22 @@  int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 			if (res)
 				goto err_stop;
 		} else {
-			if (local->monitors == 0 && local->open_count == 0) {
+			if (local->virt_monitors == 0 && local->open_count == 0) {
 				res = ieee80211_add_virtual_monitor(local);
 				if (res)
 					goto err_stop;
 			}
-			local->monitors++;
+			local->virt_monitors++;
 
 			/* 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;
 				hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
 			}
 		}
 
+		local->monitors++;
+
 		ieee80211_adjust_monitor_flags(sdata, 1);
 		ieee80211_configure_filter(local);
 		ieee80211_recalc_offload(local);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7f02bd5891eb..e2680589254f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2156,7 +2156,8 @@  int ieee80211_reconfig(struct ieee80211_local *local)
 
  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);
 
 	/*