wifi: mac80211: Get the correct interface for non-netdev skb status

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>
This commit is contained in:
Ilan Peer
2025-09-08 14:13:05 +03:00
committed by Johannes Berg
parent 8f79d2f13d
commit c7b5355b37
3 changed files with 20 additions and 19 deletions

View 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;

View 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

View 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,