summary refs log tree commit diff
path: root/src/devices/nm-device-ip-tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/nm-device-ip-tunnel.c')
-rw-r--r--src/devices/nm-device-ip-tunnel.c247
1 files changed, 55 insertions, 192 deletions
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index 568403c6..2e266bb9 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -179,13 +179,10 @@ clear:
 		goto out;
 	}
 
-	if (NM_IN_SET (priv->mode, NM_IP_TUNNEL_MODE_GRE, NM_IP_TUNNEL_MODE_GRETAP)) {
+	if (priv->mode == NM_IP_TUNNEL_MODE_GRE) {
 		const NMPlatformLnkGre *lnk;
 
-		if (priv->mode == NM_IP_TUNNEL_MODE_GRE)
-			lnk = nm_platform_link_get_lnk_gre (nm_device_get_platform (device), ifindex, NULL);
-		else
-			lnk = nm_platform_link_get_lnk_gretap (nm_device_get_platform (device), ifindex, NULL);
+		lnk = nm_platform_link_get_lnk_gre (nm_device_get_platform (device), ifindex, NULL);
 		if (!lnk) {
 			_LOGW (LOGD_PLATFORM, "could not read %s properties", "gre");
 			goto clear;
@@ -257,21 +254,11 @@ clear:
 		ttl = lnk->ttl;
 		tos = lnk->tos;
 		pmtud = lnk->path_mtu_discovery;
-	} else if (NM_IN_SET (priv->mode,
-	                      NM_IP_TUNNEL_MODE_IPIP6,
-	                      NM_IP_TUNNEL_MODE_IP6IP6,
-	                      NM_IP_TUNNEL_MODE_IP6GRE,
-	                      NM_IP_TUNNEL_MODE_IP6GRETAP)) {
+	} else if (   priv->mode == NM_IP_TUNNEL_MODE_IPIP6
+	           || priv->mode == NM_IP_TUNNEL_MODE_IP6IP6) {
 		const NMPlatformLnkIp6Tnl *lnk;
-		NMPlatform *plat = nm_device_get_platform (device);
-
-		if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRE)
-			lnk = nm_platform_link_get_lnk_ip6gre (plat, ifindex, NULL);
-		else if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRETAP)
-			lnk = nm_platform_link_get_lnk_ip6gretap (plat, ifindex, NULL);
-		else
-			lnk = nm_platform_link_get_lnk_ip6tnl (plat, ifindex, NULL);
 
+		lnk = nm_platform_link_get_lnk_ip6tnl (nm_device_get_platform (device), ifindex, NULL);
 		if (!lnk) {
 			_LOGW (LOGD_PLATFORM, "could not read %s properties", "ip6tnl");
 			goto clear;
@@ -285,40 +272,6 @@ clear:
 		encap_limit = lnk->encap_limit;
 		flow_label = lnk->flow_label;
 		flags = ip6tnl_flags_plat_to_setting (lnk->flags);
-
-		if (NM_IN_SET (priv->mode,
-		               NM_IP_TUNNEL_MODE_IP6GRE,
-		               NM_IP_TUNNEL_MODE_IP6GRETAP)) {
-			if (NM_FLAGS_HAS (lnk->input_flags, NM_GRE_KEY)) {
-				key = g_strdup_printf ("%u", lnk->input_key);
-				if (g_strcmp0 (priv->input_key, key)) {
-					g_free (priv->input_key);
-					priv->input_key = key;
-					_notify (self, PROP_INPUT_KEY);
-				} else
-					g_free (key);
-			} else {
-				if (priv->input_key) {
-					g_clear_pointer (&priv->input_key, g_free);
-					_notify (self, PROP_INPUT_KEY);
-				}
-			}
-
-			if (NM_FLAGS_HAS (lnk->output_flags, NM_GRE_KEY)) {
-				key = g_strdup_printf ("%u", lnk->output_key);
-				if (g_strcmp0 (priv->output_key, key)) {
-					g_free (priv->output_key);
-					priv->output_key = key;
-					_notify (self, PROP_OUTPUT_KEY);
-				} else
-					g_free (key);
-			} else {
-				if (priv->output_key) {
-					g_clear_pointer (&priv->output_key, g_free);
-					_notify (self, PROP_OUTPUT_KEY);
-				}
-			}
-		}
 	} else
 		g_return_if_reached ();
 
@@ -435,6 +388,8 @@ update_connection (NMDevice *device, NMConnection *connection)
 	NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
 	NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
 	NMSettingIPTunnel *s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+	NMDevice *parent = NULL;
+	const char *setting_parent, *new_parent;
 
 	if (!s_ip_tunnel) {
 		s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new ();
@@ -444,11 +399,25 @@ update_connection (NMDevice *device, NMConnection *connection)
 	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
 		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_MODE, priv->mode, NULL);
 
-	g_object_set (s_ip_tunnel,
-	              NM_SETTING_IP_TUNNEL_PARENT,
-	              nm_device_parent_find_for_connection (device,
-	                                                    nm_setting_ip_tunnel_get_parent (s_ip_tunnel)),
-	              NULL);
+	parent = nm_device_parent_get_device (device);
+
+	/* Update parent in the connection; default to parent's interface name */
+	if (parent) {
+		new_parent = nm_device_get_iface (parent);
+		setting_parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
+		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, parent_connection))
+				new_parent = NULL;
+		}
+		if (new_parent)
+			g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, new_parent, NULL);
+	} else
+		g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, NULL, NULL);
 
 	if (!address_equal_pp (priv->addr_family,
 	                       nm_setting_ip_tunnel_get_local (s_ip_tunnel),
@@ -487,11 +456,7 @@ update_connection (NMDevice *device, NMConnection *connection)
 		                        NULL);
 	}
 
