diff mbox series

p2p: Set MAC address of P2P device interface via vendor command

Message ID 20200406182159.810A7D80863@xl-sj1-30.broadcom.com
State New
Headers show
Series p2p: Set MAC address of P2P device interface via vendor command | expand

Commit Message

Stephen Chu April 6, 2020, 6:21 p.m. UTC
From 7b0357dd90f9b5974779743078b3b482c98dc18b Mon Sep 17 00:00:00 2001
From: Stephen Chu <stephen.chu@broadcom.com>
Date: Mon, 6 Apr 2020 11:13:49 -0700
Subject: [PATCH] p2p: Set MAC address of P2P device interface via vendor
 command

Supplicant uses standard linux IOCTL for setting the mac addr.  However,
P2P device interface is a netless interface and hence this case needs
additional handling.  The supplicant could pass down the mac address to be
configured via vendor command to the wireless driver.  From this context,
the wireless driver can update the p2p discovery address via iovar.

Signed-off-by: Stephen Chu <stephen.chu@broadcom.com>
---
 src/common/brcm_vendor.h     | 99 ++++++++++++++++++++++++++++++++++++
 src/drivers/driver_nl80211.c | 40 ++++++++++++++-
 src/drivers/driver_nl80211.h |  3 ++
 wpa_supplicant/Android.mk    |  5 ++
 4 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 src/common/brcm_vendor.h

Comments

Johannes Berg April 6, 2020, 7:01 p.m. UTC | #1
On Mon, 2020-04-06 at 11:21 -0700, Stephen Chu wrote:
> From 7b0357dd90f9b5974779743078b3b482c98dc18b Mon Sep 17 00:00:00 2001
> From: Stephen Chu <stephen.chu@broadcom.com>
> Date: Mon, 6 Apr 2020 11:13:49 -0700
> Subject: [PATCH] p2p: Set MAC address of P2P device interface via vendor
>  command
> 
> Supplicant uses standard linux IOCTL for setting the mac addr.  However,
> P2P device interface is a netless interface and hence this case needs
> additional handling.  The supplicant could pass down the mac address to be
> configured via vendor command to the wireless driver.  From this context,
> the wireless driver can update the p2p discovery address via iovar.

If the driver already supports nl80211, why doesn't it support a
P2P_DEVICE wdev, where the address could be set?

Or is it that we can only set it when *creating* that, and somehow the
driver has it pre-created?

johannes
Arend Van Spriel April 7, 2020, 7:16 p.m. UTC | #2
On 4/6/2020 9:01 PM, Johannes Berg wrote:
> On Mon, 2020-04-06 at 11:21 -0700, Stephen Chu wrote:
>>  From 7b0357dd90f9b5974779743078b3b482c98dc18b Mon Sep 17 00:00:00 2001
>> From: Stephen Chu <stephen.chu@broadcom.com>
>> Date: Mon, 6 Apr 2020 11:13:49 -0700
>> Subject: [PATCH] p2p: Set MAC address of P2P device interface via vendor
>>   command
>>
>> Supplicant uses standard linux IOCTL for setting the mac addr.  However,
>> P2P device interface is a netless interface and hence this case needs
>> additional handling.  The supplicant could pass down the mac address to be
>> configured via vendor command to the wireless driver.  From this context,
>> the wireless driver can update the p2p discovery address via iovar.
> 
> If the driver already supports nl80211, why doesn't it support a
> P2P_DEVICE wdev, where the address could be set?
> 
> Or is it that we can only set it when *creating* that, and somehow the
> driver has it pre-created?

I would say that pre-creation could be hidden by the wireless driver 
although I am not sure why it could not deal with P2P_DEV wdev.

The introduced vendor-specific header file introduces a whole lot more 
primitives. I think you should trim down this file and only have the 
"set mac address" primitive although even that one is arguable.

Regards,
Arend
diff mbox series

Patch

