mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-27 19:50:08 +01:00
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.
This commit is contained in:
parent
df72cad107
commit
8665cdfeff
4 changed files with 74 additions and 27 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 { \
|
||||
|
|
|
|||
|
|
@ -71,6 +71,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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue