[PATCH 5/6] VLAN: create virtual kernel devices



Creates virtual kernel devices as needed.
Since the manager is initialized after the connections have been loaded,
no CONNECTIONS_ADDED notification is received for connections parsed at
startup.
Therefore we have to walk the loaded connections and look for connections for
bonding,vlan or bridge, and create corresponding virtual devices.

Connections added on the fly are handled via the notifications.
Connection renaming and deleting is not supported yet.

This patch is written by Thomas Graf <tgraf redhat com>.

Signed-off-by: Weiping Pan <wpan redhat com>
---
 src/nm-manager.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/src/nm-manager.c b/src/nm-manager.c
index b09cceb..c977d6c 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -920,16 +920,84 @@ get_active_connections (NMManager *manager, NMConnection *filter)
 	return active;
 }
 
+static gboolean
+connection_needs_virtual_device (NMConnection *connection)
+{
+	if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME))
+		return TRUE;
+
+	return FALSE;
+}
+
+static gboolean
+system_update_virtual_device (NMConnection *connection)
+{
+	if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) {
+		NMSettingVLAN *s_vlan;
+
+		s_vlan = nm_connection_get_setting_vlan (connection);
+		g_assert (s_vlan);
+
+		return  nm_system_add_vlan_device (s_vlan);
+	}
+
+	return TRUE;
+}
+
+static void
+system_create_virtual_devices (NMSettings *settings)
+{
+	GSList *iter, *connections;
+
+	nm_log_info (LOGD_CORE, "Creating virtual devices");
+
+	connections = nm_settings_get_connections (settings);
+	for (iter = connections; iter; iter = g_slist_next (iter)) {
+		NMConnection *connection = NM_CONNECTION (iter->data);
+
+		if (connection_needs_virtual_device (connection))
+			system_update_virtual_device (connection);
+	}
+
+	g_slist_free (connections);
+}
+
 /*******************************************************************/
 /* Settings stuff via NMSettings                                   */
 /*******************************************************************/
 
 static void
-connections_changed (NMSettings *settings,
+connection_added (NMSettings *settings,
+                     NMSettingsConnection *connection,
+                     NMManager *manager)
+{
+	bluez_manager_resync_devices (manager);
+
+	if (connection_needs_virtual_device (NM_CONNECTION (connection)))
+		system_update_virtual_device (NM_CONNECTION (connection));
+}
+
+static void
+connection_changed (NMSettings *settings,
                      NMSettingsConnection *connection,
                      NMManager *manager)
 {
 	bluez_manager_resync_devices (manager);
+
+	/* FIXME: Some virtual devices may need to be updated in the future. */
+}
+
+static void
+connection_removed (NMSettings *settings,
+                     NMSettingsConnection *connection,
+                     NMManager *manager)
+{
+	bluez_manager_resync_devices (manager);
+
+	/*
+	 * Do not delete existing virtual devices to keep connectivity up.
+	 * Virtual devices are reused when NetworkManager is restarted.
+	 */
 }
 
 static void
@@ -2823,6 +2891,12 @@ nm_manager_start (NMManager *self)
 
 	nm_udev_manager_query_devices (priv->udev_mgr);
 	bluez_manager_resync_devices (self);
+
+	/*
+	 * Connections added before the manager is started do not emit
+	 * connection-added signals thus devices have to be created manually.
+	 */
+	system_create_virtual_devices (priv->settings);
 }
 
 static gboolean
@@ -3099,13 +3173,13 @@ nm_manager_new (NMSettings *settings,
 	g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
 	                  G_CALLBACK (system_hostname_changed_cb), singleton);
 	g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
-	                  G_CALLBACK (connections_changed), singleton);
+	                  G_CALLBACK (connection_added), singleton);
 	g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
-	                  G_CALLBACK (connections_changed), singleton);
+	                  G_CALLBACK (connection_changed), singleton);
 	g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
-	                  G_CALLBACK (connections_changed), singleton);
+	                  G_CALLBACK (connection_removed), singleton);
 	g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
-	                  G_CALLBACK (connections_changed), singleton);
+	                  G_CALLBACK (connection_changed), singleton);
 
 	dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton));
 
-- 
1.7.4.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]