diff --git a/src/common/brcm_vendor.h b/src/common/brcm_vendor.h
new file mode 100644
index 000000000..405e65ed0
--- /dev/null
+++ b/src/common/brcm_vendor.h
@@ -0,0 +1,99 @@ 
+/*
+ * Broadcom Corporation OUI and vendor specific assignments
+ * Copyright (c) 2015, Broadcom Corporation.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef BRCM_VENDOR_H
+#define BRCM_VENDOR_H
+
+/*
+ * This file is a registry of identifier assignments from the Broadcom
+ * OUI 00:10:18 for purposes other than MAC address assignment. New identifiers
+ * can be assigned through normal review process for changes to the upstream
+ * hostap.git repository.
+ */
+
+#define OUI_BRCM  0x001018
+
+/**
+ * enum brcm_nl80211_vendor_subcmds - BRCM nl80211 vendor command identifiers
+ *
+ * @BRCM_VENDOR_SUBCMD_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_SUBCMD_PRIV_STR: String command/event
+ */
+enum brcm_nl80211_vendor_subcmds {
+	BRCM_VENDOR_SUBCMD_UNSPEC           = 0,
+	BRCM_VENDOR_SUBCMD_PRIV_STR         = 1,
+	BRCM_VENDOR_SUBCMD_BCM_STR          = 2,
+	BRCM_VENDOR_SUBCMD_SET_PSK          = 3,
+	BRCM_VENDOR_SUBCMD_SET_PMK          = 4,
+	BRCM_VENDOR_SUBCMD_GET_FEATURES     = 5,
+	BRCM_VENDOR_SUBCMD_SET_MAC          = 6,
+	BRCM_VENDOR_SUBCMD_CONNECT_PARAMS   = 7,
+	BRCM_VENDOR_SUBCMD_START_AP_PARAMS  = 8,
+};
+
+/**
+ * enum brcm_nl80211_vendor_events - BRCM nl80211 asynchoronous event identifiers
+ *
+ * @BRCM_VENDOR_EVENT_UNSPEC: Reserved value 0
+ *
+ * @BRCM_VENDOR_EVENT_PRIV_STR: String command/event
+ */
+enum brcm_nl80211_vendor_events {
+	BRCM_VENDOR_EVENT_UNSPEC            = 0,
+	BRCM_VENDOR_EVENT_PRIV_STR          = 1,
+	BRCM_VENDOR_EVENT_HANGED            = 33,
+	BRCM_VENDOR_EVENT_SAE_KEY           = 34,
+	BRCM_VENDOR_EVENT_BEACON_RECV       = 35,
+	BRCM_VENDOR_EVENT_PORT_AUTHORIZED   = 36,
+	BRCM_VENDOR_EVENT_CU                = 38,
+	BRCM_VENDOR_EVENT_WIPS              = 39
+};
+
+#ifdef CONFIG_BRCM_SAE
+enum wifi_sae_key_attr {
+	BRCM_SAE_KEY_ATTR_PEER_MAC,
+	BRCM_SAE_KEY_ATTR_PMK,
+	BRCM_SAE_KEY_ATTR_PMKID
+};
+#endif /* CONFIG_BRCM_SAE */
+
+enum brcm_wlan_vendor_attr {
+	BRCM_ATTR_DRIVER_CMD            = 0,
+	BRCM_ATTR_DRIVER_KEY_PMK        = 1,
+	BRCM_ATTR_DRIVER_FEATURE_FLAGS  = 2,
+	BRCM_ATTR_DRIVER_MAC_ADDR       = 3,
+	BRCM_ATTR_SAE_PWE               = 4,
+	BRCM_ATTR_DRIVER_AFTER_LAST     = 5,
+	BRCM_ATTR_DRIVER_MAX            = BRCM_ATTR_DRIVER_AFTER_LAST - 1,
+};
+
+enum brcm_wlan_vendor_features {
+	BRCM_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0,
+	BRCM_WLAN_VENDOR_FEATURE_MAX = 1
+};
+
+enum brcm_nl80211_vendor_bcnrecv_attr_type {
+	BRCM_BCNRECV_ATTR_STATUS = 1,
+	BRCM_BCNRECV_ATTR_REASON,
+	BRCM_BCNRECV_ATTR_BCNINFO,
+	BRCM_BCNRECV_ATTR_MAX
+};
+
+enum brcm_nl80211_vendor_cu_attr_type {
+	BRCM_CU_ATTR_PERCENTAGE = 1,
+	BRCM_CU_ATTR_MAX
+};
+
+enum brcm_nl80211_vendor_wips_attr_type {
+	BRCM_WIPS_ATTR_DEAUTH_CNT = 1,
+	BRCM_WIPS_ATTR_DEAUTH_BSSID,
+	BRCM_WIPS_ATTR_MAX
+};
+#endif /* BRCM_VENDOR_H */
+
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3b7c31c89..95828a60c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -27,6 +27,7 @@ 
 #include "eloop.h"
 #include "common/qca-vendor.h"
 #include "common/qca-vendor-attr.h"
