summary refs log tree commit diff
path: root/src/devices/nm-device-vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/nm-device-vxlan.c')
-rw-r--r--src/devices/nm-device-vxlan.c117
1 files changed, 73 insertions, 44 deletions
diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c
index e1252223..c34f4142 100644
--- a/src/devices/nm-device-vxlan.c
+++ b/src/devices/nm-device-vxlan.c
@@ -246,65 +246,108 @@ address_matches (const char *str, in_addr_t addr4, struct in6_addr *addr6)
 }
 
 static gboolean
-check_connection_compatible (NMDevice *device, NMConnection *connection)
+check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
 {
 	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE ((NMDeviceVxlan *) device);
 	NMSettingVxlan *s_vxlan;
 	const char *parent;
 
-	if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection))
-		return FALSE;
-
-	s_vxlan = nm_connection_get_setting_vxlan (connection);
-	if (!s_vxlan)
+	if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection, error))
 		return FALSE;
 
 	if (nm_device_is_real (device)) {
+		s_vxlan = nm_connection_get_setting_vxlan (connection);
+
 		parent = nm_setting_vxlan_get_parent (s_vxlan);
-		if (parent && !nm_device_match_parent (device, parent))
+		if (parent && !nm_device_match_parent (device, parent)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan parent mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
+		if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan id mismatches");
 			return FALSE;
+		}
 
-		if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6))
+		if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan local address mismatches");
 			return FALSE;
+		}
 
-		if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6))
+		if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan remote address mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan))
+		if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan source port min mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan))
+		if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan source port max mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan))
+		if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan destination port mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan))
+		if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan TOS mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan))
+		if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan TTL mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan))
+		if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan learning mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan))
+		if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan ageing mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan))
+		if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan proxy mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan))
+		if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan rsc mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan))
+		if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan l2miss mismatches");
 			return FALSE;
+		}
 
-		if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan))
+		if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) {
+			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
+			                            "vxlan l3miss mismatches");
 			return FALSE;
+		}
 	}
 
 	return TRUE;
@@ -343,9 +386,6 @@ update_connection (NMDevice *device, NMConnection *connection)
 {
 	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE ((NMDeviceVxlan *) device);
 	NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection);
-	NMDevice *parent_device;
-	const char *setting_parent;
-	const char *new_parent = NULL;
 
 	if (!s_vxlan) {
 		s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new ();
@@ -355,23 +395,11 @@ update_connection (NMDevice *device, NMConnection *connection)
 	if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
 		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL);
 
-	parent_device = nm_device_parent_get_device (device);
-
-	/* Update parent in the connection; default to parent's interface name */
-	if (parent_device) {
-		new_parent = nm_device_get_iface (parent_device);
-		setting_parent = nm_setting_vxlan_get_parent (s_vxlan);
-		if (setting_parent && nm_utils_is_uuid (setting_parent)) {
-			NMConnection *parent_connection;
-
-			/* Don't change a parent specified by UUID if it's still valid */
-			parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device),
-			                                                                         setting_parent);
-			if (parent_connection && nm_device_check_connection_compatible (parent_device, parent_connection))
-				new_parent = NULL;
-		}
-	}
-	g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, new_parent, NULL);
+	g_object_set (s_vxlan,
+	              NM_SETTING_VXLAN_PARENT,
+	              nm_device_parent_find_for_connection (device,
+	                                                    nm_setting_vxlan_get_parent (s_vxlan)),
+	              NULL);
 
 	if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) {
 		if (priv->props.group) {
@@ -577,15 +605,16 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
 	NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass);
 	NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
 
-	NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VXLAN)
-
 	object_class->get_property = get_property;
 
 	dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vxlan);
 
+	device_class->connection_type_supported = NM_SETTING_VXLAN_SETTING_NAME;
+	device_class->connection_type_check_compatible = NM_SETTING_VXLAN_SETTING_NAME;
+	device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VXLAN);
+
 	device_class->link_changed = link_changed;
 	device_class->unrealize_notify = unrealize_notify;
-	device_class->connection_type = NM_SETTING_VXLAN_SETTING_NAME;
 	device_class->create_and_realize = create_and_realize;
 	device_class->check_connection_compatible = check_connection_compatible;
 	device_class->complete_connection = complete_connection;