diff mbox series

[wireless-next,RFC,v2,2/2] wifi: mac80211: process group addressed Rx data and mgmt packets on intended interface

Message ID 20250505113619.3654343-3-maharaja.kennadyrajan@oss.qualcomm.com
State New
Headers show
Series wifi: mac80211: Fix Rx packet handling in multi-radio devices | expand

Commit Message

Maharaja Kennadyrajan May 5, 2025, 11:36 a.m. UTC
Currently, in multi-radio devices, group-addressed data and management
frames received on one band are getting processed on an interface running
on a different band. This occurs because these frames do not have the
destination station information, unlike unicast Rx frame processing where
the transmitting station is known.

There is no check to ensure that the sdata is running on the same band as
the frames are received on before processing those frames.

Fix this by checking the operating frequency of the interface against the
frequency of the packets received before forwarding them to the interface
in multi-radio devices.

The current behavior is retained as a fallback mechanism when the frequency
is not reported by the drivers.

Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com>
---
 net/mac80211/rx.c | 48 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 40 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 09beb65d6108..59028c08dd52 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -5125,6 +5125,30 @@  static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx,
 	return ieee80211_prepare_and_rx_handle(rx, skb, consume);
 }
 
+static bool
+ieee80211_rx_is_sdata_match(struct ieee80211_sub_if_data *sdata,
+			    int freq)
+{
+	struct ieee80211_link_data *link;
+	struct ieee80211_bss_conf *bss_conf;
+	struct ieee80211_chanctx_conf *conf;
+
+	if (!freq)
+		return true;
+
+	for_each_link_data(sdata, link) {
+		bss_conf = link->conf;
+		if (!bss_conf)
+			continue;
+		conf = rcu_dereference(bss_conf->chanctx_conf);
+		if (conf && conf->def.chan &&
+		    conf->def.chan->center_freq == freq)
+			return true;
+	}
+
+	return false;
+}
+
 /*
  * This is the actual Rx frames handler. as it belongs to Rx path it must
  * be called with rcu_read_lock protection.
@@ -5264,18 +5288,26 @@  static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 		 * the loop to avoid copying the SKB once too much
 		 */
 
-		if (!prev) {
-			prev = sdata;
-			continue;
-		}
+		/* Process the group addressed management and data packets
+		 * in the intended interface when the operating frequency
+		 * matches with rx_status->freq in multi-radio devices.
+		 * If rx_status->freq is not set by the driver, then
+		 * follow the existing code flow.
+		 */
 
-		rx.sdata = prev;
-		ieee80211_rx_for_interface(&rx, skb, false);
+		if (ieee80211_rx_is_sdata_match(sdata, status->freq)) {
+			if (!prev) {
+				prev = sdata;
+				continue;
+			}
 
-		prev = sdata;
+			rx.sdata = prev;
+			ieee80211_rx_for_interface(&rx, skb, false);
+			prev = sdata;
+		}
 	}
 
-	if (prev) {
+	if (prev && ieee80211_rx_is_sdata_match(prev, status->freq)) {
 		rx.sdata = prev;
 
 		if (ieee80211_rx_for_interface(&rx, skb, true))