NetworkManager r3898 - in trunk: . introspection libnm-glib libnm-util src src/dhcp-manager src/vpn-manager system-settings/plugins/ifcfg-fedora system-settings/plugins/keyfile



Author: dcbw
Date: Wed Aug  6 22:23:48 2008
New Revision: 3898
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3898&view=rev

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

	* libnm-glib/nm-ip4-config.c
	  libnm-glib/nm-ip4-config.h
		- Add 'routes' property

	* libnm-util/nm-setting-vpn.c
	  libnm-util/nm-setting-vpn.h
		- Remove 'routes' property

	* libnm-util/nm-setting-ip4-config.c
	  libnm-util/nm-setting-ip4-config.h
		- 'ignore-dhcp-dns' renamed to 'ignore-auto-dns'
		- Add 'ignore-auto-routes' property
		- 'routes' exposed over D-Bus is now an array of array of uint (4) to 
			accomodate route metrics
		- 'routes' exposed in C is now a list of NMSettingIP4Route structures

	* libnm-util/nm-utils.c
	  libnm-util/nm-utils.h
		- Add helpers for marshalling IP4 routes

	* src/NetworkManagerUtils.c
		- (nm_utils_merge_ip4_config): handle property renames and new route
			structure

	* src/NetworkManagerSystem.c
		- (nm_system_device_set_ip4_route, nm_system_device_set_from_ip4_config,
		   nm_system_vpn_device_set_from_ip4_config): respect route metrics

	* src/dhcp-manager/nm-dhcp-manager.c
		- (nm_dhcp_manager_get_ip4_config): handle new route structure

	* system-settings/plugins/ifcfg-fedora/reader.c
	  system-settings/plugins/ifcfg-fedora/writer.c
		- Handle routes separately from addresses now that routes have a different
			format

	* introspection/nm-ip4-config.xml
	  src/nm-ip4-config.c
	  src/nm-ip4-config.h
		- Rename internal routing functions
		- 'static-routes' renamed to 'routes'



Modified:
   trunk/ChangeLog
   trunk/introspection/nm-ip4-config.xml
   trunk/libnm-glib/nm-ip4-config.c
   trunk/libnm-glib/nm-ip4-config.h
   trunk/libnm-util/nm-setting-ip4-config.c
   trunk/libnm-util/nm-setting-ip4-config.h
   trunk/libnm-util/nm-setting-vpn.c
   trunk/libnm-util/nm-setting-vpn.h
   trunk/libnm-util/nm-utils.c
   trunk/libnm-util/nm-utils.h
   trunk/src/NetworkManagerSystem.c
   trunk/src/NetworkManagerUtils.c
   trunk/src/dhcp-manager/nm-dhcp-manager.c
   trunk/src/nm-ip4-config.c
   trunk/src/nm-ip4-config.h
   trunk/src/vpn-manager/nm-vpn-connection.c
   trunk/system-settings/plugins/ifcfg-fedora/reader.c
   trunk/system-settings/plugins/keyfile/reader.c
   trunk/system-settings/plugins/keyfile/writer.c

Modified: trunk/introspection/nm-ip4-config.xml
==============================================================================
--- trunk/introspection/nm-ip4-config.xml	(original)
+++ trunk/introspection/nm-ip4-config.xml	Wed Aug  6 22:23:48 2008
@@ -3,7 +3,7 @@
 <node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0";>
   <interface name="org.freedesktop.NetworkManager.IP4Config">
     <property name="Addresses" type="aau" access="read">
-      <tp:docstring>Tuples of IPv4 address/prefix/gateway.  The gateway is optional, if not given should be 0.</tp:docstring>
+      <tp:docstring>Tuples of IPv4 address/prefix/gateway.</tp:docstring>
     </property>
     <property name="Hostname" type="s" access="read">
       <tp:docstring>The hostname associated with this IPv4 address. FIXME: what about multiple hostnames?</tp:docstring>
@@ -20,6 +20,9 @@
     <property name="NisServers" type="au" access="read">
       <tp:docstring>The NIS servers associated with this address.</tp:docstring>
     </property>
+    <property name="Routes" type="aau" access="read">
+      <tp:docstring>Tuples of IPv4 route/prefix/next-hop/metric.</tp:docstring>
+    </property>
   </interface>
 </node>
 

Modified: trunk/libnm-glib/nm-ip4-config.c
==============================================================================
--- trunk/libnm-glib/nm-ip4-config.c	(original)
+++ trunk/libnm-glib/nm-ip4-config.c	Wed Aug  6 22:23:48 2008
@@ -19,6 +19,7 @@
 	GPtrArray *domains;
 	char *nis_domain;
 	GArray *nis_servers;
+	GSList *routes;
 } NMIP4ConfigPrivate;
 
 enum {
@@ -29,6 +30,7 @@
 	PROP_DOMAINS,
 	PROP_NIS_DOMAIN,
 	PROP_NIS_SERVERS,
+	PROP_ROUTES,
 
 	LAST_PROP
 };
@@ -76,6 +78,21 @@
 	return TRUE;
 }
 
+static gboolean
+demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
+{
+	NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
+
+	g_slist_foreach (priv->routes, (GFunc) g_free, NULL);
+	g_slist_free (priv->routes);
+	priv->routes = NULL;
+
+	priv->routes = nm_utils_ip4_routes_from_gvalue (value);
+	nm_object_queue_notify (object, NM_IP4_CONFIG_ROUTES);
+
+	return TRUE;
+}
+
 static void
 register_for_property_changed (NMIP4Config *config)
 {
@@ -87,6 +104,7 @@
 		{ NM_IP4_CONFIG_DOMAINS,     demarshal_domains,            &priv->domains },
 		{ NM_IP4_CONFIG_NIS_DOMAIN,  nm_object_demarshal_generic,  &priv->nis_domain },
 		{ NM_IP4_CONFIG_NIS_SERVERS, demarshal_ip4_array,          &priv->nis_servers },
+		{ NM_IP4_CONFIG_ROUTES,      demarshal_ip4_routes_array,   &priv->routes },
 		{ NULL },
 	};
 
@@ -131,6 +149,9 @@
 	g_slist_foreach (priv->addresses, (GFunc) g_free, NULL);
 	g_slist_free (priv->addresses);
 
+	g_slist_foreach (priv->routes, (GFunc) g_free, NULL);
+	g_slist_free (priv->routes);
+
 	g_free (priv->hostname);
 	g_free (priv->nis_domain);
 	if (priv->nameservers)
