NetworkManager r3738 - in trunk: . src src/dnsmasq-manager



Author: dcbw
Date: Tue Jun 10 02:52:33 2008
New Revision: 3738
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3738&view=rev

Log:
2008-06-09  Dan Williams  <dcbw redhat com>

	* src/dnsmasq-manager/nm-dnsmasq-manager.c
	  src/dnsmasq-manager/nm-dnsmasq-manager.h
		- (create_dm_cmd_line): use the IP4 address of the ip4-config to
			calculate the addresses passed to dnsmasq instead of hard-coding
			them

	* src/nm-device.c
		- (nm_device_new_ip4_shared_config): be somewhat dynamic when choosing
			IP addresses for shared connections to guard against shared
			connection address collisions
		- (real_act_stage4_get_ip4_config): handle possible NULL ip4-configs on
			error conditions
		- (nm_device_activate_stage5_ip_config_commit): pass ip4-config to
			the dnsmasq manager



Modified:
   trunk/ChangeLog
   trunk/src/dnsmasq-manager/nm-dnsmasq-manager.c
   trunk/src/dnsmasq-manager/nm-dnsmasq-manager.h
   trunk/src/nm-device.c

Modified: trunk/src/dnsmasq-manager/nm-dnsmasq-manager.c
==============================================================================
--- trunk/src/dnsmasq-manager/nm-dnsmasq-manager.c	(original)
+++ trunk/src/dnsmasq-manager/nm-dnsmasq-manager.c	Tue Jun 10 02:52:33 2008
@@ -225,11 +225,17 @@
 }
 
 static NMCmdLine *
-create_dm_cmd_line (const char *iface, const char *pidfile, GError **error)
+create_dm_cmd_line (const char *iface,
+                    NMIP4Config *ip4_config,
+                    const char *pidfile,
+                    GError **error)
 {
 	const char *dm_binary;
 	NMCmdLine *cmd;
-	char *s;
+	GString *s;
+	const NMSettingIP4Address *tmp;
+	struct in_addr addr;
+	char buf[INET_ADDRSTRLEN + 1];
 
 	dm_binary = nm_find_dnsmasq ();
 	if (!dm_binary) {
@@ -238,24 +244,68 @@
 		return NULL;
 	}
 
+	/* Find the IP4 address to use */
+	tmp = nm_ip4_config_get_address (ip4_config, 0);
+
 	/* Create dnsmasq command line */
 	cmd = nm_cmd_line_new ();
 	nm_cmd_line_add_string (cmd, dm_binary);
 
 	nm_cmd_line_add_string (cmd, "--no-hosts");
 	nm_cmd_line_add_string (cmd, "--keep-in-foreground");
-	nm_cmd_line_add_string (cmd, "--listen-address=10.42.43.1");
 	nm_cmd_line_add_string (cmd, "--bind-interfaces");
 	nm_cmd_line_add_string (cmd, "--no-poll");
-	nm_cmd_line_add_string (cmd, "--dhcp-range=10.42.43.10,10.42.43.100,60m");
+
+	s = g_string_new ("--listen-address=");
+	addr.s_addr = tmp->address;
+	if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
+		nm_warning ("%s: error converting IP4 address 0x%X",
+		            __func__, ntohl (addr.s_addr));
+		goto error;
+	}
+	g_string_append (s, buf);
+	nm_cmd_line_add_string (cmd, s->str);
+	g_string_free (s, TRUE);
+
+	s = g_string_new ("--dhcp-range=");
+
+	/* Add start of address range */
+	addr.s_addr = tmp->address + ntohl (9);
+	if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
+		nm_warning ("%s: error converting IP4 address 0x%X",
+		            __func__, ntohl (addr.s_addr));
+		goto error;
+	}
+	g_string_append (s, buf);
+
+	g_string_append_c (s, ',');
+
+	/* Add end of address range */
+	addr.s_addr = tmp->address + ntohl (99);
+	if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
+		nm_warning ("%s: error converting IP4 address 0x%X",
+		            __func__, ntohl (addr.s_addr));
+		goto error;
+	}
+	g_string_append (s, buf);
+
+	g_string_append (s, ",60m");
+	nm_cmd_line_add_string (cmd, s->str);
+	g_string_free (s, TRUE);
+
 	nm_cmd_line_add_string (cmd, "--dhcp-option=option:router,0.0.0.0");
 	nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50");
 
-	s = g_strdup_printf ("--pid-file=%s", pidfile);
-	nm_cmd_line_add_string (cmd, s);
-	g_free (s);
+	s = g_string_new ("--pid-file=");
+	g_string_append (s, pidfile);
+	nm_cmd_line_add_string (cmd, s->str);
+	g_string_free (s, TRUE);
 
 	return cmd;
+
+error:
+	nm_cmd_line_destroy (cmd);
+	return NULL;
 }
 
 static void
@@ -300,7 +350,9 @@
 }
 
 gboolean
