static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMDeviceVlan *self = NM_DEVICE_VLAN (device);
	NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device);
	NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection);
	int ifindex = nm_device_get_ifindex (device);
	int parent_ifindex = -1, vlan_id = -1;
	NMDevice *parent;
	const char *setting_parent, *new_parent;

	if (!s_vlan) {
		s_vlan = (NMSettingVlan *) nm_setting_vlan_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_vlan);
	}

	if (!nm_platform_vlan_get_info (NM_PLATFORM_GET, ifindex, &parent_ifindex, &vlan_id)) {
		_LOGW (LOGD_VLAN, "failed to get VLAN interface info while updating connection.");
		return;
	}

	if (priv->vlan_id != vlan_id) {
		priv->vlan_id = vlan_id;
		g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID);
	}

	if (vlan_id != nm_setting_vlan_get_id (s_vlan))
		g_object_set (s_vlan, NM_SETTING_VLAN_ID, priv->vlan_id, NULL);

	if (parent_ifindex != NM_PLATFORM_LINK_OTHER_NETNS)
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex);
	else
		parent = NULL;
	nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), parent);

	/* Update parent in the connection; default to parent's interface name */
	if (parent) {
		new_parent = nm_device_get_iface (parent);
		setting_parent = nm_setting_vlan_get_parent (s_vlan);
		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 = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (), setting_parent);
			if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection))
				new_parent = NULL;
		}
		if (new_parent)
			g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, new_parent, NULL);
	} else
		g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, NULL, NULL);
}
static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
	NMSettingMacvlan *s_macvlan = nm_connection_get_setting_macvlan (connection);
	const char *setting_parent, *new_parent;
	int new_mode;

	if (!s_macvlan) {
		s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_macvlan);
	}

	new_mode = platform_mode_to_setting (priv->props.mode);
	if (new_mode != nm_setting_macvlan_get_mode (s_macvlan))
		g_object_set (s_macvlan, NM_SETTING_MACVLAN_MODE, new_mode, NULL);

	if (priv->props.no_promisc == nm_setting_macvlan_get_promiscuous (s_macvlan))
		g_object_set (s_macvlan, NM_SETTING_MACVLAN_PROMISCUOUS, !priv->props.no_promisc, NULL);


	if (priv->props.tap != nm_setting_macvlan_get_tap (s_macvlan))
		g_object_set (s_macvlan, NM_SETTING_MACVLAN_TAP, !!priv->props.tap, NULL);

	/* Update parent in the connection; default to parent's interface name */
	if (priv->parent) {
		new_parent = nm_device_get_iface (priv->parent);
		setting_parent = nm_setting_macvlan_get_parent (s_macvlan);
		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 (priv->parent, parent_connection))
				new_parent = NULL;
		}
		if (new_parent)
			g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, new_parent, NULL);
	} else
		g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, NULL, NULL);

}
static void
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 ();
		nm_connection_add_setting (connection, (NMSetting *) s_ip_tunnel);
	}

	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);

	if (priv->parent_ifindex > 0)
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->parent_ifindex);

	/* 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 = nm_connection_provider_get_connection_by_uuid (nm_connection_provider_get (),
			                                                                   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),
	                       priv->local))
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_LOCAL, priv->local, NULL);

	if (!address_equal_pp (priv->addr_family,
	                       nm_setting_ip_tunnel_get_remote (s_ip_tunnel),
	                       priv->remote))
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_REMOTE, priv->remote, NULL);

	if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl)
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TTL, priv->ttl, NULL);

	if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos)
		g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_TOS, priv->tos, NULL);

	if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		              NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY,
		              priv->path_mtu_discovery,
		              NULL);
	}

	if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		                        NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT,
		                        priv->encap_limit,
		                        NULL);
	}

	if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) {
		g_object_set (G_OBJECT (s_ip_tunnel),
		                        NM_SETTING_IP_TUNNEL_FLOW_LABEL,
		                        priv->flow_label,
		                        NULL);
	}

	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,
			              priv->input_key,
			              NULL);
		}
		if (g_strcmp0 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), priv->output_key)) {
			g_object_set (G_OBJECT (s_ip_tunnel),
			              NM_SETTING_IP_TUNNEL_OUTPUT_KEY,
			              priv->output_key,
			              NULL);
		}
	}
}
static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
	NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection);
	NMDevice *parent = NULL;
	const char *setting_parent, *new_parent;

	if (!s_vxlan) {
		s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_vxlan);
	}

	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);

	if (priv->props.parent_ifindex != NM_PLATFORM_LINK_OTHER_NETNS)
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex);

	/* Update parent in the connection; default to parent's interface name */
	if (parent) {
		new_parent = nm_device_get_iface (parent);
		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, parent_connection))
				new_parent = NULL;
		}
		if (new_parent)
			g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, new_parent, NULL);
	} else
		g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, NULL, NULL);

	if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) {
		if (priv->props.group) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
			              nm_utils_inet4_ntop (priv->props.group, NULL),
			              NULL);
		} else {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
			              nm_utils_inet6_ntop (&priv->props.group6, NULL),
			              NULL);
		}
	}

	if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) {
		if (priv->props.local) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
			              nm_utils_inet4_ntop (priv->props.local, NULL),
			              NULL);
		} else if (memcmp (&priv->props.local6, &in6addr_any, sizeof (in6addr_any))) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
			              nm_utils_inet6_ntop (&priv->props.local6, NULL),
			              NULL);
		}
	}

	if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MIN,
		              priv->props.src_port_min, NULL);
	}

	if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MAX,
		              priv->props.src_port_max, NULL);
	}

	if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_DESTINATION_PORT,
		              priv->props.dst_port, NULL);
	}

	if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TOS,
		              priv->props.tos, NULL);
	}

	if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TTL,
		              priv->props.ttl, NULL);
	}

	if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_LEARNING,
		              priv->props.learning, NULL);
	}

	if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_AGEING,
		              priv->props.ageing, NULL);
	}

	if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_PROXY,
		              priv->props.proxy, NULL);
	}

	if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_RSC,
		              priv->props.rsc, NULL);
	}

	if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L2_MISS,
		              priv->props.l2miss, NULL);
	}

	if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L3_MISS,
		              priv->props.l3miss, NULL);
	}
}