[RFC PATCH 15/23] nl80211: Factor out global event BSS lookup and prefer PD BSS by wdev

Peddolla Harshavardhan Reddy peddolla.reddy at oss.qualcomm.com
Tue Mar 31 22:48:53 PDT 2026


From: Veerendranath Jakkam <vjakkam at qti.qualcomm.com>

Introduce nl80211_get_event_bss() to centralize BSS selection for
process_global_event(). The helper first tries an exact ifindex match,
then uses nl80211_get_pd_bss_by_wdev() so that events with a wdev_id
are delivered to the correct P2P Device (PD) BSS, and finally falls
back to the existing bridge/wiphy/wdev matching rules.

This avoids duplicating the lookup logic, ensures PD BSS instances are
used when appropriate, and keeps existing behavior for wiphy-wide and
global events.

Signed-off-by: Veerendranath Jakkam <vjakkam at qti.qualcomm.com>
---
 src/drivers/driver_nl80211_event.c | 91 +++++++++++++++---------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 2fa6e9728..d71b06d5f 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -4585,13 +4585,48 @@ static bool nl80211_drv_in_list(struct nl80211_global *global,
 }
 
 
+static struct i802_bss *
+nl80211_get_event_bss(struct wpa_driver_nl80211_data *drv, int ifidx,
+		      int wiphy_idx_rx, int wiphy_idx_set,
+		      u64 wdev_id, int wdev_id_set)
+{
+	struct i802_bss *bss;
+	int wiphy_idx = -1;
+
+	if (ifidx != -1) {
+		for (bss = drv->first_bss; bss; bss = bss->next) {
+			if (ifidx == bss->ifindex)
+				return bss;
+		}
+	}
+
+	bss = nl80211_get_pd_bss_by_wdev(drv, wdev_id, wdev_id_set);
+	if (bss)
+		return bss;
+
+	for (bss = drv->first_bss; bss; bss = bss->next) {
+		if (wiphy_idx_set)
+			wiphy_idx = nl80211_get_wiphy_index(bss);
+		if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
+		    (bss->br_ifindex > 0 &&
+		     nl80211_has_ifidx(drv, bss->br_ifindex, ifidx)) ||
+		    (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
+		    (wdev_id_set && bss->wdev_id_set &&
+		     wdev_id == bss->wdev_id))
+			return bss;
+	}
+
+	return NULL;
+}
+
+
 int process_global_event(struct nl_msg *msg, void *arg)
 {
 	struct nl80211_global *global = arg;
 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
 	struct wpa_driver_nl80211_data *drv, *tmp;
-	int ifidx = -1, wiphy_idx = -1, wiphy_idx_rx = -1;
+	int ifidx = -1, wiphy_idx_rx = -1;
 	struct i802_bss *bss;
 	u64 wdev_id = 0;
 	int wdev_id_set = 0;
@@ -4644,50 +4679,18 @@ int process_global_event(struct nl_msg *msg, void *arg)
 			      struct wpa_driver_nl80211_data, list) {
 		unsigned int unique_drv_id = drv->unique_drv_id;
 
-		/* First pass: Check for exact ifindex match for events directed
-		 * to a specific interface to avoid incorrect selection based on
-		 * matching rules for bridged interfaces. */
-		if (ifidx != -1) {
-			for (bss = drv->first_bss; bss; bss = bss->next) {
-				if (ifidx == bss->ifindex) {
-					do_process_drv_event(bss, gnlh->cmd,
-							     tb);
-					return NL_SKIP;
-				}
-			}
-		}
+		bss = nl80211_get_event_bss(drv, ifidx, wiphy_idx_rx,
+					    wiphy_idx_set, wdev_id,
+					    wdev_id_set);
+		if (!bss)
+			continue;
 
-		/* Second pass: Check all other conditions including bridge */
-		for (bss = drv->first_bss; bss; bss = bss->next) {
-			if (wiphy_idx_set)
-				wiphy_idx = nl80211_get_wiphy_index(bss);
-			if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
-			    (bss->br_ifindex > 0 &&
-			     nl80211_has_ifidx(drv, bss->br_ifindex, ifidx)) ||
-			    (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
-			    (wdev_id_set && bss->wdev_id_set &&
-			     wdev_id == bss->wdev_id)) {
-				processed = true;
-				do_process_drv_event(bss, gnlh->cmd, tb);
-				/* There are two types of events that may need
-				 * to be delivered to multiple interfaces:
-				 * 1. Events for a wiphy, as it can have
-				 * multiple interfaces.
-				 * 2. "Global" events, like
-				 * NL80211_CMD_REG_CHANGE.
-				 *
-				 * Terminate early only if the event is directed
-				 * to a specific interface or wdev. */
-				if (ifidx != -1 || wdev_id_set)
-					return NL_SKIP;
-				/* The driver instance could have been removed,
-				 * e.g., due to NL80211_CMD_RADAR_DETECT event,
-				 * so need to stop the loop if that has
-				 * happened. */
-				if (!nl80211_drv_in_list(global, unique_drv_id))
-					break;
-			}
-		}
+		processed = true;
+		do_process_drv_event(bss, gnlh->cmd, tb);
+		if (ifidx != -1 || wdev_id_set)
+			return NL_SKIP;
+		if (!nl80211_drv_in_list(global, unique_drv_id))
+			break;
 	}
 
 	if (processed)
-- 
2.34.1




More information about the Hostap mailing list