@@ -174,6 +195,9 @@
 	case PROP_NIS_SERVERS:
 		g_value_set_boxed (value, nm_ip4_config_get_nis_servers (self));
 		break;
+	case PROP_ROUTES:
+		nm_utils_ip4_routes_to_gvalue (priv->routes, value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -239,6 +263,13 @@
 						    "NIS servers",
 						    NM_TYPE_UINT_ARRAY,
 						    G_PARAM_READABLE));
+
+	g_object_class_install_property
+		(object_class, PROP_ROUTES,
+		 g_param_spec_pointer (NM_IP4_CONFIG_ROUTES,
+						       "Routes",
+						       "Routes",
+						       G_PARAM_READABLE));
 }
 
 GObject *
@@ -366,7 +397,7 @@
 	return priv->nis_domain;
 }
 
-GArray *
+const GArray *
 nm_ip4_config_get_nis_servers (NMIP4Config *config)
 {
 	NMIP4ConfigPrivate *priv;
@@ -392,3 +423,29 @@
 
 	return priv->nis_servers;
 }
+
+const GSList *
+nm_ip4_config_get_routes (NMIP4Config *config)
+{
+	NMIP4ConfigPrivate *priv;
+	GValue value = { 0, };
+
+	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
+
+	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+	if (priv->routes)
+		return priv->routes;
+
+	if (!nm_object_get_property (NM_OBJECT (config),
+	                             "org.freedesktop.DBus.Properties",
+	                             "Routes",
+	                             &value)) {
+		return NULL;
+	}
+
+	demarshal_ip4_routes_array (NM_OBJECT (config), NULL, &value, &priv->routes);
+	g_value_unset (&value);
+
+	return priv->routes;
+}
+

Modified: trunk/libnm-glib/nm-ip4-config.h
==============================================================================
--- trunk/libnm-glib/nm-ip4-config.h	(original)
+++ trunk/libnm-glib/nm-ip4-config.h	Wed Aug  6 22:23:48 2008
@@ -29,6 +29,7 @@
 #define NM_IP4_CONFIG_DOMAINS "domains"
 #define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain"
 #define NM_IP4_CONFIG_NIS_SERVERS "nis-servers"
+#define NM_IP4_CONFIG_ROUTES "routes"
 
 GType nm_ip4_config_get_type (void);
 
@@ -39,7 +40,8 @@
 const GArray *   nm_ip4_config_get_nameservers (NMIP4Config *config);
 const GPtrArray *nm_ip4_config_get_domains     (NMIP4Config *config);
 const char *     nm_ip4_config_get_nis_domain  (NMIP4Config *config);
-GArray *         nm_ip4_config_get_nis_servers (NMIP4Config *config);
+const GArray *   nm_ip4_config_get_nis_servers (NMIP4Config *config);
+const GSList *   nm_ip4_config_get_routes      (NMIP4Config *config);
 
 G_END_DECLS
 

Modified: trunk/libnm-util/nm-setting-ip4-config.c
==============================================================================
--- trunk/libnm-util/nm-setting-ip4-config.c	(original)
+++ trunk/libnm-util/nm-setting-ip4-config.c	Wed Aug  6 22:23:48 2008
@@ -76,7 +76,8 @@
 	PROP_DNS_SEARCH,
 	PROP_ADDRESSES,
 	PROP_ROUTES,
-	PROP_IGNORE_DHCP_DNS,
+	PROP_IGNORE_AUTO_ROUTES,
+	PROP_IGNORE_AUTO_DNS,
 	PROP_DHCP_CLIENT_ID,
 	PROP_DHCP_HOSTNAME,
 
