summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2018-10-10 22:43:49 +0200
committerThomas Haller <thaller@redhat.com>2018-12-13 09:20:55 +0100
commit15b7b36718292e95f5023fd78292432ff18d990e (patch)
tree24c85328e91c85d9007be8b3e07f97cea07e7b57
parent08c28ef96ba52486ba037c04e55c30fd472af8f4 (diff)
downloadNetworkManager-15b7b36718292e95f5023fd78292432ff18d990e.tar.gz
supplicant: Allow creating an interface from object path
wpa_supplicant will create a new interface for P2P devices. In this case we need to fetch the supplicant interface using the object path and then fetch the interface name via dbus to setup the IP interface of the P2P device later.
-rw-r--r--src/supplicant/nm-supplicant-interface.c92
-rw-r--r--src/supplicant/nm-supplicant-interface.h2
-rw-r--r--src/supplicant/nm-supplicant-manager.c58
-rw-r--r--src/supplicant/nm-supplicant-manager.h2
4 files changed, 124 insertions, 30 deletions
diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c
index 43104cf4ce..050c939895 100644
--- a/src/supplicant/nm-supplicant-interface.c
+++ b/src/supplicant/nm-supplicant-interface.c
@@ -22,6 +22,7 @@
#include "nm-default.h"
#include "nm-supplicant-interface.h"
+#include "nm-supplicant-manager.h"
#include <stdio.h>
#include <string.h>
@@ -96,6 +97,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
NM_GOBJECT_PROPERTIES_DEFINE (NMSupplicantInterface,
PROP_IFACE,
+ PROP_OBJECT_PATH,
PROP_SCANNING,
PROP_CURRENT_BSS,
PROP_DRIVER,
@@ -1278,6 +1280,14 @@ props_changed_cb (GDBusProxy *proxy,
_LOGW ("connection disconnected (reason %d)", priv->disconnect_reason);
}
+ /* We may not have priv->dev set yet if this interface was created from a
+ * known wpa_supplicant interface without knowing the device name.
+ */
+ if (priv->dev == NULL && g_variant_lookup (changed_properties, "Ifname", "&s", &s)) {
+ priv->dev = g_strdup (s);
+ _notify (self, PROP_IFACE);
+ }
+
g_object_thaw_notify (G_OBJECT (self));
}
@@ -1466,6 +1476,7 @@ interface_add_done (NMSupplicantInterface *self, const char *path)
priv->ready_count = 1;
priv->object_path = g_strdup (path);
+ _notify (self, PROP_OBJECT_PATH);
priv->iface_proxy = g_object_new (G_TYPE_DBUS_PROXY,
"g-bus-type", G_BUS_TYPE_SYSTEM,
"g-flags", G_DBUS_PROXY_FLAGS_NONE,
@@ -1599,6 +1610,7 @@ interface_removed_cb (GDBusProxy *proxy,
/* Invalidate the object path to prevent the manager from trying to remove
* a non-existing interface. */
g_clear_pointer (&priv->object_path, g_free);
+ _notify (self, PROP_OBJECT_PATH);
/* No need to clean up everything now, that will happen at dispose time. */
@@ -1623,7 +1635,6 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
gs_free_error GError *error = NULL;
GDBusProxy *wpas_proxy;
GVariantBuilder props;
- const char *driver_name = NULL;
wpas_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
if (!wpas_proxy) {
@@ -1649,36 +1660,44 @@ on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_d
* when the supplicant has started.
*/
- switch (priv->driver) {
- case NM_SUPPLICANT_DRIVER_WIRELESS:
- driver_name = DEFAULT_WIFI_DRIVER;
- break;
- case NM_SUPPLICANT_DRIVER_WIRED:
- driver_name = "wired";
- break;
- case NM_SUPPLICANT_DRIVER_MACSEC:
- driver_name = "macsec_linux";
- break;
- }
+ if (priv->dev != NULL) {
+ const char *driver_name = NULL;
+
+ switch (priv->driver) {
+ case NM_SUPPLICANT_DRIVER_WIRELESS:
+ driver_name = DEFAULT_WIFI_DRIVER;
+ break;
+ case NM_SUPPLICANT_DRIVER_WIRED:
+ driver_name = "wired";
+ break;
+ case NM_SUPPLICANT_DRIVER_MACSEC:
+ driver_name = "macsec_linux";
+ break;
+ }
- g_return_if_fail (driver_name);
+ g_return_if_fail (driver_name);
- g_variant_builder_init (&props, G_VARIANT_TYPE_VARDICT);
- g_variant_builder_add (&props, "{sv}",
- "Driver",
- g_variant_new_string (driver_name));
- g_variant_builder_add (&props, "{sv}",
- "Ifname",
- g_variant_new_string (priv->dev));
+ g_variant_builder_init (&props, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&props, "{sv}",
+ "Driver",
+ g_variant_new_string (driver_name));
+ g_variant_builder_add (&props, "{sv}",
+ "Ifname",
+ g_variant_new_string (priv->dev));
- g_dbus_proxy_call (priv->wpas_proxy,
- "CreateInterface",
- g_variant_new ("(a{sv})", &props),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- priv->init_cancellable,
- (GAsyncReadyCallback) interface_add_cb,
- self);
+ g_dbus_proxy_call (priv->wpas_proxy,
+ "CreateInterface",
+ g_variant_new ("(a{sv})", &props),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) interface_add_cb,
+ self);
+ } else if (priv->object_path) {
+ interface_add_done (self, priv->object_path);
+ } else {
+ g_assert_not_reached ();
+ }
}
static void
@@ -2222,7 +2241,10 @@ set_property (GObject *object,
case PROP_IFACE:
/* construct-only */
priv->dev = g_value_dup_string (value);
- g_return_if_fail (priv->dev);
+ break;
+ case PROP_OBJECT_PATH:
+ /* construct-only */
+ priv->object_path = g_value_dup_string (value);
break;
case PROP_DRIVER:
/* construct-only */
@@ -2270,6 +2292,7 @@ nm_supplicant_interface_init (NMSupplicantInterface * self)
NMSupplicantInterface *
nm_supplicant_interface_new (const char *ifname,
+ const char *object_path,
NMSupplicantDriver driver,
NMSupplicantFeature fast_support,
NMSupplicantFeature ap_support,
@@ -2278,10 +2301,13 @@ nm_supplicant_interface_new (const char *ifname,
NMSupplicantFeature p2p_support,
NMSupplicantFeature wfd_support)
{
- g_return_val_if_fail (ifname != NULL, NULL);
+ /* One of ifname or path need to be set */
+ g_return_val_if_fail (ifname != NULL || object_path != NULL, NULL);
+ g_return_val_if_fail (ifname == NULL || object_path == NULL, NULL);
return g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
NM_SUPPLICANT_INTERFACE_IFACE, ifname,
+ NM_SUPPLICANT_INTERFACE_OBJECT_PATH, object_path,
NM_SUPPLICANT_INTERFACE_DRIVER, (guint) driver,
NM_SUPPLICANT_INTERFACE_FAST_SUPPORT, (int) fast_support,
NM_SUPPLICANT_INTERFACE_AP_SUPPORT, (int) ap_support,
@@ -2364,6 +2390,12 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_OBJECT_PATH] =
+ g_param_spec_string (NM_SUPPLICANT_INTERFACE_OBJECT_PATH, "", "",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
obj_properties[PROP_DRIVER] =
g_param_spec_uint (NM_SUPPLICANT_INTERFACE_DRIVER, "", "",
0, G_MAXUINT, NM_SUPPLICANT_DRIVER_WIRELESS,
diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h
index b8aca5b185..aed72af8bf 100644
--- a/src/supplicant/nm-supplicant-interface.h
+++ b/src/supplicant/nm-supplicant-interface.h
@@ -55,6 +55,7 @@ typedef enum {
/* Properties */
#define NM_SUPPLICANT_INTERFACE_IFACE "iface"
+#define NM_SUPPLICANT_INTERFACE_OBJECT_PATH "object-path"
#define NM_SUPPLICANT_INTERFACE_SCANNING "scanning"
#define NM_SUPPLICANT_INTERFACE_CURRENT_BSS "current-bss"
#define NM_SUPPLICANT_INTERFACE_DRIVER "driver"
@@ -82,6 +83,7 @@ typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
GType nm_supplicant_interface_get_type (void);
NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname,
+ const char *object_path,
NMSupplicantDriver driver,
NMSupplicantFeature fast_support,
NMSupplicantFeature ap_support,
diff --git a/src/supplicant/nm-supplicant-manager.c b/src/supplicant/nm-supplicant-manager.c
index 65cb5e20e7..64a057f384 100644
--- a/src/supplicant/nm-supplicant-manager.c
+++ b/src/supplicant/nm-supplicant-manager.c
@@ -161,6 +161,7 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self,
}
iface = nm_supplicant_interface_new (ifname,
+ NULL,
driver,
priv->fast_support,
priv->ap_support,
@@ -183,6 +184,63 @@ nm_supplicant_manager_create_interface (NMSupplicantManager *self,
return iface;
}
+/**
+ * nm_supplicant_manager_create_interface_from_path:
+ * @self: the #NMSupplicantManager
+ * @object_path: the DBus object path for which to obtain the supplicant interface
+ *
+ * Note: the manager owns a reference to the instance and the only way to
+ * get the manager to release it, is by dropping all other references
+ * to the supplicant-interface (or destroying the manager).
+ *
+ * Returns: (transfer full): returns a #NMSupplicantInterface or %NULL.
+ * Must be unrefed at the end.
+ * */
+NMSupplicantInterface *
+nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self,
+ const char *object_path)
+{
+ NMSupplicantManagerPrivate *priv;
+ NMSupplicantInterface *iface;
+ GSList *ifaces;
+
+ g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
+ g_return_val_if_fail (object_path != NULL, NULL);
+
+ priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+
+ _LOGD ("creating new supplicant interface for dbus path %s", object_path);
+
+ /* assert against not requesting duplicate interfaces. */
+ for (ifaces = priv->ifaces; ifaces; ifaces = ifaces->next) {
+ if (g_strcmp0 (nm_supplicant_interface_get_object_path (ifaces->data), object_path) == 0)
+ g_return_val_if_reached (NULL);
+ }
+
+ iface = nm_supplicant_interface_new (NULL,
+ object_path,
+ NM_SUPPLICANT_DRIVER_WIRELESS,
+ priv->fast_support,
+ priv->ap_support,
+ priv->pmf_support,
+ priv->fils_support,
+ priv->p2p_support,
+ priv->wfd_support);
+
+ priv->ifaces = g_slist_prepend (priv->ifaces, iface);
+ g_object_add_toggle_ref ((GObject *) iface, _sup_iface_last_ref, self);
+
+ /* If we're making the supplicant take a time out for a bit, don't
+ * let the supplicant interface start immediately, just let it hang
+ * around in INIT state until we're ready to talk to the supplicant
+ * again.
+ */
+ if (is_available (self))
+ nm_supplicant_interface_set_supplicant_available (iface, TRUE);
+
+ return iface;
+}
+
static void
update_capabilities (NMSupplicantManager *self)
{
diff --git a/src/supplicant/nm-supplicant-manager.h b/src/supplicant/nm-supplicant-manager.h
index 8928cf206b..7225a36b58 100644
--- a/src/supplicant/nm-supplicant-manager.h
+++ b/src/supplicant/nm-supplicant-manager.h
@@ -41,5 +41,7 @@ NMSupplicantManager *nm_supplicant_manager_get (void);
NMSupplicantInterface *nm_supplicant_manager_create_interface (NMSupplicantManager *mgr,
const char *ifname,
NMSupplicantDriver driver);
+NMSupplicantInterface *nm_supplicant_manager_create_interface_from_path (NMSupplicantManager *self,
+ const char *object_path);
#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */