Cumulative patch from commit c24f8e8e75b46f0b191cca788b6f4c10bed81861 (DO NOT MERGE)

c24f8e8 GAS: Do not cancel initial offchannel wait with comeback delay 1
364282c GAS: Retry full GAS query if comeback response is not received
a587666 GAS server: Replenish temporary STA entry timeout on comeback request
8fb718a GAS: Shorten the duration of the wait for GAS comeback response
c012567 GAS: Clear offchannel_tx_started when ending remain-on-channel
cb73008 EAP-TTLS/PEAP/FAST: Reject unsupported Phase 2 method in configuration
18704f6 EAP-TLS: Merge common error paths
4f5c86e EAP-PEAP peer: Fix a memory leak on an error path
e7160bd Drop any pending EAPOL RX frame when starting a new connection
cd5895e WPA: Explicitly clear the buffer used for decrypting Key Data
4b90fcd EAP-PEAP peer: Check SHA1 result when deriving Compond_MAC
6ca5838 EAP-PEAP server: Add support for fast-connect crypto binding
6560caf EAP-PEAP peer: Remove unused return value and error path
61f25f8 HS 2.0: Remove duplicate icon entries
ca9968a HS 2.0: Convert icon storage to use dl_list
8dd5c1b HS 2.0: Add a command to retrieve icon with in-memory storage
0e92fb8 rfkill: Match only the correct expected wiphy rfkill
6da504a nl80211: Handle rfkill for P2P Device interface
96e8d83 wpa_supplicant: Add SIGNAL_MONITOR command
2c0d0ae GAS: End remain-on-channel due to delayed GAS comeback request
dabdef9 TDLS: Ignore incoming TDLS Setup Response retries
0fc5707 hlr_auc_gw: Simplify string parsers with str_token()
d67e63d hlr_auc_gw: Fix a typo in an error message
59e7120 hlr_auc_gw: Remove unnecessary assignment
685ea2f wpa_cli: Send ALL_STA command to the correct interface
0e6a2cf Disconnect before trying to switch to a different network
706e11a Avoid network selection from scan during connection
819ad5b utils: Fix NULL pointer dereference with unexpected kernel behavior
1b3dd69 P2P: Fix possible NULL pointer dereference
f24e488 EAP-TTLS peer: Fix parsing auth= and autheap= phase2 params
47c1de2 atheros: Unify memory processing functions
d06a350 mesh: Fix VHT Operation information in peering messages
8ba8c01 TLS: Report OCSP rejection cases when no valid response if found
f163ed8 TLS: Process OCSP SingleResponse(s)
8e3271d TLS: Store DER encoded version of Subject DN for X.509 certificates
32ce690 TLS: Share digest OID checkers from X.509
b72a367 TLS: Support longer X.509 serialNumber values
af4eba1 TLS: Parse and validate BasicOCSPResponse

Change-Id: I0fadef8993a548d64a4280372bc105fefa11e62a
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0fd836b..ed5e4a8 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1520,11 +1520,16 @@
 
 static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
 {
+	struct wpa_driver_nl80211_data *drv = ctx;
+
 	wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
+
 	/*
-	 * This may be for any interface; use ifdown event to disable
-	 * interface.
+	 * rtnetlink ifdown handler will report interfaces other than the P2P
+	 * Device interface as disabled.
 	 */
+	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
+		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
 }
 
 
@@ -1541,7 +1546,12 @@
 	if (is_p2p_net_interface(drv->nlmode))
 		nl80211_disable_11b_rates(drv, drv->ifindex, 1);
 
-	/* rtnetlink ifup handler will report interface as enabled */
+	/*
+	 * rtnetlink ifup handler will report interfaces other than the P2P
+	 * Device interface as enabled.
+	 */
+	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
+		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
 }
 
 
@@ -1626,13 +1636,65 @@
 }
 
 
+static void
+wpa_driver_nl80211_drv_init_rfkill(struct wpa_driver_nl80211_data *drv)
+{
+	struct rfkill_config *rcfg;
+
+	if (drv->rfkill)
+		return;
+
+	rcfg = os_zalloc(sizeof(*rcfg));
+	if (!rcfg)
+		return;
+
+	rcfg->ctx = drv;
+
+	/* rfkill uses netdev sysfs for initialization. However, P2P Device is
+	 * not associated with a netdev, so use the name of some other interface
+	 * sharing the same wiphy as the P2P Device interface.
+	 *
+	 * Note: This is valid, as a P2P Device interface is always dynamically
+	 * created and is created only once another wpa_s interface was added.
+	 */
+	if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) {
+		struct nl80211_global *global = drv->global;
+		struct wpa_driver_nl80211_data *tmp1;
+
+		dl_list_for_each(tmp1, &global->interfaces,
+				 struct wpa_driver_nl80211_data, list) {
+			if (drv == tmp1 || drv->wiphy_idx != tmp1->wiphy_idx ||
+			    !tmp1->rfkill)
+				continue;
+
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: Use (%s) to initialize P2P Device rfkill",
+				   tmp1->first_bss->ifname);
+			os_strlcpy(rcfg->ifname, tmp1->first_bss->ifname,
+				   sizeof(rcfg->ifname));
+			break;
+		}
+	} else {
+		os_strlcpy(rcfg->ifname, drv->first_bss->ifname,
+			   sizeof(rcfg->ifname));
+	}
+
+	rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
+	rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
+	drv->rfkill = rfkill_init(rcfg);
+	if (!drv->rfkill) {
+		wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
+		os_free(rcfg);
+	}
+}
+
+
 static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
 					  void *global_priv, int hostapd,
 					  const u8 *set_addr,
 					  const char *driver_params)
 {
 	struct wpa_driver_nl80211_data *drv;
-	struct rfkill_config *rcfg;
 	struct i802_bss *bss;
 
 	if (global_priv == NULL)
@@ -1673,19 +1735,6 @@
 	if (nl80211_init_bss(bss))
 		goto failed;
 
-	rcfg = os_zalloc(sizeof(*rcfg));
-	if (rcfg == NULL)
-		goto failed;
-	rcfg->ctx = drv;
-	os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
-	rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
-	rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
-	drv->rfkill = rfkill_init(rcfg);
-	if (drv->rfkill == NULL) {
-		wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
-		os_free(rcfg);
-	}
-
 	if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
 		drv->start_iface_up = 1;
 
@@ -2224,6 +2273,8 @@
 	if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
 		nl80211_get_macaddr(bss);
 
+	wpa_driver_nl80211_drv_init_rfkill(drv);
+
 	if (!rfkill_is_blocked(drv->rfkill)) {
 		int ret = i802_set_iface_flags(bss, 1);
 		if (ret) {
@@ -2241,20 +2292,22 @@
 	} else {
 		wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
 			   "interface '%s' due to rfkill", bss->ifname);
-		if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
-			return 0;
-		drv->if_disabled = 1;
+		if (nlmode != NL80211_IFTYPE_P2P_DEVICE)
+			drv->if_disabled = 1;
+
 		send_rfkill_event = 1;
 	}
 
-	if (!drv->hostapd)
+	if (!drv->hostapd && nlmode != NL80211_IFTYPE_P2P_DEVICE)
 		netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
 				       1, IF_OPER_DORMANT);
 
-	if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
-			       bss->addr))
-		return -1;
-	os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
+	if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
+		if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
+				       bss->addr))
+			return -1;
+		os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
+	}
 
 	if (send_rfkill_event) {
 		eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,