@@ -186,9 +187,9 @@
 
 	/* Validate routes */
 	for (iter = self->routes, i = 0; iter; iter = g_slist_next (iter), i++) {
-		NMSettingIP4Address *addr = (NMSettingIP4Address *) iter->data;
+		NMSettingIP4Route *route = (NMSettingIP4Route *) iter->data;
 
-		if (!addr->address) {
+		if (!route->address) {
 			g_set_error (error,
 			             NM_SETTING_IP4_CONFIG_ERROR,
 			             NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY,
@@ -196,7 +197,7 @@
 			return FALSE;
 		}
 
-		if (!addr->prefix || addr->prefix > 32) {
+		if (!route->prefix || route->prefix > 32) {
 			g_set_error (error,
 			             NM_SETTING_IP4_CONFIG_ERROR,
 			             NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY,
@@ -258,10 +259,13 @@
 		break;
 	case PROP_ROUTES:
 		nm_utils_slist_free (setting->routes, g_free);
-		setting->routes = nm_utils_ip4_addresses_from_gvalue (value);
+		setting->routes = nm_utils_ip4_routes_from_gvalue (value);
 		break;
-	case PROP_IGNORE_DHCP_DNS:
-		setting->ignore_dhcp_dns = g_value_get_boolean (value);
+	case PROP_IGNORE_AUTO_ROUTES:
+		setting->ignore_auto_routes = g_value_get_boolean (value);
+		break;
+	case PROP_IGNORE_AUTO_DNS:
+		setting->ignore_auto_dns = g_value_get_boolean (value);
 		break;
 	case PROP_DHCP_CLIENT_ID:
 		g_free (setting->dhcp_client_id);
@@ -297,10 +301,13 @@
 		nm_utils_ip4_addresses_to_gvalue (setting->addresses, value);
 		break;
 	case PROP_ROUTES:
-		nm_utils_ip4_addresses_to_gvalue (setting->routes, value);
+		nm_utils_ip4_routes_to_gvalue (setting->routes, value);
+		break;
+	case PROP_IGNORE_AUTO_ROUTES:
+		g_value_set_boolean (value, setting->ignore_auto_routes);
 		break;
-	case PROP_IGNORE_DHCP_DNS:
-		g_value_set_boolean (value, setting->ignore_dhcp_dns);
+	case PROP_IGNORE_AUTO_DNS:
+		g_value_set_boolean (value, setting->ignore_auto_dns);
 		break;
 	case PROP_DHCP_CLIENT_ID:
 		g_value_set_string (value, setting->dhcp_client_id);
@@ -363,15 +370,23 @@
 		(object_class, PROP_ROUTES,
 		 nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ROUTES,
 							   "Routes",
-							   "List of NMSettingIP4Addresses",
+							   "List of NMSettingIP4Routes",
 							   DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
 							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	g_object_class_install_property
-		(object_class, PROP_IGNORE_DHCP_DNS,
-		 g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_DHCP_DNS,
-						   "Ignore DHCP DNS",
-						   "Ignore DHCP DNS",
+		(object_class, PROP_IGNORE_AUTO_ROUTES,
+		 g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES,
+						   "Ignore automatic routes",
+						   "Ignore automatic routes",
+						   FALSE,
+						   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	g_object_class_install_property
+		(object_class, PROP_IGNORE_AUTO_DNS,
+		 g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS,
+						   "Ignore automatic DNS",
+						   "Ignore automatic DNS",
 						   FALSE,
 						   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 

Modified: trunk/libnm-util/nm-setting-ip4-config.h
==============================================================================
--- trunk/libnm-util/nm-setting-ip4-config.h	(original)
+++ trunk/libnm-util/nm-setting-ip4-config.h	Wed Aug  6 22:23:48 2008
@@ -53,14 +53,15 @@
 #define NM_SETTING_IP4_CONFIG_ERROR nm_setting_ip4_config_error_quark ()
 GQuark nm_setting_ip4_config_error_quark (void);
 
-#define NM_SETTING_IP4_CONFIG_METHOD          "method"
-#define NM_SETTING_IP4_CONFIG_DNS             "dns"
-#define NM_SETTING_IP4_CONFIG_DNS_SEARCH      "dns-search"
-#define NM_SETTING_IP4_CONFIG_ADDRESSES       "addresses"
-#define NM_SETTING_IP4_CONFIG_ROUTES          "routes"
-#define NM_SETTING_IP4_CONFIG_IGNORE_DHCP_DNS "ignore-dhcp-dns"
-#define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID  "dhcp-client-id"
-#define NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME   "dhcp-hostname"
+#define NM_SETTING_IP4_CONFIG_METHOD             "method"
+#define NM_SETTING_IP4_CONFIG_DNS                "dns"
+#define NM_SETTING_IP4_CONFIG_DNS_SEARCH         "dns-search"
+#define NM_SETTING_IP4_CONFIG_ADDRESSES          "addresses"
+#define NM_SETTING_IP4_CONFIG_ROUTES             "routes"
+#define NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes"
+#define NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS    "ignore-auto-dns"
+#define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID     "dhcp-client-id"
+#define NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME      "dhcp-hostname"
 
 #define NM_SETTING_IP4_CONFIG_METHOD_AUTO       "auto"
 #define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local"
@@ -74,14 +75,22 @@
 } NMSettingIP4Address;
 
 typedef struct {
+	guint32 address;   /* network byte order */
+	guint32 prefix;
+	guint32 next_hop;   /* network byte order */
+	guint32 metric;    /* lower metric == more preferred */
+} NMSettingIP4Route;
+
+typedef struct {
 	NMSetting parent;
 
 	char *method;
 	GArray *dns;        /* array of guint32; elements in network byte order */
 	GSList *dns_search; /* list of strings */
 	GSList *addresses;  /* array of NMSettingIP4Address */
-	GSList *routes;     /* array of NMSettingIP4Address */
-	gboolean ignore_dhcp_dns;
+	GSList *routes;     /* array of NMSettingIP4Route */
+	gboolean ignore_auto_routes;
+	gboolean ignore_auto_dns;
 	char *dhcp_client_id;
 	char *dhcp_hostname;
 } NMSettingIP4Config;

Modified: trunk/libnm-util/nm-setting-vpn.c
==============================================================================
--- trunk/libnm-util/nm-setting-vpn.c	(original)
+++ trunk/libnm-util/nm-setting-vpn.c	Wed Aug  6 22:23:48 2008
@@ -70,7 +70,6 @@
 	PROP_0,
 	PROP_SERVICE_TYPE,
 	PROP_USER_NAME,
-	PROP_ROUTES,
 
 	LAST_PROP
 };
@@ -127,7 +126,6 @@
 
 	g_free (self->service_type);
 	g_free (self->user_name);
-	nm_utils_slist_free (self->routes, g_free);
 
 	G_OBJECT_CLASS (nm_setting_vpn_parent_class)->finalize (object);
 }
@@ -147,10 +145,6 @@
 		g_free (setting->user_name);
 		setting->user_name = g_value_dup_string (value);
 		break;
-	case PROP_ROUTES:
-		nm_utils_slist_free (setting->routes, g_free);
-		setting->routes = g_value_dup_boxed (value);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -170,9 +164,6 @@
 	case PROP_USER_NAME:
 		g_value_set_string (value, setting->user_name);
 		break;
-	case PROP_ROUTES:
-		g_value_set_boxed (value, setting->routes);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -207,12 +198,4 @@
 						  "User name",
 						  NULL,
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
-
-	g_object_class_install_property
-		(object_class, PROP_ROUTES,
-		 nm_param_spec_specialized (NM_SETTING_VPN_ROUTES,
-							   "Routes",
-							   "Routes",
-							   DBUS_TYPE_G_LIST_OF_STRING,
-							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 }

Modified: trunk/libnm-util/nm-setting-vpn.h
==============================================================================
--- trunk/libnm-util/nm-setting-vpn.h	(original)
+++ trunk/libnm-util/nm-setting-vpn.h	Wed Aug  6 22:23:48 2008
@@ -54,14 +54,12 @@
 
 #define NM_SETTING_VPN_SERVICE_TYPE "service-type"
 #define NM_SETTING_VPN_USER_NAME    "user-name"
-#define NM_SETTING_VPN_ROUTES       "routes"
 
 typedef struct {
 	NMSetting parent;
 
 	char *service_type;
 	char *user_name;
-	GSList *routes;
 } NMSettingVPN;
 
 typedef struct {

Modified: trunk/libnm-util/nm-utils.c
==============================================================================
--- trunk/libnm-util/nm-utils.c	(original)
+++ trunk/libnm-util/nm-utils.c	Wed Aug  6 22:23:48 2008
@@ -859,6 +859,58 @@
 	g_value_take_boxed (value, addresses);
 }
 
+GSList *
+nm_utils_ip4_routes_from_gvalue (const GValue *value)
+{
+	GPtrArray *routes;
+	int i;
+	GSList *list = NULL;
+
+	routes = (GPtrArray *) g_value_get_boxed (value);
+	for (i = 0; routes && (i < routes->len); i++) {
+		GArray *array = (GArray *) g_ptr_array_index (routes, i);
+		NMSettingIP4Route *route;
+
+		if (array->len != 4) {
+			nm_warning ("Ignoring invalid IP4 route");
+			continue;
+		}
+		
+		route = g_malloc0 (sizeof (NMSettingIP4Route));
+		route->address = g_array_index (array, guint32, 0);
+		route->prefix = g_array_index (array, guint32, 1);
+		route->next_hop = g_array_index (array, guint32, 2);
+		route->metric = g_array_index (array, guint32, 3);
+		list = g_slist_prepend (list, route);
+	}
+
+	return g_slist_reverse (list);
+}
+
+void
+nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value)
+{
+	GPtrArray *routes;
+	GSList *iter;
+
+	routes = g_ptr_array_new ();
+
+	for (iter = list; iter; iter = iter->next) {
+		NMSettingIP4Route *route = (NMSettingIP4Route *) iter->data;
+		GArray *array;
+
+		array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+
+		g_array_append_val (array, route->address);
+		g_array_append_val (array, route->prefix);
+		g_array_append_val (array, route->next_hop);
+		g_array_append_val (array, route->metric);
+		g_ptr_array_add (routes, array);
+	}
+
+	g_value_take_boxed (value, routes);
+}
+
 /*
  * nm_utils_ip4_netmask_to_prefix
  *

Modified: trunk/libnm-util/nm-utils.h
==============================================================================
--- trunk/libnm-util/nm-utils.h	(original)
+++ trunk/libnm-util/nm-utils.h	Wed Aug  6 22:23:48 2008
@@ -187,6 +187,9 @@
 GSList *nm_utils_ip4_addresses_from_gvalue (const GValue *value);
 void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value);
 
+GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value);
+void nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value);
+
 guint32 nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask);
 guint32 nm_utils_ip4_prefix_to_netmask (guint32 ip4_prefix);
 

Modified: trunk/src/NetworkManagerSystem.c
==============================================================================
--- trunk/src/NetworkManagerSystem.c	(original)
+++ trunk/src/NetworkManagerSystem.c	Wed Aug  6 22:23:48 2008
@@ -107,6 +107,7 @@
 						  guint32 ip4_dest,
 						  guint32 ip4_prefix,
 						  guint32 ip4_gateway,
+						  guint32 metric,
 						  int mss)
 {
 	struct nl_handle *nlh;
@@ -148,6 +149,10 @@
 		}
 	}
 
+	/* Metric */
+	if (metric)
+		rtnl_route_set_prio (route, metric);
+
 	/* Add the route */
 	err = rtnl_route_add (nlh, route, 0);
 	if (err == -ESRCH && ip4_gateway) {
@@ -284,14 +289,15 @@
 
 	sleep (1);
 
-	len = nm_ip4_config_get_num_static_routes (config);
+	len = nm_ip4_config_get_num_routes (config);
 	for (i = 0; i < len; i++) {
-		const NMSettingIP4Address *route = nm_ip4_config_get_static_route (config, i);
+		const NMSettingIP4Route *route = nm_ip4_config_get_route (config, i);
 
 		nm_system_device_set_ip4_route (iface, config, 
 								  route->address,
 								  route->prefix,
-								  route->gateway,
+								  route->next_hop,
+								  route->metric,
 								  nm_ip4_config_get_mss (config));
 	}
 
@@ -344,7 +350,7 @@
 			}
 
 			nm_system_device_set_ip4_route (nm_device_get_ip_iface (active_device),
-									  ad_config, vpn_gw, 32, ad_gw,
+									  ad_config, vpn_gw, 32, ad_gw, 0,
 									  nm_ip4_config_get_mss (config));
 		}
 	}
@@ -362,14 +368,15 @@
 		nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
 
 	/* Set routes */
-	num = nm_ip4_config_get_num_static_routes (config);
+	num = nm_ip4_config_get_num_routes (config);
 	for (i = 0; i < num; i++) {
-		const NMSettingIP4Address *route = nm_ip4_config_get_static_route (config, i);
+		const NMSettingIP4Route *route = nm_ip4_config_get_route (config, i);
 
 		nm_system_device_set_ip4_route (iface, config,
 								  route->address,
 								  route->prefix,
-								  route->gateway,
+								  route->next_hop,
+								  route->metric,
 								  nm_ip4_config_get_mss (config));
 	}
 

Modified: trunk/src/NetworkManagerUtils.c
==============================================================================
--- trunk/src/NetworkManagerUtils.c	(original)
+++ trunk/src/NetworkManagerUtils.c	Wed Aug  6 22:23:48 2008
@@ -278,11 +278,14 @@
 	if (!setting)
 		return; /* Defaults are just fine */
 
-	if (setting->ignore_dhcp_dns) {
+	if (setting->ignore_auto_dns) {
 		nm_ip4_config_reset_nameservers (ip4_config);
 		nm_ip4_config_reset_searches (ip4_config);
 	}
 
+	if (setting->ignore_auto_routes)
+		nm_ip4_config_reset_routes (ip4_config);
+
 	if (setting->dns) {
 		int i, j;
 
@@ -344,25 +347,27 @@
 			nm_ip4_config_add_address (ip4_config, setting_addr);
 	}
 
-	/* IPv4 static routes */
+	/* IPv4 routes */
 	for (iter = setting->routes; iter; iter = g_slist_next (iter)) {
-		NMSettingIP4Address *setting_route = (NMSettingIP4Address *) iter->data;
+		NMSettingIP4Route *setting_route = (NMSettingIP4Route *) iter->data;
 		guint32 i, num;
 
-		num = nm_ip4_config_get_num_static_routes (ip4_config);
+		num = nm_ip4_config_get_num_routes (ip4_config);
 		for (i = 0; i < num; i++) {
-			const NMSettingIP4Address *cfg_route;
+			const NMSettingIP4Route *cfg_route;
 
-			cfg_route = nm_ip4_config_get_static_route (ip4_config, i);
-			/* Dupe, override with user-specified address */
-			if (cfg_route->address == setting_route->address) {
-				nm_ip4_config_replace_static_route (ip4_config, i, setting_route);
+			cfg_route = nm_ip4_config_get_route (ip4_config, i);
+			/* Dupe, override with user-specified route */
+			if (   (cfg_route->address == setting_route->address)
+			    && (cfg_route->prefix == setting_route->prefix)
+			    && (cfg_route->next_hop == setting_route->next_hop)) {
+				nm_ip4_config_replace_route (ip4_config, i, setting_route);
 				break;
 			}
 		}
 
 		if (i == num)
-			nm_ip4_config_add_static_route (ip4_config, setting_route);
+			nm_ip4_config_add_route (ip4_config, setting_route);
 	}
 }
 

Modified: trunk/src/dhcp-manager/nm-dhcp-manager.c
==============================================================================
--- trunk/src/dhcp-manager/nm-dhcp-manager.c	(original)
+++ trunk/src/dhcp-manager/nm-dhcp-manager.c	Wed Aug  6 22:23:48 2008
@@ -829,6 +829,7 @@
 			char **s;
 
 			for (s = searches; *s; s += 2) {
+				NMSettingIP4Route *route;
 				struct in_addr rt_addr;
 				struct in_addr rt_route;
 
@@ -843,13 +844,12 @@
 
 				// FIXME: ensure the IP addresse and route are sane
 
-				addr = g_malloc0 (sizeof (NMSettingIP4Address));
-				addr->address = (guint32) rt_addr.s_addr;
-				addr->prefix = 32; /* 255.255.255.255 */
-				addr->gateway = (guint32) rt_route.s_addr;
+				route = g_malloc0 (sizeof (NMSettingIP4Route));
+				route->address = (guint32) rt_addr.s_addr;
+				route->prefix = 32; /* 255.255.255.255 */
+				route->next_hop = (guint32) rt_route.s_addr;
 
-				nm_ip4_config_take_static_route (ip4_config, addr);
-				addr = NULL;
+				nm_ip4_config_take_route (ip4_config, route);
 				nm_info ("  static route %s gw %s", *s, *(s + 1));
 			}
 		} else {

Modified: trunk/src/nm-ip4-config.c
==============================================================================
--- trunk/src/nm-ip4-config.c	(original)
+++ trunk/src/nm-ip4-config.c	Wed Aug  6 22:23:48 2008
@@ -58,7 +58,7 @@
 	gchar *hostname;
 	gchar *nis_domain;
 	GArray *nis_servers;
-	GSList *static_routes;
+	GSList *routes;
 } NMIP4ConfigPrivate;
 
 
@@ -70,7 +70,7 @@
 	PROP_DOMAINS,
 	PROP_NIS_DOMAIN,
 	PROP_NIS_SERVERS,
-	PROP_STATIC_ROUTES,
+	PROP_ROUTES,
 
 	LAST_PROP
 };
@@ -133,13 +133,13 @@
 	for (i = 0; i < len; i++)
 		nm_ip4_config_add_nis_server (dst_config, nm_ip4_config_get_nis_server (src_config, i));
 
-	for (iter = src_priv->static_routes; iter; iter = g_slist_next (iter)) {
-		NMSettingIP4Address *src_addr = (NMSettingIP4Address *) iter->data;
-		NMSettingIP4Address *dst_addr;
-
-		dst_addr = g_malloc0 (sizeof (NMSettingIP4Address));
-		memcpy (dst_addr, src_addr, sizeof (NMSettingIP4Address));
-		nm_ip4_config_take_static_route (dst_config, dst_addr);
+	for (iter = src_priv->routes; iter; iter = g_slist_next (iter)) {
+		NMSettingIP4Route *src_route = (NMSettingIP4Route *) iter->data;
+		NMSettingIP4Route *dst_route;
+
+		dst_route = g_malloc0 (sizeof (NMSettingIP4Route));
+		memcpy (dst_route, src_route, sizeof (NMSettingIP4Route));
+		nm_ip4_config_take_route (dst_config, dst_route);
 	}
 
 	return dst_config;
@@ -310,38 +310,38 @@
 }
 
 void
-nm_ip4_config_take_static_route (NMIP4Config *config,
-						   NMSettingIP4Address *address)
+nm_ip4_config_take_route (NMIP4Config *config,
+						   NMSettingIP4Route *route)
 {
 	NMIP4ConfigPrivate *priv;
 
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
-	g_return_if_fail (address != NULL);
+	g_return_if_fail (route != NULL);
 
 	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-	priv->static_routes = g_slist_append (priv->static_routes, address);
+	priv->routes = g_slist_append (priv->routes, route);
 }
 
 void
-nm_ip4_config_add_static_route (NMIP4Config *config,
-						  NMSettingIP4Address *address)
+nm_ip4_config_add_route (NMIP4Config *config,
+						  NMSettingIP4Route *route)
 {
 	NMIP4ConfigPrivate *priv;
-	NMSettingIP4Address *copy;
+	NMSettingIP4Route *copy;
 
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
-	g_return_if_fail (address != NULL);
+	g_return_if_fail (route != NULL);
 
 	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-	copy = g_malloc0 (sizeof (NMSettingIP4Address));
-	memcpy (copy, address, sizeof (NMSettingIP4Address));
-	priv->static_routes = g_slist_append (priv->static_routes, copy);
+	copy = g_malloc0 (sizeof (NMSettingIP4Route));
+	memcpy (copy, route, sizeof (NMSettingIP4Route));
+	priv->routes = g_slist_append (priv->routes, copy);
 }
 
 void
-nm_ip4_config_replace_static_route (NMIP4Config *config,
+nm_ip4_config_replace_route (NMIP4Config *config,
 							 guint i,
-							 NMSettingIP4Address *new_address)
+							 NMSettingIP4Route *new_route)
 {
 	NMIP4ConfigPrivate *priv;
 	GSList *old;
@@ -349,28 +349,38 @@
 	g_return_if_fail (NM_IS_IP4_CONFIG (config));
 
 	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
-	old = g_slist_nth (priv->static_routes, i);
+	old = g_slist_nth (priv->routes, i);
 	g_return_if_fail (old != NULL);
 
 	g_free (old->data);
-	old->data = new_address;
+	old->data = new_route;
 }
 
-const NMSettingIP4Address *
-nm_ip4_config_get_static_route (NMIP4Config *config, guint i)
+const NMSettingIP4Route *
+nm_ip4_config_get_route (NMIP4Config *config, guint i)
 {
 	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
 
-	return (const NMSettingIP4Address *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, i);
+	return (const NMSettingIP4Route *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->routes, i);
 }
 
-guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config)
+guint32 nm_ip4_config_get_num_routes (NMIP4Config *config)
 {
 	g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
 
-	return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes);
+	return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->routes);
 }
 
+void nm_ip4_config_reset_routes (NMIP4Config *config)
+{
+	NMIP4ConfigPrivate *priv;
+
+	g_return_if_fail (NM_IS_IP4_CONFIG (config));
+
+	priv = NM_IP4_CONFIG_GET_PRIVATE (config);
+	g_slist_foreach (priv->routes, (GFunc) g_free, NULL);
+	priv->routes = NULL;
+}
 
 void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain)
 {
@@ -572,7 +582,7 @@
 	g_ptr_array_free (priv->domains, TRUE);
 	g_ptr_array_free (priv->searches, TRUE);
 	g_array_free (priv->nis_servers, TRUE);
-	nm_utils_slist_free (priv->static_routes, g_free);
+	nm_utils_slist_free (priv->routes, g_free);
 }
 
 static void