+#include "common/brcm_vendor.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
 #include "common/wpa_common.h"
@@ -7396,8 +7397,12 @@  static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
 
 		drv->global->if_add_wdevid = p2pdev_info.wdev_id;
 		drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
-		if (!is_zero_ether_addr(p2pdev_info.macaddr))
+		if (!is_zero_ether_addr(p2pdev_info.macaddr)) {
 			os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
+#ifdef CONFIG_BRCM_P2P_RAND
+			os_memcpy(drv->global->p2p_perm_addr, p2pdev_info.macaddr, ETH_ALEN);
+#endif /* CONFIG_BRCM_P2P_RAND */
+		}
 		wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
 			   ifname,
 			   (long long unsigned int) p2pdev_info.wdev_id);
@@ -9798,9 +9803,42 @@  static int nl80211_set_mac_addr(void *priv, const u8 *addr)
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
 	int new_addr = addr != NULL;
+#ifdef CONFIG_BRCM_P2P_RAND
+	struct nl_msg *msg;
+	struct nlattr *params;
+	int ret;
+#endif /* CONFIG_BRCM_P2P_RAND */
 
 	if (TEST_FAIL())
 		return -1;
+#ifdef CONFIG_BRCM_P2P_RAND
+	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) {
+		if (!addr ) {
+			addr = drv->global->p2p_perm_addr;
+		}
+
+		if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
+			nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
+			nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+				BRCM_VENDOR_SUBCMD_SET_MAC) ||
+			!(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+			nla_put(msg, BRCM_ATTR_DRIVER_MAC_ADDR, ETH_ALEN, addr)) {
+			wpa_printf(MSG_ERROR, "failed to put p2p randmac");
+			nl80211_nlmsg_clear(msg);
+			nlmsg_free(msg);
+			return -ENOBUFS;
+		}
+		nla_nest_end(msg, params);
+
+		ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
+		if (ret) {
+			wpa_printf(MSG_ERROR, "nl80211: p2p set macaddr failed: ret=%d (%s)",
+				ret, strerror(-ret));
+		}
+		memcpy(bss->addr, addr, ETH_ALEN);
+		return ret;
+	}
+#endif /* CONFIG_BRCM_P2P_RAND */
 
 	if (!addr)
 		addr = drv->perm_addr;
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 6e6c87247..3d73d5f69 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -35,6 +35,9 @@  struct nl80211_global {
 	int ioctl_sock; /* socket for ioctl() use */
 
 	struct nl_sock *nl_event;
+#ifdef CONFIG_BRCM_P2P_RAND
+	u8 p2p_perm_addr[ETH_ALEN];
+#endif /* CONFIG_BRCM_P2P_RAND */
 };
 
 struct nl80211_wiphy_data {
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index e44b366b5..ec14c4c7c 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -28,6 +28,11 @@  L_CFLAGS += -Wno-unused-parameter
 # Set Android extended P2P functionality
 L_CFLAGS += -DANDROID_P2P
 
+# Android Q
+ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
+L_CFLAGS += -DCONFIG_BRCM_P2P_RAND
+endif
+
 ifeq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
 L_CFLAGS += -DANDROID_LIB_STUB
 endif