-	if (NM_IN_SET (priv->mode,
-	               NM_IP_TUNNEL_MODE_GRE,
-	               NM_IP_TUNNEL_MODE_GRETAP,
-	               NM_IP_TUNNEL_MODE_IP6GRE,
-	               NM_IP_TUNNEL_MODE_IP6GRETAP)) {
+	if (priv->mode == NM_IP_TUNNEL_MODE_GRE || priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) {
 		if (g_strcmp0 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), priv->input_key)) {
 			g_object_set (G_OBJECT (s_ip_tunnel),
 			              NM_SETTING_IP_TUNNEL_INPUT_KEY,
@@ -508,79 +473,54 @@ update_connection (NMDevice *device, NMConnection *connection)
 }
 
 static gboolean
-check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
+check_connection_compatible (NMDevice *device, NMConnection *connection)
 {
 	NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
 	NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
 	NMSettingIPTunnel *s_ip_tunnel;
 	const char *parent;
 
-	if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection, error))
+	if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection))
 		return FALSE;
 
 	s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+	if (!s_ip_tunnel)
+		return FALSE;
 
-	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode) {
-		nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-		                            "incompatible IP tunnel mode");
+	if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode)
 		return FALSE;
-	}
 
 	if (nm_device_is_real (device)) {
 		/* Check parent interface; could be an interface name or a UUID */
 		parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel);
-		if (parent && !nm_device_match_parent (device, parent)) {
-			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-			                            "IP tunnel parent mismatches");
+		if (parent && !nm_device_match_parent (device, parent))
 			return FALSE;
-		}
 
 		if (!address_equal_pp (priv->addr_family,
 		                       nm_setting_ip_tunnel_get_local (s_ip_tunnel),
-		                       priv->local)) {
-			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-			                            "local IP tunnel address mismatches");
+		                       priv->local))
 			return FALSE;
-		}
 
 		if (!address_equal_pp (priv->addr_family,
 		                       nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
-		                       priv->remote)) {
-			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-			                            "remote IP tunnel address mismatches");
+		                       priv->remote))
 			return FALSE;
-		}
 
-		if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl) {
-			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-			                            "TTL of IP tunnel mismatches");
+		if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
 			return FALSE;
-		}
 
-		if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos) {
-			nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-			                            "TOS of IP tunnel mismatches");
+		if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
 			return FALSE;
-		}
 
 		if (priv->addr_family == AF_INET) {
-			if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) {
-				nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-				                            "MTU discovery setting of IP tunnel mismatches");
+			if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery)
 				return FALSE;
-			}
 		} else {
-			if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) {
-				nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-				                            "encapsulation limit of IP tunnel mismatches");
+			if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit)
 				return FALSE;
-			}
 
-			if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) {
-				nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
-				                            "flow-label of IP tunnel mismatches");
+			if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label)
 				return FALSE;
-			}
 		}
 	}
 
@@ -595,8 +535,6 @@ platform_link_to_tunnel_mode (const NMPlatformLink *link)
 	switch (link->type) {
 	case NM_LINK_TYPE_GRE:
 		return NM_IP_TUNNEL_MODE_GRE;
-	case NM_LINK_TYPE_GRETAP:
-		return NM_IP_TUNNEL_MODE_GRETAP;
 	case NM_LINK_TYPE_IP6TNL:
 		lnk = nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, link->ifindex, NULL);
 		if (lnk) {
@@ -606,10 +544,6 @@ platform_link_to_tunnel_mode (const NMPlatformLink *link)
 				return NM_IP_TUNNEL_MODE_IP6IP6;
 		}
 		return NM_IP_TUNNEL_MODE_UNKNOWN;
