summary refs log tree commit diff
path: root/src/nm-ip6-config.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2012-06-29 20:12:44 +0200
committerMichael Biebl <biebl@debian.org>2012-06-29 20:12:44 +0200
commit867254ea7c2b193fecf8cd36cc6e5dc53c290d92 (patch)
tree7c698b403882736ab70c3efd524c3460f08c391c /src/nm-ip6-config.c
parentde06e5715e780baade318f3490ac7a4c9ce84e32 (diff)
Imported Upstream version 0.9.5.95 upstream/0.9.5.95
Diffstat (limited to 'src/nm-ip6-config.c')
-rw-r--r--src/nm-ip6-config.c106
1 files changed, 103 insertions, 3 deletions
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index f06e4069..511cbf46 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -53,6 +53,8 @@ typedef struct {
 	GPtrArray *domains;
 	GPtrArray *searches;
 
+	gboolean gateway_set;
+	struct in6_addr gateway;
 	GSList *routes;
 
 	gboolean never_default;
@@ -138,11 +140,17 @@ nm_ip6_config_add_address (NMIP6Config *config,
                            NMIP6Address *address)
 {
 	NMIP6ConfigPrivate *priv;
+	GSList *iter;
 
 	g_return_if_fail (NM_IS_IP6_CONFIG (config));
 	g_return_if_fail (address != NULL);
 
 	priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+	for (iter = priv->addresses; iter; iter = g_slist_next (iter)) {
+		if (nm_ip6_address_compare ((NMIP6Address *) iter->data, address))
+			return;
+	}
+
 	priv->addresses = g_slist_append (priv->addresses, nm_ip6_address_dup (address));
 }
 
@@ -205,8 +213,10 @@ void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *n
 
 	/* No dupes */
 	nameservers = (struct in6_addr *)priv->nameservers->data;
-	for (i = 0; i < priv->nameservers->len; i++)
-		g_return_if_fail (IN6_ARE_ADDR_EQUAL (nameserver, &nameservers[i]) == FALSE);
+	for (i = 0; i < priv->nameservers->len; i++) {
+		if (IN6_ARE_ADDR_EQUAL (nameserver, &nameservers[i]))
+			return;
+	}
 
 	g_array_append_val (priv->nameservers, *nameserver);
 }
@@ -237,6 +247,30 @@ void nm_ip6_config_reset_nameservers (NMIP6Config *config)
 }
 
 void
+nm_ip6_config_set_gateway (NMIP6Config *config, const struct in6_addr *gateway)
+{
+	NMIP6ConfigPrivate *priv;
+
+	g_return_if_fail (NM_IS_IP6_CONFIG (config));
+
+	priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+	if (gateway)
+		memcpy (&priv->gateway, gateway, sizeof (priv->gateway));
+	priv->gateway_set = !!gateway;
+}
+
+const struct in6_addr *
+nm_ip6_config_get_gateway (NMIP6Config *config)
+{
+	NMIP6ConfigPrivate *priv;
+
+	g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
+
+	priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+	return priv->gateway_set ? &priv->gateway : NULL;
+}
+
+void
 nm_ip6_config_take_route (NMIP6Config *config, NMIP6Route *route)
 {
 	NMIP6ConfigPrivate *priv;
@@ -252,11 +286,17 @@ void
 nm_ip6_config_add_route (NMIP6Config *config, NMIP6Route *route)
 {
 	NMIP6ConfigPrivate *priv;
+	GSList *iter;
 
 	g_return_if_fail (NM_IS_IP6_CONFIG (config));
 	g_return_if_fail (route != NULL);
 
 	priv = NM_IP6_CONFIG_GET_PRIVATE (config);
+	for (iter = priv->routes; iter; iter = g_slist_next (iter)) {
+		if (nm_ip6_route_compare ((NMIP6Route *) iter->data, route))
+			return;
+	}
+
 	priv->routes = g_slist_append (priv->routes, nm_ip6_route_dup (route));
 }
 
@@ -598,7 +638,7 @@ nm_ip6_config_diff (NMIP6Config *a, NMIP6Config *b)
 	NMIP6ConfigCompareFlags flags = NM_IP6_COMPARE_FLAG_NONE;
 
 	if ((a && !b) || (b && !a))
-		return 0xFFFFFFFF;
+		return NM_IP6_COMPARE_FLAG_ALL;
 	if (!a && !b)
 		return NM_IP6_COMPARE_FLAG_NONE;
 
@@ -637,6 +677,65 @@ nm_ip6_config_diff (NMIP6Config *a, NMIP6Config *b)
 	return flags;
 }
 
+static inline void
+hash_u32 (GChecksum *sum, guint32 n)
+{
+	g_checksum_update (sum, (const guint8 *) &n, sizeof (n));
+}
+
+static inline void
+hash_in6addr (GChecksum *sum, const struct in6_addr *a)
+{
+	g_checksum_update (sum, (const guint8 *) a, sizeof (*a));
+}
+
+void
+nm_ip6_config_hash (NMIP6Config *config, GChecksum *sum, gboolean dns_only)
+{
+	guint32 i;
+	const struct in6_addr *in6a;
+	const char *s;
+
+	g_return_if_fail (config != NULL);
+	g_return_if_fail (sum != NULL);
+
+	if (dns_only == FALSE) {
+		for (i = 0; i < nm_ip6_config_get_num_addresses (config); i++) {
+			NMIP6Address *a = nm_ip6_config_get_address (config, i);
+
+			hash_in6addr (sum, nm_ip6_address_get_address (a));
+			hash_u32 (sum, nm_ip6_address_get_prefix (a));
+			hash_in6addr (sum, nm_ip6_address_get_gateway (a));
+		}
+
+		for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) {
+			NMIP6Route *r = nm_ip6_config_get_route (config, i);
+
+			hash_in6addr (sum, nm_ip6_route_get_dest (r));
+			hash_u32 (sum, nm_ip6_route_get_prefix (r));
+			hash_in6addr (sum, nm_ip6_route_get_next_hop (r));
+			hash_u32 (sum, nm_ip6_route_get_metric (r));
+		}
+
+		in6a = nm_ip6_config_get_ptp_address (config);
+		if (in6a)
+			hash_in6addr (sum, in6a);
+	}
+
+	for (i = 0; i < nm_ip6_config_get_num_nameservers (config); i++)
+		hash_in6addr (sum, nm_ip6_config_get_nameserver (config, i));
+
+	for (i = 0; i < nm_ip6_config_get_num_domains (config); i++) {
+		s = nm_ip6_config_get_domain (config, i);
+		g_checksum_update (sum, (const guint8 *) s, strlen (s));
+	}
+
+	for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) {
+		s = nm_ip6_config_get_search (config, i);
+		g_checksum_update (sum, (const guint8 *) s, strlen (s));
+	}
+}
+
 static void
 nm_ip6_config_init (NMIP6Config *config)
 {
@@ -645,6 +744,7 @@ nm_ip6_config_init (NMIP6Config *config)
 	priv->nameservers = g_array_new (FALSE, TRUE, sizeof (struct in6_addr));
 	priv->domains = g_ptr_array_sized_new (3);
 	priv->searches = g_ptr_array_sized_new (3);
+	priv->gateway_set = FALSE;
 }
 
 static void