@@ -629,8 +639,8 @@
 	case PROP_NIS_SERVERS:
 		g_value_set_boxed (value, priv->nis_servers);
 		break;
-	case PROP_STATIC_ROUTES:
-		ip4_addresses_to_gvalue (priv->static_routes, value);
+	case PROP_ROUTES:
+		ip4_addresses_to_gvalue (priv->routes, value);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -694,10 +704,10 @@
 							 G_PARAM_READABLE));
 
 	g_object_class_install_property
-		(object_class, PROP_STATIC_ROUTES,
-		 g_param_spec_boxed (NM_IP4_CONFIG_STATIC_ROUTES,
-						 "Static routes",
-						 "Static routes",
+		(object_class, PROP_ROUTES,
+		 g_param_spec_boxed (NM_IP4_CONFIG_ROUTES,
+						 "Routes",
+						 "Routes",
 						 DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
 						 G_PARAM_READABLE));
 

Modified: trunk/src/nm-ip4-config.h
==============================================================================
--- trunk/src/nm-ip4-config.h	(original)
+++ trunk/src/nm-ip4-config.h	Wed Aug  6 22:23:48 2008
@@ -50,7 +50,7 @@
 #define NM_IP4_CONFIG_DOMAINS "domains"
 #define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain"
 #define NM_IP4_CONFIG_NIS_SERVERS "nis-servers"
-#define NM_IP4_CONFIG_STATIC_ROUTES "static-routes"
+#define NM_IP4_CONFIG_ROUTES "routes"
 
 GType nm_ip4_config_get_type (void);
 
@@ -76,11 +76,12 @@
 guint32		nm_ip4_config_get_nis_server		(NMIP4Config *config, guint i);
 guint32		nm_ip4_config_get_num_nis_servers	(NMIP4Config *config);
 
-void			nm_ip4_config_take_static_route		(NMIP4Config *config, NMSettingIP4Address *address);
-void			nm_ip4_config_add_static_route		(NMIP4Config *config, NMSettingIP4Address *address);
-void			nm_ip4_config_replace_static_route		(NMIP4Config *config, guint32 i, NMSettingIP4Address *new_address);
-const NMSettingIP4Address *	nm_ip4_config_get_static_route		(NMIP4Config *config, guint32 i);
-guint32		nm_ip4_config_get_num_static_routes	(NMIP4Config *config);
+void			nm_ip4_config_take_route		(NMIP4Config *config, NMSettingIP4Route *route);
+void			nm_ip4_config_add_route			(NMIP4Config *config, NMSettingIP4Route *route);
+void			nm_ip4_config_replace_route		(NMIP4Config *config, guint32 i, NMSettingIP4Route *new_route);
+const NMSettingIP4Route *	nm_ip4_config_get_route		(NMIP4Config *config, guint32 i);
+guint32		nm_ip4_config_get_num_routes		(NMIP4Config *config);
+void            nm_ip4_config_reset_routes		(NMIP4Config *config);
 
 void			nm_ip4_config_set_hostname		(NMIP4Config *config, const char *hostname);
 const char * 	nm_ip4_config_get_hostname		(NMIP4Config *config);

Modified: trunk/src/vpn-manager/nm-vpn-connection.c
==============================================================================
--- trunk/src/vpn-manager/nm-vpn-connection.c	(original)
+++ trunk/src/vpn-manager/nm-vpn-connection.c	Wed Aug  6 22:23:48 2008
@@ -299,13 +299,15 @@
 		    ip_address_to_string (nm_ip4_config_get_ptp_address (config)));
 	nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config));
 
-	num = nm_ip4_config_get_num_static_routes (config);
+	num = nm_ip4_config_get_num_routes (config);
 	for (i = 0; i < num; i++) {
-		addr = nm_ip4_config_get_static_route (config, i);
-		nm_info ("Static Route: %s/%d Gateway: %s",
-			    ip_address_to_string (addr->address),
-			    addr->prefix,
-			    ip_address_to_string (addr->gateway));
+		const NMSettingIP4Route *route;
+
+		route = nm_ip4_config_get_route (config, i);
+		nm_info ("Static Route: %s/%d   Next Hop: %s",
+			    ip_address_to_string (route->address),
+			    route->prefix,
+			    ip_address_to_string (route->next_hop));
 	}
 
 	num = nm_ip4_config_get_num_nameservers (config);
@@ -322,57 +324,6 @@
 }
 
 static void
-merge_vpn_routes (NMVPNConnection *connection, NMIP4Config *config)
-{
-	NMSettingVPN *setting;
-	GSList *iter;
-
-	setting = NM_SETTING_VPN (nm_connection_get_setting (NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection,
-											   NM_TYPE_SETTING_VPN));
-
-	/* FIXME: Shouldn't the routes from user (NMSettingVPN) be inserted in the beginning
-	   instead of appending to the end?
-	*/
-
-	for (iter = setting->routes; iter; iter = iter->next) {
-		struct in_addr tmp;
-		char *p, *route;
-		long int prefix = 32;
-
-		route = g_strdup ((char *) iter->data);
-		p = strchr (route, '/');
-		if (!p || !(*(p + 1))) {
-			nm_warning ("Ignoring invalid route '%s'", route);
-			goto next;
-		}
-
-		errno = 0;
-		prefix = strtol (p + 1, NULL, 10);
-		if (errno || prefix <= 0 || prefix > 32) {
-			nm_warning ("Ignoring invalid route '%s'", route);
-			goto next;
-		}
-
-		/* don't pass the prefix to inet_pton() */
-		*p = '\0';
-		if (inet_pton (AF_INET, route, &tmp) > 0) {
-			NMSettingIP4Address *addr;
-
-			addr = g_new0 (NMSettingIP4Address, 1);
-			addr->address = tmp.s_addr;
-			addr->prefix = (guint32) prefix;
-			addr->gateway = 0;
-
-			nm_ip4_config_take_static_route (config, addr);
-		} else
-			nm_warning ("Ignoring invalid route '%s'", route);
-
-next:
-		g_free (route);
-	}
-}
-
-static void
 nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
 						    GHashTable *config_hash,
 						    gpointer user_data)
