summary refs log tree commit diff
path: root/src/devices/nm-device-factory.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2017-01-17 20:25:09 +0100
committerMichael Biebl <biebl@debian.org>2017-01-17 20:25:09 +0100
commit58f8be580039b0575b197b9573a1c92745d96d30 (patch)
tree2c226233f623a0dcb529be0eb8cdf97e4a2ae0c0 /src/devices/nm-device-factory.c
parent45cb5bb3c0e6edb887cf69b417fcaf7053814a9b (diff)
New upstream version 1.5.90 upstream/1.5.90
Diffstat (limited to 'src/devices/nm-device-factory.c')
-rw-r--r--src/devices/nm-device-factory.c241
1 files changed, 83 insertions, 158 deletions
diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c
index a72c0bbb..0ce2cb48 100644
--- a/src/devices/nm-device-factory.c
+++ b/src/devices/nm-device-factory.c
@@ -19,33 +19,43 @@
  */
 
 #include "nm-default.h"
+
+#include "nm-device-factory.h"
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <string.h>
 #include <gmodule.h>
 
-#include "nm-device-factory.h"
-#include "nm-platform.h"
+#include "platform/nm-platform.h"
 #include "nm-utils.h"
 
-const NMLinkType _nm_device_factory_no_default_links[] = { NM_LINK_TYPE_NONE };
-const char *_nm_device_factory_no_default_settings[] = { NULL };
+#define PLUGIN_PREFIX "libnm-device-plugin-"
+#define PLUGIN_PATH_TAG "NMManager-plugin-path"
 
-G_DEFINE_INTERFACE (NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT)
+/*****************************************************************************/
 
 enum {
 	DEVICE_ADDED,
 	COMPONENT_ADDED,
 	LAST_SIGNAL
 };
+
 static guint signals[LAST_SIGNAL] = { 0 };
 
+G_DEFINE_ABSTRACT_TYPE (NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT)
+
+/*****************************************************************************/
+
 gboolean
 nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component)
 {
 	gboolean consumed = FALSE;
 
+	g_return_val_if_fail (NM_IS_DEVICE_FACTORY (factory), FALSE);
+	g_return_val_if_fail (G_IS_OBJECT (component), FALSE);
+
 	g_signal_emit (factory, signals[COMPONENT_ADDED], 0, component, &consumed);
 	return consumed;
 }
@@ -53,21 +63,13 @@ nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *compo
 void
 nm_device_factory_get_supported_types (NMDeviceFactory *factory,
                                        const NMLinkType **out_link_types,
-                                       const char ***out_setting_types)
+                                       const char *const**out_setting_types)
 {
-	const NMLinkType *link_types_fallback;
-	const char **setting_types_fallback;
-
-	g_return_if_fail (factory != NULL);
-
-	if (!out_link_types)
-		out_link_types = &link_types_fallback;
-	if (!out_setting_types)
-		out_setting_types = &setting_types_fallback;
+	g_return_if_fail (NM_IS_DEVICE_FACTORY (factory));
 
-	NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_supported_types (factory,
-	                                                                out_link_types,
-	                                                                out_setting_types);
+	NM_DEVICE_FACTORY_GET_CLASS (factory)->get_supported_types (factory,
+	                                                            out_link_types,
+	                                                            out_setting_types);
 }
 
 void
@@ -75,8 +77,8 @@ nm_device_factory_start (NMDeviceFactory *factory)
 {
 	g_return_if_fail (factory != NULL);
 
-	if (NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start)
-		NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start (factory);
+	if (NM_DEVICE_FACTORY_GET_CLASS (factory)->start)
+		NM_DEVICE_FACTORY_GET_CLASS (factory)->start (factory);
 }
 
 NMDevice *