-	case NM_LINK_TYPE_IP6GRE:
-		return NM_IP_TUNNEL_MODE_IP6GRE;
-	case NM_LINK_TYPE_IP6GRETAP:
-		return NM_IP_TUNNEL_MODE_IP6GRETAP;
 	case NM_LINK_TYPE_IPIP:
 		return NM_IP_TUNNEL_MODE_IPIP;
 	case NM_LINK_TYPE_SIT:
@@ -625,20 +559,15 @@ tunnel_mode_to_link_type (NMIPTunnelMode tunnel_mode)
 	switch (tunnel_mode) {
 	case NM_IP_TUNNEL_MODE_GRE:
 		return NM_LINK_TYPE_GRE;
-	case NM_IP_TUNNEL_MODE_GRETAP:
-		return NM_LINK_TYPE_GRETAP;
 	case NM_IP_TUNNEL_MODE_IPIP6:
 	case NM_IP_TUNNEL_MODE_IP6IP6:
 		return NM_LINK_TYPE_IP6TNL;
-	case NM_IP_TUNNEL_MODE_IP6GRE:
-		return NM_LINK_TYPE_IP6GRE;
-	case NM_IP_TUNNEL_MODE_IP6GRETAP:
-		return NM_LINK_TYPE_IP6GRETAP;
 	case NM_IP_TUNNEL_MODE_IPIP:
 		return NM_LINK_TYPE_IPIP;
 	case NM_IP_TUNNEL_MODE_SIT:
 		return NM_LINK_TYPE_SIT;
 	case NM_IP_TUNNEL_MODE_VTI:
+	case NM_IP_TUNNEL_MODE_IP6GRE:
 	case NM_IP_TUNNEL_MODE_VTI6:
 	case NM_IP_TUNNEL_MODE_ISATAP:
 		return NM_LINK_TYPE_UNKNOWN;
@@ -666,16 +595,11 @@ create_and_realize (NMDevice *device,
 	NMPlatformLnkIp6Tnl lnk_ip6tnl = { };
 	const char *str;
 	gint64 val;
-	NMIPTunnelMode mode;
 
 	s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
 	g_assert (s_ip_tunnel);
 
-	mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel);
-	switch (mode) {
-	case NM_IP_TUNNEL_MODE_GRETAP:
-		lnk_gre.is_tap = TRUE;
-		/* fall-through */
+	switch (nm_setting_ip_tunnel_get_mode (s_ip_tunnel)) {
 	case NM_IP_TUNNEL_MODE_GRE:
 		if (parent)
 			lnk_gre.parent_ifindex = nm_device_get_ifindex (parent);
@@ -776,8 +700,6 @@ create_and_realize (NMDevice *device,
 		break;
 	case NM_IP_TUNNEL_MODE_IPIP6:
 	case NM_IP_TUNNEL_MODE_IP6IP6:
-	case NM_IP_TUNNEL_MODE_IP6GRE:
-	case NM_IP_TUNNEL_MODE_IP6GRETAP:
 		if (parent)
 			lnk_ip6tnl.parent_ifindex = nm_device_get_ifindex (parent);
 
@@ -793,44 +715,13 @@ create_and_realize (NMDevice *device,
 		lnk_ip6tnl.tclass = nm_setting_ip_tunnel_get_tos (s_ip_tunnel);
 		lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel);
 		lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel);
+		lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6;
 		lnk_ip6tnl.flags = ip6tnl_flags_setting_to_plat (nm_setting_ip_tunnel_get_flags (s_ip_tunnel));
 
-		if (NM_IN_SET (mode, NM_IP_TUNNEL_MODE_IP6GRE, NM_IP_TUNNEL_MODE_IP6GRETAP)) {
-			val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel),
-			                                    10,
-			                                    0,
-			                                    G_MAXUINT32,
-			                                    -1);
-			if (val != -1) {
-				lnk_ip6tnl.input_key = val;
-				lnk_ip6tnl.input_flags = NM_GRE_KEY;
-			}
-
-			val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel),
-			                                    10,
-			                                    0,
-			                                    G_MAXUINT32,
-			                                    -1);
-			if (val != -1) {
-				lnk_ip6tnl.output_key = val;
-				lnk_ip6tnl.output_flags = NM_GRE_KEY;
-			}
-
-			lnk_ip6tnl.is_gre = TRUE;
-			lnk_ip6tnl.is_tap = (mode == NM_IP_TUNNEL_MODE_IP6GRETAP);
-
-			plerr = nm_platform_link_ip6gre_add (nm_device_get_platform (device),
-			                                     iface, &lnk_ip6tnl, out_plink);
-		} else {
-			lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6
-			                       ? IPPROTO_IPIP
-			                       : IPPROTO_IPV6;
-			plerr = nm_platform_link_ip6tnl_add (nm_device_get_platform (device),
-			                                     iface, &lnk_ip6tnl, out_plink);
-		}
+		plerr = nm_platform_link_ip6tnl_add (nm_device_get_platform (device), iface, &lnk_ip6tnl, out_plink);
 		if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
 			g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
