summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-06-30 16:33:07 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2017-08-05 08:03:16 +0200
commit8665cdfefff50bb575eb03893d6361930bc8ad40 (patch)
tree4de4d257429ccf9964da098a63896c3171e254da
parentdf72cad107fd4e721488195109e29fae5f9b8e20 (diff)
downloadNetworkManager-8665cdfefff50bb575eb03893d6361930bc8ad40.tar.gz
core: device-factory: implement match_connection()
Make it possible to register different factories for the same setting type, and add a match_connection() method to let each factory decide if it's capable of handling a connection. This will be used to decide whether a PPPoE connection must be handled through the legacy Ethernet factory or through the new PPP factory.
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.c17
-rw-r--r--src/devices/nm-device-bridge.c18
-rw-r--r--src/devices/nm-device-factory.c58
-rw-r--r--src/devices/nm-device-factory.h8
4 files changed, 74 insertions, 27 deletions
diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c
index 33bea4e27c..74bf027c72 100644
--- a/src/devices/bluetooth/nm-bluez-manager.c
+++ b/src/devices/bluetooth/nm-bluez-manager.c
@@ -26,6 +26,7 @@
#include <gmodule.h>
#include "devices/nm-device-factory.h"
+#include "devices/nm-device-bridge.h"
#include "nm-setting-bluetooth.h"
#include "settings/nm-settings.h"
#include "nm-bluez4-manager.h"
@@ -417,6 +418,21 @@ create_device (NMDeviceFactory *factory,
return NULL;
}
+static gboolean
+match_connection (NMDeviceFactory *factory,
+ NMConnection *connection)
+{
+ const char *type = nm_connection_get_connection_type (connection);
+
+ nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME));
+
+ if ( nm_bt_vtable_network_server
+ && _nm_connection_get_setting_bluetooth_for_nap (connection))
+ return FALSE; /* handled by the bridge factory */
+
+ return TRUE;
+}
+
/*****************************************************************************/
static void
@@ -461,5 +477,6 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
factory_class->get_supported_types = get_supported_types;
factory_class->create_device = create_device;
+ factory_class->match_connection = match_connection;
factory_class->start = start;
}
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index e3ba81a57d..ef5550cd6a 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -538,8 +538,24 @@ create_device (NMDeviceFactory *factory,
NULL);
}
+static gboolean
+match_connection (NMDeviceFactory *factory,
+ NMConnection *connection)
+{
+ const char *type = nm_connection_get_connection_type (connection);
+
+ if (nm_streq (type, NM_SETTING_BRIDGE_SETTING_NAME))
+ return TRUE;
+
+ nm_assert (nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME));
+
+ return nm_bt_vtable_network_server
+ && _nm_connection_get_setting_bluetooth_for_nap (connection);
+}
+
NM_DEVICE_FACTORY_DEFINE_INTERNAL (BRIDGE, Bridge, bridge,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_BRIDGE)
- NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME),
+ NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BLUETOOTH_SETTING_NAME),
factory_class->create_device = create_device;
+ factory_class->match_connection = match_connection;
);
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c
index b163bc3d22..4e0d7939d4 100644
--- a/src/devices/nm-device-factory.c
+++ b/src/devices/nm-device-factory.c
@@ -235,34 +235,24 @@ nm_device_factory_manager_find_factory_for_link_type (NMLinkType link_type)
NMDeviceFactory *
nm_device_factory_manager_find_factory_for_connection (NMConnection *connection)
{
+ NMDeviceFactoryClass *klass;
+ NMDeviceFactory *factory;
const char *type;
+ GSList *list;
g_return_val_if_fail (factories_by_setting, NULL);
type = nm_connection_get_connection_type (connection);
+ list = g_hash_table_lookup (factories_by_setting, type);
- if ( nm_streq (type, NM_SETTING_BLUETOOTH_SETTING_NAME)
- && _nm_connection_get_setting_bluetooth_for_nap (connection)) {
- /* for Bluetooth NAP connections, we return the bridge factory
- * instead of the bluetooth factory.
- *
- * In a way, this is a hack. The more orthodox solution would
- * be that device factories don't only announce supported setting
- * types, but instead match on a full fledged NMConnection.
- *
- * However, our device-factories are known at compile time.
- * There is no need to keep this generic. We *know* which
- * factory to choose. Making this generic would not make it
- * cleaner. */
- if (!g_hash_table_lookup (factories_by_setting, type)) {
- /* we need both the bluetooth and the bridge factory
- * to make this work. */
- return NULL;
- }
- type = NM_SETTING_BRIDGE_SETTING_NAME;
+ for (; list; list = g_slist_next (list)) {
+ factory = list->data;
+ klass = NM_DEVICE_FACTORY_GET_CLASS (factory);
+ if (!klass->match_connection || klass->match_connection (factory, connection))
+ return factory;
}
- return g_hash_table_lookup (factories_by_setting, type);
+ return NULL;
}
void
@@ -283,9 +273,11 @@ nm_device_factory_manager_for_each_factory (NMDeviceFactoryManagerFactoryFunc ca
if (factories_by_setting) {
g_hash_table_iter_init (&iter, factories_by_setting);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &factory)) {
- if (!g_slist_find (list, factory))
- list = g_slist_prepend (list, factory);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &list_iter)) {
+ for (; list_iter; list_iter = g_slist_next (list_iter)) {
+ if (!g_slist_find (list, list_iter->data))
+ list = g_slist_prepend (list, list_iter->data);
+ }
}
}
@@ -303,6 +295,7 @@ _add_factory (NMDeviceFactory *factory,
{
const NMLinkType *link_types = NULL;
const char *const*setting_types = NULL;
+ GSList *list;
int i;
g_return_val_if_fail (factories_by_link, FALSE);
@@ -313,8 +306,15 @@ _add_factory (NMDeviceFactory *factory,
g_object_set_qdata_full (G_OBJECT (factory), plugin_path_quark (), g_strdup (path), g_free);
for (i = 0; link_types && link_types[i] > NM_LINK_TYPE_UNKNOWN; i++)
g_hash_table_insert (factories_by_link, GUINT_TO_POINTER (link_types[i]), g_object_ref (factory));
- for (i = 0; setting_types && setting_types[i]; i++)
- g_hash_table_insert (factories_by_setting, (char *) setting_types[i], g_object_ref (factory));
+ for (i = 0; setting_types && setting_types[i]; i++) {
+ list = g_hash_table_lookup (factories_by_setting, (char *) setting_types[i]);
+ if (list)
+ list = g_slist_append (list, g_object_ref (factory));
+ else {
+ list = g_slist_append (list, g_object_ref (factory));
+ g_hash_table_insert (factories_by_setting, (char *) setting_types[i], list);
+ }
+ }
callback (factory, user_data);
@@ -333,6 +333,12 @@ _load_internal_factory (GType factory_gtype,
_add_factory (factory, "internal", callback, user_data);
}
+static void
+factories_list_unref (GSList *list)
+{
+ g_slist_free_full (list, g_object_unref);
+}
+
void
nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc callback,
gpointer user_data)
@@ -345,7 +351,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
g_return_if_fail (factories_by_setting == NULL);
factories_by_link = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
- factories_by_setting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+ factories_by_setting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) factories_list_unref);
#define _ADD_INTERNAL(get_type_fcn) \
G_STMT_START { \
diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h
index 0c590f657a..33b596e6e6 100644
--- a/src/devices/nm-device-factory.h
+++ b/src/devices/nm-device-factory.h
@@ -72,6 +72,14 @@ typedef struct {
void (*start) (NMDeviceFactory *factory);
/**
+ * match_connection:
+ * @connection: the #NMConnection
+ *
+ * Check if the factory supports the given connection.
+ */
+ gboolean (*match_connection) (NMDeviceFactory *factory, NMConnection *connection);
+
+ /**
* get_connection_parent:
* @factory: the #NMDeviceFactory
* @connection: the #NMConnection to return the parent name for, if supported