diff options
author | Benjamin Berg <bberg@redhat.com> | 2018-10-08 19:42:07 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-12-13 09:20:55 +0100 |
commit | 55407fd0275004a17aa422277b843e42d5dd5b5a (patch) | |
tree | 77f5c29e43f93084bf5beb2279e24be65a210ee9 | |
parent | b16e09a707fd836cf1ea4ed34422158c8408d94f (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.c | 41 |
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); |