-nm_dnsmasq_manager_start (NMDnsMasqManager *manager, GError **error)
+nm_dnsmasq_manager_start (NMDnsMasqManager *manager,
+                          NMIP4Config *ip4_config,
+                          GError **error)
 {
 	NMDnsMasqManagerPrivate *priv;
 	NMCmdLine *dm_cmd;
@@ -315,7 +367,7 @@
 
 	kill_existing_for_iface (priv->iface, priv->pidfile);
 
-	dm_cmd = create_dm_cmd_line (priv->iface, priv->pidfile, error);
+	dm_cmd = create_dm_cmd_line (priv->iface, ip4_config, priv->pidfile, error);
 	if (!dm_cmd)
 		return FALSE;
 

Modified: trunk/src/dnsmasq-manager/nm-dnsmasq-manager.h
==============================================================================
--- trunk/src/dnsmasq-manager/nm-dnsmasq-manager.h	(original)
+++ trunk/src/dnsmasq-manager/nm-dnsmasq-manager.h	Tue Jun 10 02:52:33 2008
@@ -6,6 +6,8 @@
 #include <glib/gtypes.h>
 #include <glib-object.h>
 
+#include "nm-ip4-config.h"
+
 #define NM_TYPE_DNSMASQ_MANAGER            (nm_dnsmasq_manager_get_type ())
 #define NM_DNSMASQ_MANAGER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DNSMASQ_MANAGER, NMDnsMasqManager))
 #define NM_DNSMASQ_MANAGER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DNSMASQ_MANAGER, NMDnsMasqManagerClass))
@@ -35,7 +37,9 @@
 
 NMDnsMasqManager *nm_dnsmasq_manager_new (const char *iface);
 
-gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, GError **error);
+gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager,
+                                   NMIP4Config *ip4_config,
+                                   GError **error);
 
 void     nm_dnsmasq_manager_stop  (NMDnsMasqManager *manager);
 

Modified: trunk/src/nm-device.c
==============================================================================
--- trunk/src/nm-device.c	(original)
+++ trunk/src/nm-device.c	Tue Jun 10 02:52:33 2008
@@ -653,20 +653,58 @@
 	return config;
 }
 
+static GHashTable *shared_ips = NULL;
+
+static void
+release_shared_ip (gpointer data)
+{
+	g_hash_table_remove (shared_ips, data);
+}
+
+static guint32
+reserve_shared_ip (void)
+{
+	guint32 start = (guint32) ntohl (0x0a2a2b01); /* 10.42.43.1 */
+	guint32 count = 0;
+
+	while (g_hash_table_lookup (shared_ips, (gpointer) (start + count))) {
+		count += ntohl (0x100);
+		if (count > ntohl (0xFE00)) {
+			nm_warning ("%s: ran out of shared IP addresses!", __func__);
+			return 0;
+		}
+	}
+
+	g_hash_table_insert (shared_ips, (gpointer) (start + count), GUINT_TO_POINTER (TRUE));
+	return start + count;
+}
+
 static NMIP4Config *
 nm_device_new_ip4_shared_config (NMDevice *self)
 {
 	NMIP4Config *config = NULL;
 	NMSettingIP4Address *addr;
+	guint32 tmp_addr;
 
 	g_return_val_if_fail (self != NULL, NULL);
 
+	if (G_UNLIKELY (shared_ips == NULL))
+		shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+	tmp_addr = reserve_shared_ip ();
+	if (!tmp_addr)
+		return NULL;
+
 	config = nm_ip4_config_new ();
 	addr = g_malloc0 (sizeof (NMSettingIP4Address));
-	addr->address = (guint32) ntohl (0x0a2a2b01); /* 10.42.43.1 */
+	addr->address = tmp_addr;
 	addr->netmask = (guint32) ntohl (0xFFFFFF00); /* 255.255.255.0 */
 	nm_ip4_config_take_address (config, addr);
 
+	/* Remove the address lock when the object gets disposed */
+	g_object_set_data_full (G_OBJECT (config), "shared-ip",
+	                        GUINT_TO_POINTER (addr->address), release_shared_ip);
+
 	return config;
 }
 
@@ -690,7 +728,8 @@
 	if (nm_device_get_use_dhcp (self)) {
 		*config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
 											 nm_device_get_iface (self));
-		nm_utils_merge_ip4_config (*config, s_ip4);
+		if (*config)
+			nm_utils_merge_ip4_config (*config, s_ip4);
 	} else {
 		g_assert (s_ip4);
 
@@ -698,10 +737,12 @@
 			*config = nm_device_new_ip4_autoip_config (self);
 		} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
 			*config = nm_ip4_config_new ();
-			nm_utils_merge_ip4_config (*config, s_ip4);
+			if (*config)
+				nm_utils_merge_ip4_config (*config, s_ip4);
 		} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
 			*config = nm_device_new_ip4_shared_config (self);
-			priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
+			if (*config)
+				priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
 		}
 	}
 
@@ -895,7 +936,7 @@
 	if (s_ip4 && !strcmp (s_ip4->method, "shared")) {
 		GError *error = NULL;
 
-		if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, &error)) {
+		if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) {
 			nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
 			g_error_free (error);
 			nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);



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