-			             "Failed to create IPv6 tunnel interface '%s' for '%s': %s",
+			             "Failed to create IPIP interface '%s' for '%s': %s",
 			             iface,
 			             nm_connection_get_id (connection),
 			             nm_platform_error_to_string_a (plerr));
@@ -961,21 +852,6 @@ set_property (GObject *object, guint prop_id,
 	}
 }
 
-static NMActStageReturn
-act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
-{
-	NMActStageReturn ret;
-
-	ret = NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->act_stage1_prepare (device, out_failure_reason);
-	if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
-		return ret;
-
-	if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
-		return NM_ACT_STAGE_RETURN_FAILURE;
-
-	return NM_ACT_STAGE_RETURN_SUCCESS;
-}
-
 /*****************************************************************************/
 
 static void
@@ -988,11 +864,8 @@ constructed (GObject *object)
 {
 	NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE ((NMDeviceIPTunnel *) object);
 
-	if (NM_IN_SET (priv->mode,
-	               NM_IP_TUNNEL_MODE_IPIP6,
-	               NM_IP_TUNNEL_MODE_IP6IP6,
-	               NM_IP_TUNNEL_MODE_IP6GRE,
-	               NM_IP_TUNNEL_MODE_IP6GRETAP))
+	if (   priv->mode == NM_IP_TUNNEL_MODE_IPIP6
+	    || priv->mode == NM_IP_TUNNEL_MODE_IP6IP6)
 		priv->addr_family = AF_INET6;
 	else
 		priv->addr_family = AF_INET;
@@ -1052,17 +925,6 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
 
 	dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ip_tunnel);
 
-	device_class->connection_type_supported = NM_SETTING_IP_TUNNEL_SETTING_NAME;
-	device_class->connection_type_check_compatible = NM_SETTING_IP_TUNNEL_SETTING_NAME;
-	device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_GRE,
-	                                                        NM_LINK_TYPE_GRETAP,
-	                                                        NM_LINK_TYPE_IP6TNL,
-	                                                        NM_LINK_TYPE_IP6GRE,
-	                                                        NM_LINK_TYPE_IP6GRETAP,
-	                                                        NM_LINK_TYPE_IPIP,
-	                                                        NM_LINK_TYPE_SIT);
-
-	device_class->act_stage1_prepare = act_stage1_prepare;
 	device_class->link_changed = link_changed;
 	device_class->can_reapply_change = can_reapply_change;
 	device_class->complete_connection = complete_connection;
@@ -1073,6 +935,13 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
 	device_class->get_configured_mtu = get_configured_mtu;
 	device_class->unrealize_notify = unrealize_notify;
 
+	NM_DEVICE_CLASS_DECLARE_TYPES (klass,
+	                               NM_SETTING_IP_TUNNEL_SETTING_NAME,
+	                               NM_LINK_TYPE_GRE,
+	                               NM_LINK_TYPE_IP6TNL,
+	                               NM_LINK_TYPE_IPIP,
+	                               NM_LINK_TYPE_SIT);
+
 	obj_properties[PROP_MODE] =
 	     g_param_spec_uint (NM_DEVICE_IP_TUNNEL_MODE, "", "",
 	                        0, G_MAXUINT, 0,
@@ -1215,13 +1084,7 @@ get_connection_iface (NMDeviceFactory *factory,
 }
 
 NM_DEVICE_FACTORY_DEFINE_INTERNAL (IP_TUNNEL, IPTunnel, ip_tunnel,
-	NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE,
-	                                      NM_LINK_TYPE_GRETAP,
-	                                      NM_LINK_TYPE_SIT,
-	                                      NM_LINK_TYPE_IPIP,
-	                                      NM_LINK_TYPE_IP6TNL,
-	                                      NM_LINK_TYPE_IP6GRE,
-	                                      NM_LINK_TYPE_IP6GRETAP)
+	NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE, NM_LINK_TYPE_SIT, NM_LINK_TYPE_IPIP)
 	NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_IP_TUNNEL_SETTING_NAME),
 	factory_class->create_device = create_device;
 	factory_class->get_connection_parent = get_connection_parent;