Merge changes from topic "wifi-p2p-random-interface-address"

* changes:
  p2p: support random interface address
  p2p: support random device address
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index dd7f603..a8987a6 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2637,6 +2637,7 @@
 #ifdef CONFIG_MBO
 	os_free(config->non_pref_chan);
 #endif /* CONFIG_MBO */
+	os_free(config->p2p_device_persistent_mac_addr);
 
 	os_free(config);
 }
@@ -4753,6 +4754,9 @@
 	{ INT(gas_rand_addr_lifetime), 0 },
 	{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
 	{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
+	{ INT(p2p_device_random_mac_addr), 0 },
+	{ STR(p2p_device_persistent_mac_addr), 0 },
+	{ INT(p2p_interface_random_mac_addr), 0 },
 };
 
 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index ad4dd88..ee20a93 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1469,6 +1469,36 @@
 	 *	profile automatically
 	 */
 	int dpp_config_processing;
+
+	/**
+	 * p2p_device_random_mac_addr - P2P Device MAC address policy default
+	 *
+	 * 0 = use permanent MAC address
+	 * 1 = use random MAC address on creating the interface if there is no persistent groups.
+	 *
+	 * By default, permanent MAC address is used.
+	 */
+	int p2p_device_random_mac_addr;
+
+	/**
+	 * p2p_device_persistent_mac_addr - Record last used MAC address
+	 *
+	 * If there are saved persistent groups, P2P cannot generate another random MAC address,
+	 * and need to restore to last used MAC address.
+	 * format: aa:bb:cc:dd:ee:ff
+	 */
+	char *p2p_device_persistent_mac_addr;
+
+	/**
+	 * p2p_interface_random_mac_addr - P2P Interface MAC address policy default
+	 *
+	 * 0 = use permanent MAC address
+	 * 1 = use random MAC address on creating the interface.
+	 *
+	 * By default, permanent MAC address is used.
+	 */
+	int p2p_interface_random_mac_addr;
+
 };
 
 
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index aa73f9d..3a6dae5 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1511,6 +1511,15 @@
 	if (config->dpp_config_processing)
 		fprintf(f, "dpp_config_processing=%d\n",
 			config->dpp_config_processing);
+	if (config->p2p_device_random_mac_addr)
+		fprintf(f, "p2p_device_random_mac_addr=%d\n",
+			config->p2p_device_random_mac_addr);
+	if (config->p2p_device_persistent_mac_addr)
+		fprintf(f, "p2p_device_persistent_mac_addr=%s\n",
+			config->p2p_device_persistent_mac_addr);
+	if (config->p2p_interface_random_mac_addr)
+		fprintf(f, "p2p_interface_random_mac_addr=%d\n",
+			config->p2p_interface_random_mac_addr);
 
 }
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b9b0bea..3d3296f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2075,6 +2075,17 @@
 		return -1;
 	}
 
+	if (wpa_s->conf->p2p_interface_random_mac_addr) {
+		if (random_mac_addr(wpa_s->pending_interface_addr) < 0) {
+			wpa_printf(MSG_ERROR, "P2P: Failed to generate random MAC address "
+					      "for the group interface");
+			return -1;
+		}
+		wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR " for the group",
+			MAC2STR(wpa_s->pending_interface_addr));
+	}
+
+
 	if (force_ifname[0]) {
 		wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
 			   force_ifname);
@@ -2153,6 +2164,25 @@
 
 	wpas_p2p_clone_config(group_wpa_s, wpa_s);
 
+	if (wpa_s->conf->p2p_interface_random_mac_addr) {
+		if (wpa_drv_set_mac_addr(group_wpa_s, wpa_s->pending_interface_addr) < 0) {
+			wpa_msg(group_wpa_s, MSG_INFO,
+				"Failed to set random MAC address");
+			wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, 0);
+			return NULL;
+		}
+
+		if (wpa_supplicant_update_mac_addr(group_wpa_s) < 0) {
+			wpa_msg(group_wpa_s, MSG_INFO,
+				"Could not update MAC address information");
+			wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, 0);
+			return NULL;
+		}
+
+		wpa_printf(MSG_DEBUG, "P2P: Using random MAC address " MACSTR " for the group",
+			MAC2STR(wpa_s->pending_interface_addr));
+	}
+
 	return group_wpa_s;
 }
 
@@ -4314,6 +4344,57 @@
 					  WPA_IF_P2P_CLIENT, len, freq_list);
 }
 
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
+{
+	u8 addr[ETH_ALEN] = {0};
+
+	if (wpa_s->conf->p2p_device_random_mac_addr == 0)
+		return 0;
+
+	if (wpa_s->conf->ssid == NULL) {
+		if (random_mac_addr(addr) < 0) {
+			wpa_msg(wpa_s, MSG_INFO,
+				"Failed to generate random MAC address");
+			return -EINVAL;
+		}
+
+		// store generated MAC address.
+		if (wpa_s->conf->p2p_device_persistent_mac_addr)
+			os_free(wpa_s->conf->p2p_device_persistent_mac_addr);
+		size_t mac_addr_str_len = sizeof("00:00:00:00:00:00");
+		wpa_s->conf->p2p_device_persistent_mac_addr =
+			os_zalloc(mac_addr_str_len + 1);
+		os_snprintf(wpa_s->conf->p2p_device_persistent_mac_addr,
+			mac_addr_str_len, MACSTR, MAC2STR(addr));
+	} else {
+		// If there are existing saved groups, restore last MAC address.
+		// if there is no last used MAC address, the last one is factory MAC.
+		if (!wpa_s->conf->p2p_device_persistent_mac_addr)
+			return 0;
+
+		if (hwaddr_aton(wpa_s->conf->p2p_device_persistent_mac_addr, addr) < 0)
+			return -EINVAL;
+		wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address.");
+	}
+
+	if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
+		wpa_msg(wpa_s, MSG_INFO,
+			"Failed to set random MAC address");
+		return -EINVAL;
+	}
+
+	if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+		wpa_msg(wpa_s, MSG_INFO,
+			"Could not update MAC address information");
+		return -EINVAL;
+	}
+
+	wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
+		MAC2STR(addr));
+
+	return 0;
+}
+
 
 /**
  * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
@@ -4335,6 +4416,12 @@
 	if (global->p2p)
 		return 0;
 
+	if (wpas_p2p_mac_setup(wpa_s) < 0) {
+		wpa_msg(wpa_s, MSG_ERROR,
+			"Failed to initialize P2P random MAC address.");
+		return -1;
+	}
+
 	os_memset(&p2p, 0, sizeof(p2p));
 	p2p.cb_ctx = wpa_s;
 	p2p.debug_print = wpas_p2p_debug_print;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 63910d1..0a08a88 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -211,6 +211,7 @@
 		      unsigned int period, unsigned int interval,
 		      unsigned int count);
 int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
 
 #else /* CONFIG_P2P */