@@ -87,9 +89,9 @@ nm_device_factory_create_device (NMDeviceFactory *factory,
                                  gboolean *out_ignore,
                                  GError **error)
 {
-	NMDeviceFactoryInterface *interface;
+	NMDeviceFactoryClass *klass;
 	const NMLinkType *link_types = NULL;
-	const char **setting_types = NULL;
+	const char *const*setting_types = NULL;
 	int i;
 	NMDevice *device;
 	gboolean ignore = FALSE;
@@ -133,15 +135,15 @@ nm_device_factory_create_device (NMDeviceFactory *factory,
 		}
 	}
 
-	interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
-	if (!interface->create_device) {
+	klass = NM_DEVICE_FACTORY_GET_CLASS (factory);
+	if (!klass->create_device) {
 		g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
 		             "Device factory %s cannot manage new devices",
 		             G_OBJECT_TYPE_NAME (factory));
 		return NULL;
 	}
 
-	device = interface->create_device (factory, iface, plink, connection, &ignore);
+	device = klass->create_device (factory, iface, plink, connection, &ignore);
 	NM_SET_OUT (out_ignore, ignore);
 	if (!device) {
 		if (ignore) {
@@ -167,8 +169,8 @@ nm_device_factory_get_connection_parent (NMDeviceFactory *factory,
 	if (!nm_connection_is_virtual (connection))
 		return NULL;
 
-	if (NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_parent)
-		return NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_connection_parent (factory, connection);
+	if (NM_DEVICE_FACTORY_GET_CLASS (factory)->get_connection_parent)
+		return NM_DEVICE_FACTORY_GET_CLASS (factory)->get_connection_parent (factory, connection);
 	return NULL;
 }
 
@@ -178,14 +180,14 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
                                         const char *parent_iface,
                                         GError **error)
 {
-	NMDeviceFactoryInterface *klass;
+	NMDeviceFactoryClass *klass;
 	char *ifname;
 
 	g_return_val_if_fail (factory != NULL, NULL);
 	g_return_val_if_fail (connection != NULL, NULL);
 	g_return_val_if_fail (!error || !*error, NULL);
 
-	klass = NM_DEVICE_FACTORY_GET_INTERFACE (factory);
+	klass = NM_DEVICE_FACTORY_GET_CLASS (factory);
 
 	ifname = g_strdup (nm_connection_get_interface_name (connection));
 	if (!ifname && klass->get_connection_iface)
@@ -200,12 +202,10 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
 		return NULL;
 	}
 
-	if (!nm_utils_iface_valid_name (ifname)) {
-		g_set_error (error,
-		             NM_MANAGER_ERROR,
-		             NM_MANAGER_ERROR_FAILED,
-		             "failed to determine interface name: name \"%s\" is invalid",
-		             ifname);
+	if (!nm_utils_is_valid_iface_name (ifname, error)) {
+		g_prefix_error (error,
+		                "failed to determine interface name: name \"%s\" is invalid",
+		                ifname);
 		g_free (ifname);
 		return NULL;
 	}
@@ -213,51 +213,48 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
 	return ifname;
 }
 
-/*******************************************************************/
+/*****************************************************************************/
 
 static void
-nm_device_factory_default_init (NMDeviceFactoryInterface *factory_iface)
+nm_device_factory_init (NMDeviceFactory *self)
 {
-	/* Signals */
+}
+
+static void
+nm_device_factory_class_init (NMDeviceFactoryClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
 	signals[DEVICE_ADDED] = g_signal_new (NM_DEVICE_FACTORY_DEVICE_ADDED,
-	                                      NM_TYPE_DEVICE_FACTORY,
+	                                      G_OBJECT_CLASS_TYPE (object_class),
 	                                      G_SIGNAL_RUN_FIRST,
-	                                      G_STRUCT_OFFSET (NMDeviceFactoryInterface, device_added),
+	                                      G_STRUCT_OFFSET (NMDeviceFactoryClass, device_added),
 	                                      NULL, NULL, NULL,
 	                                      G_TYPE_NONE, 1, NM_TYPE_DEVICE);
 
 	signals[COMPONENT_ADDED] = g_signal_new (NM_DEVICE_FACTORY_COMPONENT_ADDED,
-	                                         NM_TYPE_DEVICE_FACTORY,
+	                                         G_OBJECT_CLASS_TYPE (object_class),
 	                                         G_SIGNAL_RUN_LAST,
-	                                         G_STRUCT_OFFSET (NMDeviceFactoryInterface, component_added),
+	                                         G_STRUCT_OFFSET (NMDeviceFactoryClass, component_added),
 	                                         g_signal_accumulator_true_handled, NULL, NULL,
 	                                         G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT);
 }
 
-/*******************************************************************/
+/*****************************************************************************/
 
-static GSList *internal_types = NULL;
 static GHashTable *factories_by_link = NULL;
 static GHashTable *factories_by_setting = NULL;
 
-void
-_nm_device_factory_internal_register_type (GType factory_type)
-{
-	g_return_if_fail (g_slist_find (internal_types, GUINT_TO_POINTER (factory_type)) == NULL);
-	internal_types = g_slist_prepend (internal_types, GUINT_TO_POINTER (factory_type));
-}
-
 static void __attribute__((destructor))
 _cleanup (void)
 {
-	g_clear_pointer (&internal_types, g_slist_free);
 	g_clear_pointer (&factories_by_link, g_hash_table_unref);
 	g_clear_pointer (&factories_by_setting, g_hash_table_unref);
 }
 
 static NMDeviceFactory *
 find_factory (const NMLinkType *needle_link_types,
-              const char **needle_setting_types)
+              const char *const*needle_setting_types)
 {
 	NMDeviceFactory *found;
 	guint i;
@@ -296,7 +293,7 @@ nm_device_factory_manager_find_factory_for_link_type (NMLinkType link_type)
 NMDeviceFactory *
 nm_device_factory_manager_find_factory_for_connection (NMConnection *connection)
 {
-	const char *stypes[2] = { nm_connection_get_connection_type (connection), NULL };
+	const char *const stypes[2] = { nm_connection_get_connection_type (connection), NULL };
 
 	g_assert (stypes[0]);
 	return find_factory (NULL, stypes);
@@ -332,98 +329,6 @@ nm_device_factory_manager_for_each_factory (NMDeviceFactoryManagerFactoryFunc ca
 	g_slist_free (list);
 }
 
-#define PLUGIN_PREFIX "libnm-device-plugin-"
-#define PLUGIN_PATH_TAG "NMManager-plugin-path"
-
-struct read_device_factory_paths_data {
-	char *path;
-	struct stat st;
-};
-
-static gint
-read_device_factory_paths_sort_fcn (gconstpointer a, gconstpointer b)
-{
-	const struct read_device_factory_paths_data *da = a;
-	const struct read_device_factory_paths_data *db = b;
-	time_t ta, tb;
-
-	ta = MAX (da->st.st_mtime, da->st.st_ctime);
-	tb = MAX (db->st.st_mtime, db->st.st_ctime);
-
-	if (ta < tb)
-		return 1;
-	if (ta > tb)
-		return -1;
-	return 0;
-}
-
-static char**
-read_device_factory_paths (void)
-{
-	GDir *dir;
-	GError *error = NULL;
-	const char *item;
-	GArray *paths;
-	char **result;
-	guint i;
-
-	dir = g_dir_open (NMPLUGINDIR, 0, &error);
-	if (!dir) {
-		nm_log_warn (LOGD_PLATFORM, "device plugin: failed to open directory %s: %s",
-		             NMPLUGINDIR,
-		             error->message);
-		g_clear_error (&error);
-		return NULL;
-	}
-
-	paths = g_array_new (FALSE, FALSE, sizeof (struct read_device_factory_paths_data));
-
-	while ((item = g_dir_read_name (dir))) {
-		int errsv;
-		struct read_device_factory_paths_data data;
-
-		if (!g_str_has_prefix (item, PLUGIN_PREFIX))
-			continue;
-		if (g_str_has_suffix (item, ".la"))
-			continue;
-
-		data.path = g_build_filename (NMPLUGINDIR, item, NULL);
-
-		if (stat (data.path, &data.st) != 0) {
-			errsv = errno;
-			nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (error during stat: %s)", data.path, strerror (errsv));
-			goto NEXT;
-		}
-		if (!S_ISREG (data.st.st_mode))
-			goto NEXT;
-		if (data.st.st_uid != 0) {
-			nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (file must be owned by root)", data.path);
-			goto NEXT;
-		}
-		if (data.st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) {
-			nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (invalid file permissions)", data.path);
-			goto NEXT;
-		}
-
-		g_array_append_val (paths, data);
-		continue;
-NEXT:
-		g_free (data.path);
-	}
-	g_dir_close (dir);
-
-	/* sort filenames by modification time. */
-	g_array_sort (paths, read_device_factory_paths_sort_fcn);
-
-	result = g_new (char *, paths->len + 1);
-	for (i = 0; i < paths->len; i++)
-		result[i] = g_array_index (paths, struct read_device_factory_paths_data, i).path;
-	result[i] = NULL;
-
-	g_array_free (paths, TRUE);
-	return result;
-}
-
 static gboolean
 _add_factory (NMDeviceFactory *factory,
               gboolean check_duplicates,
@@ -433,7 +338,7 @@ _add_factory (NMDeviceFactory *factory,
 {
 	NMDeviceFactory *found = NULL;
 	const NMLinkType *link_types = NULL;
-	const char **setting_types = NULL;
+	const char *const*setting_types = NULL;
 	int i;
 
 	g_return_val_if_fail (factories_by_link, FALSE);
@@ -463,12 +368,22 @@ _add_factory (NMDeviceFactory *factory,
 	return TRUE;
 }
 
+static void
+_load_internal_factory (GType factory_gtype,
+                        NMDeviceFactoryManagerFactoryFunc callback,
+                        gpointer user_data)
+{
+	NMDeviceFactory *factory;
+
+	factory = (NMDeviceFactory *) g_object_new (factory_gtype, NULL);
+	_add_factory (factory, FALSE, "internal", callback, user_data);
+}
+
 void
 nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc callback,
                                           gpointer user_data)
 {
 	NMDeviceFactory *factory;
-	const GSList *iter;
 	GError *error = NULL;
 	char **path, **paths;
 
@@ -478,16 +393,26 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call
 	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);
 
-	/* Register internal factories first */
-	for (iter = internal_types; iter; iter = iter->next) {
-		GType ftype = (GType) GPOINTER_TO_SIZE (iter->data);
-
-		factory = (NMDeviceFactory *) g_object_new (ftype, NULL);
-		g_assert (factory);
-		_add_factory (factory, FALSE, "internal", callback, user_data);
-	}
-
-	paths = read_device_factory_paths ();
+#define _ADD_INTERNAL(get_type_fcn) \
+	G_STMT_START { \
+		GType get_type_fcn (void); \
+		_load_internal_factory (get_type_fcn (), \
+		                        callback, user_data); \
+	} G_STMT_END
+
+	_ADD_INTERNAL (nm_bond_device_factory_get_type);
+	_ADD_INTERNAL (nm_bridge_device_factory_get_type);
+	_ADD_INTERNAL (nm_ethernet_device_factory_get_type);
+	_ADD_INTERNAL (nm_infiniband_device_factory_get_type);
+	_ADD_INTERNAL (nm_ip_tunnel_device_factory_get_type);
+	_ADD_INTERNAL (nm_macsec_device_factory_get_type);
+	_ADD_INTERNAL (nm_macvlan_device_factory_get_type);
+	_ADD_INTERNAL (nm_tun_device_factory_get_type);
+	_ADD_INTERNAL (nm_veth_device_factory_get_type);
+	_ADD_INTERNAL (nm_vlan_device_factory_get_type);
+	_ADD_INTERNAL (nm_vxlan_device_factory_get_type);
+
+	paths = nm_utils_read_plugin_paths (NMPLUGINDIR, PLUGIN_PREFIX);
 	if (!paths)
 		return;