Hi there,
Michael asked to forward this to the list, so here it is...

The patch 0005-Mark-virtual-ethernet-interfaces-as-unmanaged.patch
(debian Jessie) messes up with my virtual interfaces (vmware
vmnet1/vmnet8).
Even if I set them manually unmanaged (from /etc/network/interfaces or
using keyfile plugin), they finally appear connected and make me lose my
internet connection if my ethernet link is down and I'm using WIFI.
I'm not sure exactly what's going on with the internals of
Network-Manager in this case but setting the default unmanaged flag on
the interfaces seems to have some negative side effects.
However, I think the idea of not managing the virtual interfaces is OK,
in particular for not expert users.
You'll find enclosed a small plugin that detects those virtual
interfaces and adds them to the unmanaged list. This is based on the
keyfile plugin.
Please feel free to use it (or not).
(0005-Mark-virtual-ethernet-interfaces-as-unmanaged.patch has to be
reverted for this plugin to work)

Thanks for your work anyway.

Nicolas
From 0fbcb8c9aecd652926c58553f401de2e5be1e785 Mon Sep 17 00:00:00 2001
From: boul <[email protected]>
Date: Sun, 12 Oct 2014 23:56:03 +0200
Subject: [PATCH 1/1] Added ifvirt plugin

---
 configure.ac                            |   5 +
 src/settings/plugins/Makefile.am        |   4 +
 src/settings/plugins/ifvirt/Makefile.am |  41 +++++
 src/settings/plugins/ifvirt/plugin.c    | 271 ++++++++++++++++++++++++++++++++
 src/settings/plugins/ifvirt/plugin.h    |  50 ++++++
 5 files changed, 371 insertions(+)
 create mode 100644 src/settings/plugins/ifvirt/Makefile.am
 create mode 100644 src/settings/plugins/ifvirt/plugin.c
 create mode 100644 src/settings/plugins/ifvirt/plugin.h

