[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(¶ms, 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(¶ms, 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