]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: Get the correct interface for non-netdev skb status
authorIlan Peer <ilan.peer@intel.com>
Mon, 8 Sep 2025 11:13:05 +0000 (14:13 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 19 Sep 2025 09:26:23 +0000 (11:26 +0200)
The function ieee80211_sdata_from_skb() always returned the P2P Device
interface in case the skb was not associated with a netdev and didn't
consider the possibility that an NAN Device interface is also enabled.

To support configurations where both P2P Device and a NAN Device
interface are active, extend the function to match the correct
interface based on address 2 in the 802.11 MAC header.

Since the 'p2p_sdata' field in struct ieee80211_local is no longer
needed, remove it.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250908140015.5252d2579a49.Id4576531c6b2ad83c9498b708dc0ade6b0214fa8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/status.c

index 48e1ba919fbaf0f94a5c58fd10d4a6e9579cbe3d..242cb109b232da23087d99be0e959b6ea7167257 100644 (file)
@@ -1676,8 +1676,6 @@ struct ieee80211_local {
        struct idr ack_status_frames;
        spinlock_t ack_status_lock;
 
-       struct ieee80211_sub_if_data __rcu *p2p_sdata;
-
        /* virtual monitor interface */
        struct ieee80211_sub_if_data __rcu *monitor_sdata;
        struct ieee80211_chan_req monitor_chanreq;
index 4a9175d9f51c6f4bd45bbb7e477240a6cc6f7e1d..a7873832d4fa68792ee1503a4c780d3bf46327f6 100644 (file)
@@ -620,10 +620,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 
                spin_unlock_bh(&sdata->u.nan.func_lock);
                break;
-       case NL80211_IFTYPE_P2P_DEVICE:
-               /* relies on synchronize_rcu() below */
-               RCU_INIT_POINTER(local->p2p_sdata, NULL);
-               fallthrough;
        default:
                wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work);
                /*
@@ -1414,6 +1410,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                ieee80211_recalc_idle(local);
 
                netif_carrier_on(dev);
+               list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
                break;
        default:
                if (coming_up) {
@@ -1477,17 +1474,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                        sdata->vif.type != NL80211_IFTYPE_STATION);
        }
 
-       switch (sdata->vif.type) {
-       case NL80211_IFTYPE_P2P_DEVICE:
-               rcu_assign_pointer(local->p2p_sdata, sdata);
-               break;
-       case NL80211_IFTYPE_MONITOR:
-               list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
-               break;
-       default:
-               break;
-       }
-
        /*
         * set_multicast_list will be invoked by the networking core
         * which will check whether any increments here were done in
index a362254b310cd54c01534c8e1d081bbec1e9d816..4b38aa0e902a85be6af9b3a02d95803087295b1a 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright 2021-2024  Intel Corporation
+ * Copyright 2021-2025  Intel Corporation
  */
 
 #include <linux/export.h>
@@ -572,6 +572,7 @@ static struct ieee80211_sub_if_data *
 ieee80211_sdata_from_skb(struct ieee80211_local *local, struct sk_buff *skb)
 {
        struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_hdr *hdr = (void *)skb->data;
 
        if (skb->dev) {
                list_for_each_entry_rcu(sdata, &local->interfaces, list) {
@@ -585,7 +586,23 @@ ieee80211_sdata_from_skb(struct ieee80211_local *local, struct sk_buff *skb)
                return NULL;
        }
 
-       return rcu_dereference(local->p2p_sdata);
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+               switch (sdata->vif.type) {
+               case NL80211_IFTYPE_P2P_DEVICE:
+                       break;
+               case NL80211_IFTYPE_NAN:
+                       if (sdata->u.nan.started)
+                               break;
+                       fallthrough;
+               default:
+                       continue;
+               }
+
+               if (ether_addr_equal(sdata->vif.addr, hdr->addr2))
+                       return sdata;
+       }
+
+       return NULL;
 }
 
 static void ieee80211_report_ack_skb(struct ieee80211_local *local,