]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Nov 2025 20:37:27 +0000 (15:37 -0500)
[ Upstream commit c7b5355b37a59c927b2374e9f783acd004d00960 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/status.c

index 8afa2404eaa8e3383c0021fd95861024af44e18e..140dc7e32d4aa20522c225998cfe92d4981f0d41 100644 (file)
@@ -1665,8 +1665,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 07ba68f7cd817df2085eb6dd1dbdb554be117f56..abc8cca54f4e1675b937e57d439227f003ef5f91 100644 (file)
@@ -611,10 +611,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);
                /*
@@ -1405,6 +1401,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) {
@@ -1468,17 +1465,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,