[PATCH v4 06/20] nl80211: Route key operations to PD wdev based on own_addr

Kavita Kavita kavita.kavita at oss.qualcomm.com
Fri May 22 18:23:38 PDT 2026


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

When installing or removing keys for PD-only wdevs, the key operation
must be sent using the PD wdev_id instead of the main interface ifindex.

Add own_addr field to struct wpa_driver_set_key_params to identify the
virtual interface for the key operation. In the nl80211 driver, if
own_addr matches the active PD wdev MAC address, route the operation to
the PD BSS with ifindex = 0. Update NEW_KEY, DEL_KEY, and SET_KEY
message construction to use nl80211_cmd_msg() (wdev-based) instead of
nl80211_ifindex_msg() when operating on the PD wdev.

Populate own_addr in wpas_pr_pasn_set_keys() and
wpas_pr_pasn_clear_keys() so key install and removal are correctly
directed to the PD wdev.

Signed-off-by: Veerendranath Jakkam <vjakkam at qti.qualcomm.com>
---
 src/drivers/driver.h           |  6 ++++++
 src/drivers/driver_nl80211.c   | 21 ++++++++++++++++++---
 wpa_supplicant/pr_supplicant.c |  2 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index e7ce48c80..10c899ead 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -1978,6 +1978,12 @@ struct wpa_driver_set_key_params {
 	 * ifname - Interface name (for multi-SSID/VLAN support) */
 	const char *ifname;
 
+	/**
+	 * own_addr - Own MAC address identifying the virtual interface for
+	 * the key operation, or %NULL to use the default interface (ifname)
+	 */
+	const u8 *own_addr;
+
 	/**
 	 * alg - Encryption algorithm
 	 *
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a8c4c61a3..824125be1 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4133,6 +4133,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 	struct nl_msg *key_msg;
 	int ret;
 	int skip_set_key = 1;
+	int is_pd_bss = 0;
 	const char *ifname = params->ifname;
 	enum wpa_alg alg = params->alg;
 	const u8 *addr = params->addr;
@@ -4151,6 +4152,20 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 		return 0;
 
 	ifindex = if_nametoindex(ifname);
+
+#ifdef CONFIG_PR
+	/* Route key operation to PD wdev if own_addr matches */
+	if (drv->pd_bss && params->own_addr &&
+	    ether_addr_equal(params->own_addr, drv->pd_bss->addr)) {
+		bss = drv->pd_bss;
+		is_pd_bss = 1;
+		wpa_printf(MSG_DEBUG,
+			   "nl80211: set_key: routing to PD wdev " MACSTR,
+			   MAC2STR(bss->addr));
+		ifindex = 0; /* PD wdev has no ifindex */
+	}
+#endif /* CONFIG_PR */
+
 	wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
 		   "set_tx=%d seq_len=%lu key_len=%lu key_flag=0x%x link_id=%d",
 		   __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
@@ -4197,7 +4212,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 	    KEY_FLAG_PAIRWISE_RX_TX_MODIFY) {
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: SET_KEY (pairwise RX/TX modify)");
-		if (!nl80211_is_netdev_iftype(drv->nlmode))
+		if (!nl80211_is_netdev_iftype(drv->nlmode) || is_pd_bss)
 			msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_SET_KEY);
 		else
 			msg = nl80211_ifindex_msg(drv, ifindex, 0,
@@ -4211,7 +4226,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 		goto fail2;
 	} else if (alg == WPA_ALG_NONE) {
 		wpa_printf(MSG_DEBUG, "nl80211: DEL_KEY");
-		if (!nl80211_is_netdev_iftype(drv->nlmode))
+		if (!nl80211_is_netdev_iftype(drv->nlmode) || is_pd_bss)
 			msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_KEY);
 		else
 			msg = nl80211_ifindex_msg(drv, ifindex, 0,
@@ -4227,7 +4242,7 @@ static int wpa_driver_nl80211_set_key(struct i802_bss *bss,
 			goto fail2;
 		}
 		wpa_printf(MSG_DEBUG, "nl80211: NEW_KEY");
-		if (!nl80211_is_netdev_iftype(drv->nlmode))
+		if (!nl80211_is_netdev_iftype(drv->nlmode) || is_pd_bss)
 			msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_NEW_KEY);
 		else
 			msg = nl80211_ifindex_msg(drv, ifindex, 0,
diff --git a/wpa_supplicant/pr_supplicant.c b/wpa_supplicant/pr_supplicant.c
index 494538e60..98da0a432 100644
--- a/wpa_supplicant/pr_supplicant.c
+++ b/wpa_supplicant/pr_supplicant.c
@@ -317,6 +317,7 @@ static int wpas_pr_pasn_set_keys(void *ctx, const u8 *own_addr,
 
 	os_memset(&params, 0, sizeof(params));
 	params.ifname = wpa_s->ifname;
+	params.own_addr = own_addr;
 	params.alg = wpa_cipher_to_alg(cipher);
 	params.addr = peer_addr;
 	params.key_idx = 0;
@@ -351,6 +352,7 @@ static void wpas_pr_pasn_clear_keys(void *ctx, const u8 *own_addr,
 
 	os_memset(&params, 0, sizeof(params));
 	params.ifname = wpa_s->ifname;
+	params.own_addr = own_addr;
 	params.alg = WPA_ALG_NONE;
 	params.addr = peer_addr;
 	params.key_idx = 0;
-- 
2.34.1




More information about the Hostap mailing list