@@ -463,9 +414,9 @@
 		GSList *routes;
 		GSList *iter;
 
-		routes = nm_utils_ip4_addresses_from_gvalue (val);
+		routes = nm_utils_ip4_routes_from_gvalue (val);
 		for (iter = routes; iter; iter = iter->next)
-			nm_ip4_config_take_static_route (config, (NMSettingIP4Address *) iter->data);
+			nm_ip4_config_take_route (config, (NMSettingIP4Route *) iter->data);
 
 		g_slist_free (routes);
 	}
@@ -478,7 +429,6 @@
 	/* Merge in user overrides from the NMConnection's IPv4 setting */
 	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG));
 	nm_utils_merge_ip4_config (config, s_ip4);
-	merge_vpn_routes (connection, config);
 
 	if (nm_system_vpn_device_set_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config)) {
 		nm_info ("VPN connection '%s' (IP Config Get) complete.",

Modified: trunk/system-settings/plugins/ifcfg-fedora/reader.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/reader.c	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/reader.c	Wed Aug  6 22:23:48 2008
@@ -238,7 +238,7 @@
 	/* Yay, let's make an IP4 config */
 	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
 	s_ip4->method = g_strdup (method);
-	s_ip4->ignore_dhcp_dns = !svTrueValue (ifcfg, "PEERDNS", 1);
+	s_ip4->ignore_auto_dns = !svTrueValue (ifcfg, "PEERDNS", 1);
 
 	/* DHCP hostname for 'send host-name' option */
 	if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {

Modified: trunk/system-settings/plugins/keyfile/reader.c
==============================================================================
--- trunk/system-settings/plugins/keyfile/reader.c	(original)
+++ trunk/system-settings/plugins/keyfile/reader.c	Wed Aug  6 22:23:48 2008
@@ -61,6 +61,22 @@
 	return TRUE;
 }
 
+static gboolean
+get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *out)
+{
+	long tmp;
+
+	errno = 0;
+	tmp = strtol (str, NULL, 10);
+	if (errno || (tmp < 0) || (tmp > max_val)) {
+		g_warning ("%s: ignoring invalid IPv4 %s item '%s'", __func__, key_name, str);
+		return FALSE;
+	}
+
+	*out = (guint32) tmp;
+	return TRUE;
+}
+
 static void
 free_one_address (gpointer data, gpointer user_data)
 {
@@ -69,8 +85,8 @@
 
 static GPtrArray *
 read_addresses (GKeyFile *file,
-			 const char *setting_name,
-			 const char *key)
+			    const char *setting_name,
+			    const char *key)
 {
 	GPtrArray *addresses;
 	int i = 0;
@@ -105,18 +121,14 @@
 			struct in_addr addr;
 
 			if (j == 1) {
-				/* prefix */
-				long tmp_prefix;
-				guint32 prefix;
+				guint32 prefix = 0;
 
-				errno = 0;
-				tmp_prefix = strtol (*iter, NULL, 10);
-				if (errno || (tmp_prefix < 0) || (tmp_prefix > 32)) {
-					g_warning ("%s: ignoring invalid IPv4 %s prefix '%s'", __func__, key_name, *iter);
+				/* prefix */
+				if (!get_one_int (*iter, 32, key_name, &prefix)) {
 					g_array_free (address, TRUE);
 					goto next;
 				}
-				prefix = (guint32) tmp_prefix;
+
 				g_array_append_val (address, prefix);
 			} else {
 				/* address and gateway */
@@ -148,32 +160,132 @@
 	return addresses;
 }
 
+static void
+free_one_route (gpointer data, gpointer user_data)
+{
+	g_array_free ((GArray *) data, TRUE);
+}
+
+static GPtrArray *
+read_routes (GKeyFile *file,
+			 const char *setting_name,
+			 const char *key)
+{
+	GPtrArray *routes;
+	int i = 0;
+
+	routes = g_ptr_array_sized_new (3);
+
+	/* Look for individual routes */
+	while (i++ < 1000) {
+		gchar **tmp, **iter;
+		char *key_name;
+		gsize length = 0;
+		int ret;
+		GArray *route;
+		int j;
+
+		key_name = g_strdup_printf ("%s%d", key, i);
+		tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL);
+		g_free (key_name);
+
+		if (!tmp || !length)
+			break; /* all done */
+
+		if (length != 4) {
+			g_warning ("%s: ignoring invalid IPv4 route item '%s'", __func__, key_name);
+			goto next;
+		}
+
+		/* convert the string array into IP addresses */
+		route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
+		for (iter = tmp, j = 0; *iter; iter++, j++) {
+			struct in_addr addr;
+
+			if (j == 1) {
+				guint32 prefix = 0;
+
+				/* prefix */
+				if (!get_one_int (*iter, 32, key_name, &prefix)) {
+					g_array_free (route, TRUE);
+					goto next;
+				}
+
+				g_array_append_val (route, prefix);
+			} else if (j == 3) {
+				guint32 metric = 0;
+
+				/* prefix */
+				if (!get_one_int (*iter, G_MAXUINT32, key_name, &metric)) {
+					g_array_free (route, TRUE);
+					goto next;
+				}
+
+				g_array_append_val (route, metric);
+			} else {
+				/* address and next hop */
+				ret = inet_pton (AF_INET, *iter, &addr);
+				if (ret <= 0) {
+					g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter);
+					g_array_free (route, TRUE);
+					goto next;
+				}
+				g_array_append_val (route, addr.s_addr);
+			}
+		}
+		g_ptr_array_add (routes, route);
+
+next:
+		g_strfreev (tmp);
+	}
+
+	if (routes->len < 1) {
+		g_ptr_array_free (routes, TRUE);
+		routes = NULL;
+	}
+
+	return routes;
+}
+
 static gboolean
 read_array_of_array_of_uint (GKeyFile *file,
                              NMSetting *setting,
                              const char *key)
 {
-	GPtrArray *addresses;
+	gboolean success = FALSE;
 
 	/* Only handle IPv4 addresses and routes for now */
-	if (   !NM_IS_SETTING_IP4_CONFIG (setting) ||
-		  (strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES) &&
-		   strcmp (key, NM_SETTING_IP4_CONFIG_ROUTES)))
-	    return FALSE;
-
-	addresses = read_addresses (file, setting->name, key);
-
-	/* Work around for previous syntax */
-	if (!addresses && !strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
-		addresses = read_addresses (file, setting->name, "address");
-
-	if (addresses) {
-		g_object_set (setting, key, addresses, NULL);
-		g_ptr_array_foreach (addresses, free_one_address, NULL);
-		g_ptr_array_free (addresses, TRUE);
+	if (!NM_IS_SETTING_IP4_CONFIG (setting))
+		return FALSE;
+
+	if (!strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES)) {
+		GPtrArray *addresses;
+
+		addresses = read_addresses (file, setting->name, key);
+
+		/* Work around for previous syntax */
+		if (!addresses && !strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+			addresses = read_addresses (file, setting->name, "address");
+
+		if (addresses) {
+			g_object_set (setting, key, addresses, NULL);
+			g_ptr_array_foreach (addresses, free_one_address, NULL);
+			g_ptr_array_free (addresses, TRUE);
+		}
+		success = TRUE;
+	} else if (!strcmp (key, NM_SETTING_IP4_CONFIG_ROUTES)) {
+		GPtrArray *routes;
+
+		routes = read_routes (file, setting->name, key);
+		if (routes) {
+			g_object_set (setting, key, routes, NULL);
+			g_ptr_array_foreach (routes, free_one_route, NULL);
+			g_ptr_array_free (routes, TRUE);
+		}
+		success = TRUE;
 	}
 
-	return TRUE;
+	return success;
 }
 
 static void

Modified: trunk/system-settings/plugins/keyfile/writer.c
==============================================================================
--- trunk/system-settings/plugins/keyfile/writer.c	(original)
+++ trunk/system-settings/plugins/keyfile/writer.c	Wed Aug  6 22:23:48 2008
@@ -62,6 +62,61 @@
 	return TRUE;
 }
 
+static void
+write_ip4_values (GKeyFile *file,
+                  const char *setting_name,
+                  const char *key,
+                  GPtrArray *array,
+                  guint32 tuple_len,
+                  guint32 addr1_pos,
+                  guint32 addr2_pos)
+{
+	char **list = NULL;
+	int i, j;
+
+	list = g_malloc (tuple_len);
+
+	for (i = 0, j = 0; i < array->len; i++, j++) {
+		GArray *tuple = g_ptr_array_index (array, i);
+		gboolean success = TRUE;
+		char *key_name;
+		int k;
+
+		memset (list, 0, tuple_len);
+
+		for (k = 0; k < tuple_len; k++) {
+			if (k == addr1_pos || k == addr2_pos) {
+				char buf[INET_ADDRSTRLEN + 1];
+				struct in_addr addr;
+
+				/* IP addresses */
+				addr.s_addr = g_array_index (tuple, guint32, k);
+				if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
+					nm_warning ("%s: error converting IP4 address 0x%X",
+					            __func__, ntohl (addr.s_addr));
+					success = FALSE;
+					break;
+				} else {
+					list[k] = g_strdup (buf);
+				}
+			} else {
+				/* prefix, metric */
+				list[k] = g_strdup_printf ("%d", g_array_index (tuple, guint32, k));
+			}
+		}
+
+		if (success) {
+			key_name = g_strdup_printf ("%s%d", key, j + 1);
+			g_key_file_set_string_list (file, setting_name, key_name, (const char **) list, tuple_len);
+			g_free (key_name);
+		}
+
+		for (k = 0; k < tuple_len; k++)
+			g_free (list[k]);
+	}
+	g_free (list);
+}
+
 static gboolean
 write_array_of_array_of_uint (GKeyFile *file,
                               NMSetting *setting,
@@ -69,58 +124,19 @@
                               const GValue *value)
 {
 	GPtrArray *array;
-	int i, j;
 
 	/* Only handle IPv4 addresses and routes for now */
-	if (   !NM_IS_SETTING_IP4_CONFIG (setting) ||
-		  (strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES) &&
-		   strcmp (key, NM_SETTING_IP4_CONFIG_ROUTES)))
-	    return FALSE;
+	if (!NM_IS_SETTING_IP4_CONFIG (setting))
+		return FALSE;
 
 	array = (GPtrArray *) g_value_get_boxed (value);
 	if (!array || !array->len)
 		return TRUE;
 
