summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2018-10-08 19:42:07 +0200
committerThomas Haller <thaller@redhat.com>2018-12-13 09:20:55 +0100
commit55407fd0275004a17aa422277b843e42d5dd5b5a (patch)
tree77f5c29e43f93084bf5beb2279e24be65a210ee9
parentb16e09a707fd836cf1ea4ed34422158c8408d94f (diff)
supplicant: Handle interface removal
The signal was not handled, potentially creating corner cases where NetworkManager may not notice an interface removal. Add a handler and ensure the supplicant interface is brought down when it is removed from wpa_supplicant for a reason other than NetworkManager requesting it.
-rw-r--r--src/supplicant/nm-supplicant-interface.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index 5237acb263..562b754d3f 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -1289,6 +1289,38 @@ interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
}
}
+static void
+interface_removed_cb (GDBusProxy *proxy,
+ const char *path,
+ gpointer user_data)
+{
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (g_strcmp0 (priv->object_path, path) != 0)
+ return;
+
+ _LOGD ("Received interface removed signal");
+
+ /* The interface may lose its last reference during signal handling otherwise. */
+ g_object_ref (self);
+
+ /* Invalidate the object path to prevent the manager from trying to remove
+ * a non-existing interface. */
+ g_clear_pointer (&priv->object_path, g_free);
+
+ /* No need to clean up everything now, that will happen at dispose time. */
+
+ /* Interface is down and has been removed. */
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ g_signal_emit (self, signals[REMOVED], 0);
+
+ g_object_unref (self);
+}
+
#if HAVE_WEXT
#define DEFAULT_WIFI_DRIVER "nl80211,wext"
#else
@@ -1320,6 +1352,10 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
priv->wpas_proxy = wpas_proxy;
+ /* Watch for interface removal. */
+ _nm_dbus_signal_connect (priv->wpas_proxy, "InterfaceRemoved", G_VARIANT_TYPE ("(o)"),
+ G_CALLBACK (interface_removed_cb), self);
+
/* Try to add the interface to the supplicant. If the supplicant isn't
* running, this will start it via D-Bus activation and return the response
* when the supplicant has started.
@@ -1374,8 +1410,7 @@ interface_add (NMSupplicantInterface *self)
priv->init_cancellable = g_cancellable_new ();
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL,
WPAS_DBUS_SERVICE,
WPAS_DBUS_PATH,
@@ -1983,6 +2018,8 @@ dispose (GObject *object)
nm_clear_g_cancellable (&priv->init_cancellable);
nm_clear_g_cancellable (&priv->other_cancellable);
+ if (priv->wpas_proxy)
+ g_signal_handlers_disconnect_by_data (priv->wpas_proxy, object);
g_clear_object (&priv->wpas_proxy);
g_clear_pointer (&priv->bss_proxies, g_hash_table_destroy);