diff --git a/configure.ac b/configure.ac
index 94b0758..0e1caf7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,6 +95,7 @@ AC_ARG_ENABLE(ifcfg-rh, AS_HELP_STRING([--enable-ifcfg-rh], [enable ifcfg-rh con
 AC_ARG_ENABLE(ifcfg-suse, AS_HELP_STRING([--enable-ifcfg-suse], [enable ifcfg-suse configuration plugin (SUSE)]))
 AC_ARG_ENABLE(ifupdown, AS_HELP_STRING([--enable-ifupdown], [enable ifupdown configuration plugin (Debian/Ubuntu)]))
 AC_ARG_ENABLE(ifnet, AS_HELP_STRING([--enable-ifnet], [enable ifnet configuration plugin (Gentoo)]))
+AC_ARG_ENABLE(ifnet, AS_HELP_STRING([--enable-ifvirt], [enable ifvirt configuration plugin]))
 # Default alternative plugins by distribution
 AS_IF([test -z "$enable_ifcfg_rh"], AC_CHECK_FILE(/etc/redhat-release, enable_ifcfg_rh=yes))
 AS_IF([test -z "$enable_ifcfg_rh"], AC_CHECK_FILE(/etc/fedora-release, enable_ifcfg_rh=yes))
@@ -107,11 +108,13 @@ AS_IF([test -z "$enable_ifcfg_rh"], enable_ifcfg_rh=no)
 AS_IF([test -z "$enable_ifcfg_suse"], enable_ifcfg_suse=no)
 AS_IF([test -z "$enable_ifupdown"], enable_ifupdown=no)
 AS_IF([test -z "$enable_ifnet"], enable_ifnet=no)
+AS_IF([test -z "$enable_ifvirt"], enable_ifvirt=no)
 # Create automake conditionals
 AM_CONDITIONAL(CONFIG_PLUGIN_IFCFG_RH, test "$enable_ifcfg_rh" = "yes")
 AM_CONDITIONAL(CONFIG_PLUGIN_IFCFG_SUSE, test "$enable_ifcfg_suse" = "yes")
 AM_CONDITIONAL(CONFIG_PLUGIN_IFUPDOWN, test "$enable_ifupdown" = "yes")
 AM_CONDITIONAL(CONFIG_PLUGIN_IFNET, test "$enable_ifnet" = "yes")
+AM_CONDITIONAL(CONFIG_PLUGIN_IFVIRT, test "$enable_ifvirt" = "yes")
 
 if test "$enable_ifcfg_rh" = "yes"; then
     DISTRO_NETWORK_SERVICE=network.service
@@ -794,6 +797,7 @@ src/settings/plugins/ifcfg-suse/Makefile
 src/settings/plugins/keyfile/Makefile
 src/settings/plugins/keyfile/tests/Makefile
 src/settings/plugins/keyfile/tests/keyfiles/Makefile
+src/settings/plugins/ifvirt/Makefile
 src/settings/plugins/example/Makefile
 src/settings/tests/Makefile
 src/platform/Makefile
@@ -906,6 +910,7 @@ echo "  ifcfg-rh: ${enable_ifcfg_rh}"
 echo "  ifcfg-suse: ${enable_ifcfg_suse}"
 echo "  ifupdown: ${enable_ifupdown}"
 echo "  ifnet: ${enable_ifnet}"
+echo "  ifvirt: ${enable_ifvirt}"
 echo
 
 echo "Handlers for /etc/resolv.conf:"
diff --git a/src/settings/plugins/Makefile.am b/src/settings/plugins/Makefile.am
index 41694e7..2ae7444 100644
--- a/src/settings/plugins/Makefile.am
+++ b/src/settings/plugins/Makefile.am
@@ -17,3 +17,7 @@ endif
 if CONFIG_PLUGIN_IFNET
 SUBDIRS+=ifnet
 endif
+
+if CONFIG_PLUGIN_IFVIRT
+SUBDIRS+=ifvirt
+endif
diff --git a/src/settings/plugins/ifvirt/Makefile.am b/src/settings/plugins/ifvirt/Makefile.am
new file mode 100644
index 0000000..ab15e55
--- /dev/null
+++ b/src/settings/plugins/ifvirt/Makefile.am
@@ -0,0 +1,41 @@
+SUBDIRS = .
+
+@GNOME_CODE_COVERAGE_RULES@
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/config \
+	-I$(top_srcdir)/src/logging \
+	-I$(top_srcdir)/src/settings \
+	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util \
+	-DG_LOG_DOMAIN=\""NetworkManager-ifvirt"\" \
+	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	$(POLKIT_CFLAGS) \
+	$(GUDEV_CFLAGS) \
+	-DNMCONFDIR=\"$(nmconfdir)\"
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifvirt.la
+
+#####################################
+
+libnm_settings_plugin_ifvirt_la_SOURCES = \
+	plugin.c \
+	plugin.h
+
+libnm_settings_plugin_ifvirt_la_LIBADD = \
+	$(top_builddir)/libnm-util/libnm-util.la \
+	$(GLIB_LIBS) \
+	$(GUDEV_LIBS)
+
+libnm_settings_plugin_ifvirt_la_LDFLAGS = -rdynamic
+
+ifvirtdir=$(sysconfdir)/NetworkManager/system-connections
+
+install-data-hook:
+	$(mkinstalldirs) -m 0755 $(DESTDIR)$(ifvirtdir)
+
diff --git a/src/settings/plugins/ifvirt/plugin.c b/src/settings/plugins/ifvirt/plugin.c
new file mode 100644
index 0000000..cac1443
--- /dev/null
+++ b/src/settings/plugins/ifvirt/plugin.c
@@ -0,0 +1,271 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Nicolas Boulicault
+ */
+
+#include <config.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include <gmodule.h>
+#include <glib.h>
+#include <gudev/gudev.h>
+
+#include <nm-logging.h>
+
+#include "plugin.h"
+#include "nm-system-config-interface.h"
+//#include "utils.h"
+
+static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginIfVirt, sc_plugin_ifvirt, G_TYPE_OBJECT, 0,
+				    G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+									  system_config_interface_init))
+
+#define SC_PLUGIN_IFVIRT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFVIRT, SCPluginIfVirtPrivate))
+
+typedef struct {
+	GUdevClient *client;
+	GHashTable  *virtual_ifaces;
+} SCPluginIfVirtPrivate;
+
+/*
+ * Return a list of device specifications which NetworkManager should not
+ * manage.  Returned list will be freed by the system settings service, and
+ * each element must be allocated using g_malloc() or its variants.
+ */
+static GSList*
+sc_plugin_ifvirt_get_unmanaged_specs (NMSystemConfigInterface *config)
+{
+	SCPluginIfVirtPrivate *priv = SC_PLUGIN_IFVIRT_GET_PRIVATE(config);
+	GSList *specs = NULL;
+	GHashTableIter iter;
+	GUdevDevice *device;
+	const char *iface;
+
+	g_hash_table_iter_init (&iter, priv->virtual_ifaces);
+	while (g_hash_table_iter_next (&iter, (gpointer) &iface, (gpointer) &device)) {
+		specs = g_slist_append (specs, g_strdup_printf ("interface-name:%s", iface));
+	}
+
+	return specs;
+}
+
+gboolean is_iface_virtual(const char *iface, const char *sysfs_path)
+{
+	const char *virt_path = "/sys/devices/virtual/net";
+
+	// loopback is already handled by network-manager
+	if (g_ascii_strncasecmp(iface, "lo", strlen(iface)) == 0)
+		return FALSE;
+
+	if (g_ascii_strncasecmp (sysfs_path, virt_path, strlen (virt_path)) == 0) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+udev_device_added (SCPluginIfVirt *self, GUdevDevice *device)
+{
+	SCPluginIfVirtPrivate *priv = SC_PLUGIN_IFVIRT_GET_PRIVATE (self);
+	const char *iface, *path;
+
+	iface = g_udev_device_get_name (device);
+	path = g_udev_device_get_sysfs_path (device);
+	if (!iface || !path)
+		return;
+
+	if (is_iface_virtual(iface, path)) {
+		nm_log_info(LOGD_SETTINGS, "ifvirt: iface %s is virtual, adding to unmanaged ifaces", iface);
+		g_hash_table_insert (priv->virtual_ifaces, g_strdup (iface), g_object_ref (device));
+	}
+
+	g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+udev_device_removed(SCPluginIfVirt *self, GUdevDevice *device)
+{
+	SCPluginIfVirtPrivate *priv = SC_PLUGIN_IFVIRT_GET_PRIVATE (self);
+	const char *iface, *path;
+
+	iface = g_udev_device_get_name (device);
+	path = g_udev_device_get_sysfs_path (device);
+	if (!iface || !path)
+		return;
+
+	// iface is not in virtual ifaces list, do nothing
+	if (!g_hash_table_contains(priv->virtual_ifaces, iface)) {
+		return;
+	}
+
+	g_hash_table_remove(priv->virtual_ifaces, iface);
+	g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+handle_uevent (GUdevClient *client,
+			   const char *action,
+			   GUdevDevice *device,
+			   gpointer user_data)
+{
+	SCPluginIfVirt *self = SC_PLUGIN_IFVIRT(user_data);
+	const char *subsys;
+
+	g_return_if_fail (action != NULL);
+
+	subsys = g_udev_device_get_subsystem (device);
+	g_return_if_fail (subsys != NULL);
+	g_return_if_fail (strcmp (subsys, "net") == 0);
+
+	if (!strcmp (action, "add"))
+		udev_device_added (self, device);
+	else if (!strcmp (action, "remove"))
+		udev_device_removed (self, device);
+}
+
+static void
+SCPluginIfVirt_init (NMSystemConfigInterface *plugin)
+{
+	const gchar *subsys[2] = { "net", NULL };
+	GList *all_interfaces, *iter;
+
+	SCPluginIfVirt *self = SC_PLUGIN_IFVIRT (plugin);
+	SCPluginIfVirtPrivate *priv = SC_PLUGIN_IFVIRT_GET_PRIVATE (self);
+
+	priv->virtual_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+	priv->client = g_udev_client_new (subsys);
+	if (!priv->client) {
+		nm_log_warn (LOGD_SETTINGS, "ifvirt: error initializing libgudev !");
+	} else
+		g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
+
+	// Get list of network devices, and simulate addition to check virtual interfaces
+	all_interfaces = g_udev_client_query_by_subsystem(priv->client, subsys[0]);
+	for (iter = all_interfaces; iter; iter = g_list_next (iter)) {
+		udev_device_added (self, G_UDEV_DEVICE (iter->data));
+		g_object_unref (G_UDEV_DEVICE (iter->data));
+	}
+
+	g_list_free (all_interfaces);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+            GValue *value, GParamSpec *pspec)
+{
+    switch (prop_id) {
+    case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+		g_value_set_string (value, IFVIRT_PLUGIN_NAME);
+        break;
+    case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+		g_value_set_string (value, IFVIRT_PLUGIN_INFO);
+        break;
+	case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+		g_value_set_uint (value, 0);
+		break;
+    default:
+		nm_log_warn(LOGD_SETTINGS, "ifvirt: get_property %d not implemented !", prop_id);
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+              const GValue *value, GParamSpec *pspec)
+{
+	switch (prop_id) {
+	default:
+		nm_log_warn(LOGD_SETTINGS, "ifvirt: set_property %d not implemented !", prop_id);
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+	system_config_interface_class->get_unmanaged_specs = sc_plugin_ifvirt_get_unmanaged_specs;
+	system_config_interface_class->init = SCPluginIfVirt_init;
+}
+
+static void
+dispose (GObject *object)
+{
+	SCPluginIfVirt *self = SC_PLUGIN_IFVIRT (object);
+	SCPluginIfVirtPrivate *priv = SC_PLUGIN_IFVIRT_GET_PRIVATE (self);
+
+	if (priv->virtual_ifaces)
+		g_hash_table_destroy(priv->virtual_ifaces);
+
+	if (priv->client)
+		g_object_unref (priv->client);
+
+	G_OBJECT_CLASS (sc_plugin_ifvirt_parent_class)->dispose (object);
+}
+
+static void sc_plugin_ifvirt_init(SCPluginIfVirt *plugin)
+{
+}
+
+static void
+sc_plugin_ifvirt_class_init (SCPluginIfVirtClass *req_class)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+    g_type_class_add_private (req_class, sizeof (SCPluginIfVirtPrivate));
+
+    object_class->dispose = dispose;
+    object_class->get_property = get_property;
+    object_class->set_property = set_property;
+
+    g_object_class_override_property (object_class,
+                                      NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+                                      NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+    g_object_class_override_property (object_class,
+                                      NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+                                      NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+	g_object_class_override_property (object_class,
+									  NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+									  NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+	g_object_class_override_property (object_class,
+									  NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+									  NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+	static SCPluginIfVirt *singleton = NULL;
+
+	if (!singleton) {
+		singleton = SC_PLUGIN_IFVIRT (g_object_new (SC_TYPE_PLUGIN_IFVIRT, NULL));
+	} else
+		g_object_ref (singleton);
+
+	return G_OBJECT (singleton);
+}
diff --git a/src/settings/plugins/ifvirt/plugin.h b/src/settings/plugins/ifvirt/plugin.h
new file mode 100644
index 0000000..1d834da
--- /dev/null
+++ b/src/settings/plugins/ifvirt/plugin.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - ifvirt plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Nicolas Boulicault
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#define IFVIRT_PLUGIN_NAME "ifvirt"
+#define IFVIRT_PLUGIN_INFO "(c) 2014 Nicolas Boulicault ([email protected])"
+
+#include <glib-object.h>
+
+#define SC_TYPE_PLUGIN_IFVIRT            (sc_plugin_ifvirt_get_type ())
+#define SC_PLUGIN_IFVIRT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFVIRT, SCPluginIfVirt))
+#define SC_PLUGIN_IFVIRT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFVIRT, SCPluginIfVirtClass))
+#define SC_IS_PLUGIN_IFVIRT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFVIRT))
+#define SC_IS_PLUGIN_IFVIRT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_PLUGIN_IFVIRT))
+#define SC_PLUGIN_IFVIRT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFVIRT, SCPluginIfVirtClass))
+
+typedef struct {
+	GObject parent;
+} SCPluginIfVirt;
+
+typedef struct {
+	GObjectClass parent;
+} SCPluginIfVirtClass;
+
+GType sc_plugin_ifvirt_get_type (void);
+
+//GQuark ifvirt_plugin_error_quark (void);
+
+GObject *nm_settings_ifvirt_plugin_new (void);
+
+#endif	/* _PLUGIN_H_ */
-- 
2.1.1

_______________________________________________
networkmanager-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to