summary refs log tree commit diff
path: root/libnm-core/nm-setting-ip-config.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-08-26 02:18:32 +0200
committerMichael Biebl <biebl@debian.org>2016-08-26 02:18:32 +0200
commit7514efc2f38c9ace4557d4e69d68e7d380389030 (patch)
tree7fb00fda86cfcc2ca377f191633a7cfdbfea7ca3 /libnm-core/nm-setting-ip-config.c
parentd6201f5d8daada3d64a0a3e0038e14eebec683ce (diff)
Imported Upstream version 1.4.0 upstream/1.4.0
Diffstat (limited to 'libnm-core/nm-setting-ip-config.c')
-rw-r--r--libnm-core/nm-setting-ip-config.c139
1 files changed, 128 insertions, 11 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index bdcbc23b..55ad7bb0 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -300,17 +300,17 @@ nm_ip_address_unref (NMIPAddress *address)
 }
 
 /**
- * nm_ip_address_equal:
+ * _nm_ip_address_equal:
  * @address: the #NMIPAddress
  * @other: the #NMIPAddress to compare @address to.
+ * @consider_attributes: whether to check for equality of attributes too.
  *
- * Determines if two #NMIPAddress objects contain the same address and prefix
- * (attributes are not compared).
+ * Determines if two #NMIPAddress objects are equal.
  *
  * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
  **/
-gboolean
-nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
+static gboolean
+_nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other, gboolean consider_attributes)
 {
 	g_return_val_if_fail (address != NULL, FALSE);
 	g_return_val_if_fail (address->refcount > 0, FALSE);
@@ -322,10 +322,46 @@ nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
 	    || address->prefix != other->prefix
 	    || strcmp (address->address, other->address) != 0)
 		return FALSE;
+	if (consider_attributes) {
+		GHashTableIter iter;
+		const char *key;
+		GVariant *value, *value2;
+		guint n;
+
+		n = address->attributes ? g_hash_table_size (address->attributes) : 0;
+		if (n != (other->attributes ? g_hash_table_size (other->attributes) : 0))
+			return FALSE;
+		if (n) {
+			g_hash_table_iter_init (&iter, address->attributes);
+			while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
+				value2 = g_hash_table_lookup (other->attributes, key);
+				if (!value2)
+					return FALSE;
+				if (!g_variant_equal (value, value2))
+					return FALSE;
+			}
+		}
+	}
 	return TRUE;
 }
 
 /**
+ * nm_ip_address_equal:
+ * @address: the #NMIPAddress
+ * @other: the #NMIPAddress to compare @address to.
+ *
+ * Determines if two #NMIPAddress objects contain the same address and prefix
+ * (attributes are not compared).
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
+gboolean
+nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
+{
+	return _nm_ip_address_equal (address, other, FALSE);
+}
+
+/**
  * nm_ip_address_dup:
  * @address: the #NMIPAddress
  *
@@ -717,17 +753,18 @@ nm_ip_route_unref (NMIPRoute *route)
 }
 
 /**
- * nm_ip_route_equal:
+ * _nm_ip_route_equal:
  * @route: the #NMIPRoute
  * @other: the #NMIPRoute to compare @route to.
+ * @consider_attributes: whether to compare attributes too
  *
  * Determines if two #NMIPRoute objects contain the same destination, prefix,
- * next hop, and metric. (Attributes are not compared.)
+ * next hop, and metric.
  *
  * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
  **/
-gboolean
-nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
+static gboolean
+_nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other, gboolean consider_attributes)
 {
 	g_return_val_if_fail (route != NULL, FALSE);
 	g_return_val_if_fail (route->refcount > 0, FALSE);
@@ -740,10 +777,46 @@ nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
 	    || strcmp (route->dest, other->dest) != 0
 	    || g_strcmp0 (route->next_hop, other->next_hop) != 0)
 		return FALSE;
+	if (consider_attributes) {
+		GHashTableIter iter;
+		const char *key;
+		GVariant *value, *value2;
+		guint n;
+
+		n = route->attributes ? g_hash_table_size (route->attributes) : 0;
+		if (n != (other->attributes ? g_hash_table_size (other->attributes) : 0))
+			return FALSE;
+		if (n) {
+			g_hash_table_iter_init (&iter, route->attributes);
+			while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
+				value2 = g_hash_table_lookup (other->attributes, key);
+				if (!value2)
+					return FALSE;
+				if (!g_variant_equal (value, value2))
+					return FALSE;
+			}
+		}
+	}
 	return TRUE;
 }
 
 /**
+ * nm_ip_route_equal:
+ * @route: the #NMIPRoute
+ * @other: the #NMIPRoute to compare @route to.
+ *
+ * Determines if two #NMIPRoute objects contain the same destination, prefix,
+ * next hop, and metric. (Attributes are not compared.)
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
+gboolean
+nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
+{
+	return _nm_ip_route_equal (route, other, FALSE);
+}
+
+/**
  * nm_ip_route_dup:
  * @route: the #NMIPRoute
  *
@@ -1691,7 +1764,7 @@ nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_
  *
  * Returns: the priority of DNS servers
  *
- * Since: 1.2.4
+ * Since: 1.4
  **/
 gint
 nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting)
@@ -1700,6 +1773,7 @@ nm_setting_ip_config_get_dns_priority (NMSettingIPConfig *setting)
 
 	return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_priority;
 }
+NM_BACKPORT_SYMBOL (libnm_1_2_4, gint, nm_setting_ip_config_get_dns_priority, (NMSettingIPConfig *setting), (setting));
 
 /**
  * nm_setting_ip_config_get_num_addresses:
@@ -2305,6 +2379,48 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	return TRUE;
 }
 
+static gboolean
+compare_property (NMSetting *setting,
+                  NMSetting *other,
+                  const GParamSpec *prop_spec,
+                  NMSettingCompareFlags flags)
+{
+	NMSettingIPConfigPrivate *a_priv, *b_priv;
+	NMSettingClass *parent_class;
+	guint i;
+
+	if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ADDRESSES)) {
+		a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+		b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
+
+		if (a_priv->addresses->len != b_priv->addresses->len)
+			return FALSE;
+		for (i = 0; i < a_priv->addresses->len; i++) {
+			if (!_nm_ip_address_equal (a_priv->addresses->pdata[i], b_priv->addresses->pdata[i], TRUE))
+				return FALSE;
+		}
+		return TRUE;
+	}
+
+	if (nm_streq (prop_spec->name, NM_SETTING_IP_CONFIG_ROUTES)) {
+		a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+		b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
+
+		if (a_priv->routes->len != b_priv->routes->len)
+			return FALSE;
+		for (i = 0; i < a_priv->routes->len; i++) {
+			if (!_nm_ip_route_equal (a_priv->routes->pdata[i], b_priv->routes->pdata[i], TRUE))
+				return FALSE;
+		}
+		return TRUE;
+	}
+
+	/* Otherwise chain up to parent to handle generic compare */
+	parent_class = NM_SETTING_CLASS (nm_setting_ip_config_parent_class);
+	return parent_class->compare_property (setting, other, prop_spec, flags);
+}
+
+/*****************************************************************************/
 
 static void
 nm_setting_ip_config_init (NMSettingIPConfig *setting)
@@ -2535,6 +2651,7 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
 	object_class->get_property = get_property;
 	object_class->finalize     = finalize;
 	parent_class->verify       = verify;
+	parent_class->compare_property = compare_property;
 
 	/* Properties */
 
@@ -2627,7 +2744,7 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
 	 * priority, only DNS servers from configurations with the lowest priority
 	 * value will be used.
 	 *
-	 * Since: 1.2.4
+	 * Since: 1.4
 	 **/
 	g_object_class_install_property
 	    (object_class, PROP_DNS_PRIORITY,