|
|
ae491f |
From 3a5179e49fbbd5eb3df00e476e380915dd84eb05 Mon Sep 17 00:00:00 2001
|
|
|
ae491f |
From: Jouni Malinen <j@w1.fi>
|
|
|
ae491f |
Date: Sun, 22 Feb 2015 18:03:42 +0200
|
|
|
ae491f |
Subject: [PATCH] nl80211: Resubscribe to nl80211 events on global nl_event
|
|
|
ae491f |
socket
|
|
|
ae491f |
|
|
|
ae491f |
This allows wpa_supplicant to recover from some of the cases where
|
|
|
ae491f |
cfg80211 is unloaded and reloaded without restarting wpa_supplicant. The
|
|
|
ae491f |
netlink socket used for nl80211 events (global->nl_event) seemed to end
|
|
|
ae491f |
up in otherwise functionality state, but with all the event memberships
|
|
|
ae491f |
lost when cfg80211 gets reloaded.
|
|
|
ae491f |
|
|
|
ae491f |
There does not seem to be any clear way of determining when this has
|
|
|
ae491f |
happened, so it looks simplest to just try to re-subscribe to all the
|
|
|
ae491f |
events whenever an interface is re-enabled or added.
|
|
|
ae491f |
|
|
|
ae491f |
[lkundrak@v3.sk: 2.0 backport]
|
|
|
ae491f |
|
|
|
ae491f |
Signed-off-by: Jouni Malinen <j@w1.fi>
|
|
|
ae491f |
(cherry picked from commit f51f54a007e0de1d413dee3523472d3bbeed2ecc)
|
|
|
ae491f |
---
|
|
|
ae491f |
src/drivers/driver_nl80211.c | 27 +++++++++++++++++++++++++++
|
|
|
ae491f |
1 file changed, 27 insertions(+)
|
|
|
ae491f |
|
|
|
ae491f |
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
|
|
ae491f |
index 37b6be9..097265c 100644
|
|
|
ae491f |
--- a/src/drivers/driver_nl80211.c
|
|
|
ae491f |
+++ b/src/drivers/driver_nl80211.c
|
|
|
ae491f |
@@ -184,6 +184,7 @@ struct nl80211_wiphy_data {
|
|
|
ae491f |
};
|
|
|
ae491f |
|
|
|
ae491f |
static void nl80211_global_deinit(void *priv);
|
|
|
ae491f |
+static void nl80211_check_global(struct nl80211_global *global);
|
|
|
ae491f |
static void wpa_driver_nl80211_deinit(void *priv);
|
|
|
ae491f |
|
|
|
ae491f |
struct i802_bss {
|
|
|
ae491f |
@@ -852,6 +853,7 @@ static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
|
|
|
ae491f |
return 1;
|
|
|
ae491f |
|
|
|
ae491f |
if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
|
|
|
ae491f |
+ nl80211_check_global(drv->global);
|
|
|
ae491f |
drv->first_bss.ifindex = if_nametoindex(drv->first_bss.ifname);
|
|
|
ae491f |
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
|
|
|
ae491f |
"interface");
|
|
|
ae491f |
@@ -2918,6 +2920,30 @@ static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
|
|
|
ae491f |
}
|
|
|
ae491f |
|
|
|
ae491f |
|
|
|
ae491f |
+static void nl80211_check_global(struct nl80211_global *global)
|
|
|
ae491f |
+{
|
|
|
ae491f |
+ const char *groups[] = { "scan", "mlme", "regulatory", "vendor", NULL };
|
|
|
ae491f |
+ int ret;
|
|
|
ae491f |
+ unsigned int i;
|
|
|
ae491f |
+
|
|
|
ae491f |
+ /*
|
|
|
ae491f |
+ * Try to re-add memberships to handle case of cfg80211 getting reloaded
|
|
|
ae491f |
+ * and all registration having been cleared.
|
|
|
ae491f |
+ */
|
|
|
ae491f |
+
|
|
|
ae491f |
+ for (i = 0; groups[i]; i++) {
|
|
|
ae491f |
+ ret = nl_get_multicast_id(global, "nl80211", groups[i]);
|
|
|
ae491f |
+ if (ret >= 0)
|
|
|
ae491f |
+ ret = nl_socket_add_membership(global->nl_event, ret);
|
|
|
ae491f |
+ if (ret < 0) {
|
|
|
ae491f |
+ wpa_printf(MSG_INFO,
|
|
|
ae491f |
+ "nl80211: Could not re-add multicast membership for %s events: %d (%s)",
|
|
|
ae491f |
+ groups[i], ret, strerror(-ret));
|
|
|
ae491f |
+ }
|
|
|
ae491f |
+ }
|
|
|
ae491f |
+}
|
|
|
ae491f |
+
|
|
|
ae491f |
+
|
|
|
ae491f |
static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
|
|
|
ae491f |
{
|
|
|
ae491f |
wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
|
|
|
ae491f |
@@ -3137,6 +3163,7 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
|
|
|
ae491f |
}
|
|
|
ae491f |
|
|
|
ae491f |
if (drv->global) {
|
|
|
ae491f |
+ nl80211_check_global(drv->global);
|
|
|
ae491f |
dl_list_add(&drv->global->interfaces, &drv->list);
|
|
|
ae491f |
drv->in_interface_list = 1;
|
|
|
ae491f |
}
|
|
|
ae491f |
--
|
|
|
ae491f |
2.5.0
|
|
|
ae491f |
|