-	for (i = 0, j = 0; i < array->len; i++, j++) {
-		GArray *tuple = g_ptr_array_index (array, i);
-		char buf[INET_ADDRSTRLEN + 1];
-		struct in_addr addr;
-		char *list[3] = { NULL, NULL, NULL };
-		char *key_name;
-
-		/* Address */
-		addr.s_addr = g_array_index (tuple, guint32, 0);
-		if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
-			nm_warning ("%s: error converting IP4 address 0x%X",
-			            __func__, ntohl (addr.s_addr));
-			list[0] = NULL;
-		} else {
-			list[0] = g_strdup (buf);
-		}
-
-		/* Prefix */
-		list[1] = g_strdup_printf ("%d", g_array_index (tuple, guint32, 1));
-
-		/* Gateway */
-		addr.s_addr = g_array_index (tuple, guint32, 2);
-		if (addr.s_addr) {
-			if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
-				nm_warning ("%s: error converting IP4 address 0x%X",
-					        __func__, ntohl (addr.s_addr));
-				list[2] = NULL;
-			} else {
-				list[2] = g_strdup (buf);
-			}
-		}
-
-		key_name = g_strdup_printf ("%s%d", key, j + 1);
-		g_key_file_set_string_list (file, setting->name, key_name, (const char **) list, list[2] ? 3 : 2);
-		g_free (key_name);
-
-		g_free (list[0]);
-		g_free (list[1]);
-		g_free (list[2]);
-	}
+	if (!strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+		write_ip4_values (file, setting->name, key, array, 3, 0, 2);
+	else if (!strcmp (key, NM_SETTING_IP4_CONFIG_ROUTES))
+		write_ip4_values (file, setting->name, key, array, 4, 0, 2);
 
 	return TRUE;
 }



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