diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2017-06-30 16:33:07 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2017-08-05 08:03:16 +0200 |
commit | 8665cdfefff50bb575eb03893d6361930bc8ad40 (patch) | |
tree | 4de4d257429ccf9964da098a63896c3171e254da | |
parent | df72cad107fd4e721488195109e29fae5f9b8e20 (diff) | |
download | NetworkManager-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.c | 17 | ||||
-rw-r--r-- | src/devices/nm-device-bridge.c | 18 | ||||
-rw-r--r-- | src/devices/nm-device-factory.c | 58 | ||||
-rw-r--r-- | src/devices/nm-device-factory.h | 8 |
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 |