From e79febb3f5b516f4027fba0a8a35be359c38cf9f Mon Sep 17 00:00:00 2001 From: Ircama Date: Sun, 24 Jan 2021 16:33:58 +0100 Subject: [PATCH] P2P: Adding option to manage device drivers creating random MAC addresses Add option 2 to the p2p_device_random_mac_addr configuration option to support device drivers which use by default random MAC adresses when creating a new P2P Device interface (for instance, the BCM2711 80211 wireless device driver included in Raspberry Pi 4 Model B). In such case, this option allows to create the P2P Device interface correctly when using P2P permanent groups, enabling wpa_supplicant to reuse the same MAC address when re-invoking a P2P permanent group. update_config=1 is required. Signed-off-by: Ircama --- src/drivers/driver_nl80211.c | 4 ++++ wpa_supplicant/config.h | 26 ++++++++++++++++++++++++-- wpa_supplicant/p2p_supplicant.c | 18 +++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index a137ba293..fe07f5828 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -5261,6 +5261,10 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv, if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER)) goto fail; + if ((addr && iftype == NL80211_IFTYPE_P2P_DEVICE) && + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) + goto fail; + ret = send_and_recv_msgs(drv, msg, handler, arg, NULL, NULL); msg = NULL; if (ret) { diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 6ce737c03..c902ffbfa 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1554,9 +1554,31 @@ struct wpa_config { /** * p2p_device_random_mac_addr - P2P Device MAC address policy default * - * 0 = use permanent MAC address + * 0 = use permanent MAC address (the one set by default by the device + * driver). Notice that, if the device driver is configured to + * always use random MAC addresses, this flag breaks reinvoking a + * persistent group, so flags 1 or 2 should be used instead with + * such drivers if persistent groups are used. * 1 = use random MAC address on creating the interface if there is no - * persistent groups. + * persistent group. Besides, if a persistent group is created, + * p2p_device_persistent_mac_addr is set to the MAC address of the + * P2P Device interface, so that this address will be subsequently + * used to change the MAC address of the P2P Device interface. With + * no persistent group, the random MAC address is created by + * wpa_supplicant, changing the one set by the device driver. + * The device driver shall support SIOCGIFFLAGS/SIOCSIFFLAGS ioctl + * interface control operations. + * 2 = this flag should be used when the device driver uses random MAC + * addresses by default when a P2P Device interface is created. + * If p2p_device_persistent_mac_addr is set, use this MAC address + * on creating the P2P Device interface. If not set, use the + * default method adopted by the device driver (e.g., random MAC + * address). Besides, if a persistent group is created, + * p2p_device_persistent_mac_addr is set to the MAC address of the + * P2P Device interface, so that this address will be subsequently + * used in place of the default address set by the device driver. + * (This option does not need support of SIOCGIFFLAGS/SIOCSIFFLAGS + * ioctl interface control operations and uses NL80211_ATTR_MAC). * * By default, permanent MAC address is used. */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 62a3ea691..c04e8ec71 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3980,6 +3980,7 @@ int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s, char ifname[100]; char force_name[100]; int ret; + const u8 *if_addr = NULL; ret = os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s", wpa_s->ifname); @@ -3991,7 +3992,12 @@ int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s, ifname[IFNAMSIZ - 1] = '\0'; force_name[0] = '\0'; wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE; - ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL, + + if (wpa_s->conf->p2p_device_random_mac_addr == 2 && + !is_zero_ether_addr(wpa_s->conf->p2p_device_persistent_mac_addr)) + if_addr = wpa_s->conf->p2p_device_persistent_mac_addr; + + ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, if_addr, NULL, force_name, wpa_s->pending_interface_addr, NULL); if (ret < 0) { wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface"); @@ -4568,6 +4574,16 @@ int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s) if (wpa_s->conf->p2p_device_random_mac_addr == 0) return 0; + if (wpa_s->conf->p2p_device_random_mac_addr == 2) { + if (is_zero_ether_addr( + wpa_s->conf->p2p_device_persistent_mac_addr) && + !is_zero_ether_addr(wpa_s->own_addr)) { + os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, + wpa_s->own_addr, ETH_ALEN); + } + return 0; + } + if (!wpa_s->conf->ssid) { if (random_mac_addr(addr) < 0) { wpa_msg(wpa_s, MSG_INFO,