[PATCH] wpa_supplicant: Denitialize the driver if the last user went away

Lubomir Rintel lkundrak at v3.sk
Wed Oct 29 12:57:09 EDT 2014


It might be that the underlying infrastrucutre went away and the state is no
longer valid. We ought to reinitialize it once a device appears again.

This is the case when the nl80211 devices disappear and cfg8011 is remoed
afterwards. The netlink handle is no longer valid (returns ENOENT) and a new
one needs to be open if it's loaded back.

Signed-off-by: Lubomir Rintel <lkundrak at v3.sk>
---
 wpa_supplicant/wpa_supplicant.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 5a4d8dc..072dce5 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3925,6 +3925,24 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 	return 0;
 }
 
+/* Deinitialize the driver if we're the last user. */
+static void wpa_drv_cleanup(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_global *global = wpa_s->global;
+	struct wpa_supplicant *iface;
+	int i;
+
+	for (iface = global->ifaces; iface; iface = iface->next)
+		if (iface != wpa_s && iface->driver == wpa_s->driver)
+			return;
+
+	for (i = 0; wpa_drivers[i]; i++)
+		if (global->drv_priv[i] == wpa_s->global_drv_priv)
+			wpa_s->global_drv_priv = global->drv_priv[i] = NULL;
+
+	if (wpa_s->driver->global_deinit)
+		wpa_s->driver->global_deinit (wpa_s->global_drv_priv);
+}
 
 static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
 					int notify, int terminate)
@@ -3967,6 +3985,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
 	if (wpa_s->drv_priv)
 		wpa_drv_deinit(wpa_s);
 
+	wpa_drv_cleanup(wpa_s);
+
 	if (notify)
 		wpas_notify_iface_removed(wpa_s);
 
-- 
1.8.2.1



More information about the HostAP mailing list