static gboolean
match_parent (NMDeviceVlan *self, const char *parent)
{
	NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);

	g_return_val_if_fail (parent != NULL, FALSE);

	if (nm_utils_is_uuid (parent)) {
		NMActRequest *parent_req;
		NMConnection *parent_connection;

		/* If the parent is a UUID, the connection matches if our parent
		 * device has that connection activated.
		 */

		parent_req = nm_device_get_act_request (priv->parent);
		if (!parent_req)
			return FALSE;

		parent_connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (parent_req));
		if (!parent_connection)
			return FALSE;

		if (g_strcmp0 (parent, nm_connection_get_uuid (parent_connection)) != 0)
			return FALSE;
	} else {
		/* interface name */
		if (g_strcmp0 (parent, nm_device_get_ip_iface (priv->parent)) != 0)
			return FALSE;
	}

	return TRUE;
}
static gboolean
match_parent (NMDevice *dev_parent, const char *setting_parent)
{
	g_return_val_if_fail (setting_parent, FALSE);

	if (!dev_parent)
		return FALSE;

	if (nm_utils_is_uuid (setting_parent)) {
		NMActRequest *parent_req;
		NMConnection *parent_connection;

		/* If the parent is a UUID, the connection matches if our parent
		 * device has that connection activated.
		 */
		parent_req = nm_device_get_act_request (dev_parent);
		if (!parent_req)
			return FALSE;

		parent_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (parent_req));
		if (!parent_connection)
			return FALSE;

		if (g_strcmp0 (setting_parent, nm_connection_get_uuid (parent_connection)) != 0)
			return FALSE;
	} else {
		/* interface name */
		if (g_strcmp0 (setting_parent, nm_device_get_ip_iface (dev_parent)) != 0)
			return FALSE;
	}

	return TRUE;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
    NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
    NMSettingConnection *s_con;
    NMSettingWired *s_wired;

    if (connection) {
        s_con = nm_connection_get_setting_connection (connection);
        s_wired = nm_connection_get_setting_wired (connection);
    } else {
        s_con = NULL;
        s_wired = NULL;
    }

    if (priv->parent) {
        if (   !nm_utils_is_uuid (priv->parent)
                && !nm_utils_iface_valid_name (priv->parent)) {
            g_set_error (error,
                         NM_CONNECTION_ERROR,
                         NM_CONNECTION_ERROR_INVALID_PROPERTY,
                         _("'%s' is neither an UUID nor an interface name"),
                         priv->parent);
            g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
            return FALSE;
        }
    } else {
        /* If parent is NULL, the parent must be specified via
         * NMSettingWired:mac-address.
         */
        if (   connection
                && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
            g_set_error (error,
                         NM_CONNECTION_ERROR,
                         NM_CONNECTION_ERROR_MISSING_PROPERTY,
                         _("property is not specified and neither is '%s:%s'"),
                         NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
            g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
            return FALSE;
        }
    }

    if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) {
        g_set_error_literal (error,
                             NM_CONNECTION_ERROR,
                             NM_CONNECTION_ERROR_INVALID_PROPERTY,
                             _("non promiscuous operation is allowed only in passthru mode'"));
        g_prefix_error (error, "%s.%s: ",
                        NM_SETTING_MACVLAN_SETTING_NAME,
                        NM_SETTING_MACVLAN_PROMISCUOUS);
        return FALSE;

    }

    return TRUE;
}
/**
 * nmt_connect_connection_list_get_connection:
 * @list: an #NmtConnectConnectionList
 * @identifier: a connection ID or UUID, or device name
 * @connection: (out) (transfer none): the #NMConnection to be activated
 * @device: (out) (transfer none): the #NMDevice to activate @connection on
 * @specific_object: (out) (transfer none): the "specific object" to connect to
 * @active: (out) (transfer none): the #NMActiveConnection corresponding
 *   to the selection, if any.
 *
 * Gets information about the indicated connection.
 *
 * Returns: %TRUE if there was a match, %FALSE if not.
 */
gboolean
nmt_connect_connection_list_get_connection (NmtConnectConnectionList  *list,
                                            const char                *identifier,
                                            NMConnection             **connection,
                                            NMDevice                 **device,
                                            NMObject                 **specific_object,
                                            NMActiveConnection       **active)
{
	NmtConnectConnectionListPrivate *priv = NMT_CONNECT_CONNECTION_LIST_GET_PRIVATE (list);
	GSList *diter, *citer;
	NmtConnectDevice *nmtdev;
	NmtConnectConnection *nmtconn = NULL;
	NMConnection *conn = NULL;

	g_return_val_if_fail (identifier, FALSE);

	if (nm_utils_is_uuid (identifier))
		conn = NM_CONNECTION (nm_client_get_connection_by_uuid (nm_client, identifier));
	if (!conn)
		conn = NM_CONNECTION (nm_client_get_connection_by_id (nm_client, identifier));

	for (diter = priv->nmt_devices; diter; diter = diter->next) {
		nmtdev = diter->data;
		if (!nmtdev->conns)
			continue;

		for (citer = nmtdev->conns; citer; citer = citer->next) {
			nmtconn = citer->data;
			if (conn) {
				if (conn == nmtconn->conn)
					goto found;
			} else if (nmtconn->ssid && !strcmp (identifier, nmtconn->ssid))
				goto found;
		}

		if (!conn && nmtdev->device && !strcmp (identifier, nm_device_get_ip_iface (nmtdev->device))) {
			nmtconn = nmtdev->conns->data;
			goto found;
		}
	}

	return FALSE;

 found:
	if (connection)
		*connection = nmtconn->conn;
	if (device)
		*device = nmtconn->device;
	if (specific_object)
		*specific_object = NM_OBJECT (nmtconn->ap);
	if (active)
		*active = nmtconn->active;

	return TRUE;
}
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);

}
NmtNewtForm *
nmtui_edit (gboolean is_top, int argc, char **argv)
{
	NMConnection *conn = NULL;

	if (argc == 2) {
		if (nm_utils_is_uuid (argv[1]))
			conn = NM_CONNECTION (nm_client_get_connection_by_uuid (nm_client, argv[1]));
		if (!conn)
			conn = NM_CONNECTION (nm_client_get_connection_by_id (nm_client, argv[1]));

		if (!conn) {
			nmt_newt_message_dialog ("%s: no such connection '%s'\n", argv[0], argv[1]);
			return NULL;
		}

		return nmt_editor_new (conn);
	} else
		return nmt_edit_main_connection_list (is_top);
}
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);
	}
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
	int family = AF_UNSPEC;

	switch (priv->mode) {
	case NM_IP_TUNNEL_MODE_IPIP:
	case NM_IP_TUNNEL_MODE_SIT:
	case NM_IP_TUNNEL_MODE_ISATAP:
	case NM_IP_TUNNEL_MODE_GRE:
	case NM_IP_TUNNEL_MODE_VTI:
		family = AF_INET;
		break;
	case NM_IP_TUNNEL_MODE_IP6IP6:
	case NM_IP_TUNNEL_MODE_IPIP6:
	case NM_IP_TUNNEL_MODE_IP6GRE:
	case NM_IP_TUNNEL_MODE_VTI6:
		family = AF_INET6;
		break;
	case NM_IP_TUNNEL_MODE_UNKNOWN:
		break;
	}

	if (family == AF_UNSPEC) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%d' is not a valid tunnel mode"),
		             (int) priv->mode);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE);
		return FALSE;
	}

	if (   priv->parent
	    && !nm_utils_iface_valid_name (priv->parent)
	    && !nm_utils_is_uuid (priv->parent)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is neither an UUID nor an interface name"),
		             priv->parent);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
		                NM_SETTING_IP_TUNNEL_PARENT);
		return FALSE;
	}

	if (priv->local && !nm_utils_ipaddr_valid (family, priv->local)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IPv%c address"),
		             priv->local,
		             family == AF_INET ? '4' : '6');
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL);
		return FALSE;
	}

	if (!priv->remote) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
		return FALSE;
	}

	if (!nm_utils_ipaddr_valid (family, priv->remote)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IPv%c address"),
		             priv->remote,
		             family == AF_INET ? '4' : '6');
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
		return FALSE;
	}

	if (   (priv->input_key && priv->input_key[0])
	    || (priv->output_key && priv->output_key[0])) {
		if (   priv->mode != NM_IP_TUNNEL_MODE_GRE
		    && priv->mode != NM_IP_TUNNEL_MODE_IP6GRE) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("tunnel keys can only be specified for GRE tunnels"));
			return FALSE;
		}
	}

	if (priv->input_key && priv->input_key[0]) {
		gint64 val;

		val = _nm_utils_ascii_str_to_int64 (priv->input_key, 10, 0, G_MAXUINT32, -1);
		if (val == -1) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid tunnel key"),
			             priv->input_key);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
			                NM_SETTING_IP_TUNNEL_INPUT_KEY);
		return FALSE;
		}
	}

	if (priv->output_key && priv->output_key[0]) {
		gint64 val;

		val = _nm_utils_ascii_str_to_int64 (priv->output_key, 10, 0, G_MAXUINT32, -1);
		if (val == -1) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid tunnel key"),
			             priv->output_key);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
			                NM_SETTING_IP_TUNNEL_OUTPUT_KEY);
		return FALSE;
		}
	}

	if (!priv->path_mtu_discovery && priv->ttl != 0) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("a fixed TTL is allowed only when path MTU discovery is enabled"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
		                NM_SETTING_IP_TUNNEL_TTL);
		return FALSE;
	}

	return TRUE;
}
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);

	if (!priv->id) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
		             NM_SETTING_CONNECTION_ID);
		return FALSE;
	} else if (!strlen (priv->id)) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
		             NM_SETTING_CONNECTION_ID);
		return FALSE;
	}

	if (!priv->uuid) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
		             NM_SETTING_CONNECTION_UUID);
		return FALSE;
	} else if (!nm_utils_is_uuid (priv->uuid)) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
		             NM_SETTING_CONNECTION_UUID);
		return FALSE;
	}

	if (!priv->type) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY,
		             NM_SETTING_CONNECTION_TYPE);
		return FALSE;
	} else if (!strlen (priv->type)) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY,
		             NM_SETTING_CONNECTION_TYPE);
		return FALSE;
	}

	/* Make sure the corresponding 'type' item is present */
	if (all_settings && !g_slist_find_custom (all_settings, priv->type, find_setting_by_name)) {
		g_set_error (error,
		             NM_SETTING_CONNECTION_ERROR,
		             NM_SETTING_CONNECTION_ERROR_TYPE_SETTING_NOT_FOUND,
		             NM_SETTING_CONNECTION_TYPE);
		return FALSE;
	}

	/*
	 * Bonding: Slaves are not allowed to have any IP configuration.
	 */
	if (priv->slave_type && all_settings &&
	    !strcmp(priv->slave_type, NM_SETTING_BOND_SETTING_NAME)) {
		GSList *list;

		list = g_slist_find_custom (all_settings, NM_SETTING_IP4_CONFIG_SETTING_NAME,
		                            find_setting_by_name);
		if (list) {
			NMSettingIP4Config *s_ip4 = g_slist_nth_data (list, 0);
			g_assert (s_ip4);

			if (strcmp (nm_setting_ip4_config_get_method (s_ip4),
			            NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
				g_set_error (error,
				             NM_SETTING_CONNECTION_ERROR,
				             NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED,
				             "No IP configuration allowed for bonding slave");
				return FALSE;
			}
		}

		list = g_slist_find_custom (all_settings, NM_SETTING_IP6_CONFIG_SETTING_NAME,
		                            find_setting_by_name);
		if (list) {
			NMSettingIP6Config *s_ip6 = g_slist_nth_data (list, 0);
			g_assert (s_ip6);

			if (strcmp (nm_setting_ip6_config_get_method (s_ip6),
			            NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
				g_set_error (error,
				             NM_SETTING_CONNECTION_ERROR,
				             NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED,
				             "No IPv6 configuration allowed for bonding slave");
				return FALSE;
			}
		}
	}

	return TRUE;
}
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting);
	NMSettingConnection *s_con = NULL;
	NMSettingWired *s_wired = NULL;
	GSList *iter;

	for (iter = all_settings; iter; iter = iter->next) {
		if (NM_IS_SETTING_CONNECTION (iter->data))
			s_con = iter->data;
		else if (NM_IS_SETTING_WIRED (iter->data))
			s_wired = iter->data;
	}

	/* If iface_name is specified, it must be a valid interface name. We
	 * don't check that it matches parent and/or id, because we allowing
	 * renaming vlans to arbitrary names.
	 */
	if (priv->iface_name && !nm_utils_iface_valid_name (priv->iface_name)) {
		g_set_error (error,
		             NM_SETTING_VLAN_ERROR,
		             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
		             NM_SETTING_VLAN_INTERFACE_NAME);
		return FALSE;
	}

	if (priv->parent) {
		if (nm_utils_is_uuid (priv->parent)) {
			/* If we have an NMSettingConnection:master with slave-type="vlan",
			 * then it must be the same UUID.
			 */
			if (s_con) {
				const char *master = NULL, *slave_type = NULL;

				slave_type = nm_setting_connection_get_slave_type (s_con);
				if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME))
					master = nm_setting_connection_get_master (s_con);

				if (master && g_strcmp0 (priv->parent, master) != 0) {
					g_set_error (error,
					             NM_SETTING_VLAN_ERROR,
					             NM_SETTING_VLAN_ERROR_INVALID_PARENT,
					             NM_SETTING_CONNECTION_MASTER);
					return FALSE;
				}
			}
		} else if (!nm_utils_iface_valid_name (priv->parent)) {
			/* parent must be either a UUID or an interface name */
			g_set_error (error,
			             NM_SETTING_VLAN_ERROR,
			             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
			             NM_SETTING_VLAN_PARENT);
			return FALSE;
		} 
	} else {
		/* If parent is NULL, the parent must be specified via
		 * NMSettingWired:mac-address.
		 */
		if (!s_wired || !nm_setting_wired_get_mac_address (s_wired)) {
			g_set_error (error,
			             NM_SETTING_VLAN_ERROR,
			             NM_SETTING_VLAN_ERROR_MISSING_PROPERTY,
			             NM_SETTING_VLAN_PARENT);
			return FALSE;
		}
	}

	if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS |
	                    NM_VLAN_FLAG_GVRP |
	                    NM_VLAN_FLAG_LOOSE_BINDING)) {
		g_set_error (error,
		             NM_SETTING_VLAN_ERROR,
		             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
		             NM_SETTING_VLAN_FLAGS);
		return FALSE;
	}

	return TRUE;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting);
	NMSettingConnection *s_con;
	NMSettingWired *s_wired;

	if (connection) {
		s_con = nm_connection_get_setting_connection (connection);
		s_wired = nm_connection_get_setting_wired (connection);
	} else {
		s_con = NULL;
		s_wired = NULL;
	}

	if (priv->parent) {
		if (nm_utils_is_uuid (priv->parent)) {
			/* If we have an NMSettingConnection:master with slave-type="vlan",
			 * then it must be the same UUID.
			 */
			if (s_con) {
				const char *master = NULL, *slave_type = NULL;

				slave_type = nm_setting_connection_get_slave_type (s_con);
				if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME))
					master = nm_setting_connection_get_master (s_con);

				if (master && g_strcmp0 (priv->parent, master) != 0) {
					g_set_error (error,
					             NM_CONNECTION_ERROR,
					             NM_CONNECTION_ERROR_INVALID_PROPERTY,
					             _("'%s' value doesn't match '%s=%s'"),
					             priv->parent, NM_SETTING_CONNECTION_MASTER, master);
					g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT);
					return FALSE;
				}
			}
		} else if (!nm_utils_iface_valid_name (priv->parent)) {
			/* parent must be either a UUID or an interface name */
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is neither an UUID nor an interface name"),
			             priv->parent);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT);
			return FALSE;
		}
	} else {
		/* If parent is NULL, the parent must be specified via
		 * NMSettingWired:mac-address.
		 */
		if (   connection
		    && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_MISSING_PROPERTY,
			             _("property is not specified and neither is '%s:%s'"),
			             NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_PARENT);
			return FALSE;
		}
	}

	if (priv->id >= 4095) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("the vlan id must be in range 0-4094 but is %u"),
		             priv->id);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_ID);
	}

	if (priv->flags & ~NM_VLAN_FLAGS_ALL) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("flags are invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VLAN_FLAGS);
		return FALSE;
	}

	return TRUE;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting);
	int family = AF_UNSPEC;

	if (!priv->remote) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_MISSING_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_REMOTE);
		return FALSE;
	}

	if (nm_utils_ipaddr_valid (AF_INET, priv->remote))
		family = AF_INET;
	else if (nm_utils_ipaddr_valid (AF_INET6, priv->remote))
		family = AF_INET6;
	else {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid IP address"),
		             priv->remote);
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_REMOTE);
		return FALSE;
	}

	if (priv->local) {
		if (!nm_utils_ipaddr_valid (family, priv->local)) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid IP%c address"),
			             priv->local, family == AF_INET ? '4' : '6');
			g_prefix_error (error, "%s.%s: ",
			                NM_SETTING_VXLAN_SETTING_NAME,
			                NM_SETTING_VXLAN_LOCAL);
			return FALSE;
		}
	}

	if (   priv->parent
	    && !nm_utils_iface_valid_name (priv->parent)
	    && !nm_utils_is_uuid (priv->parent)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' is neither an UUID nor an interface name"),
		             priv->parent);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_PARENT);
		return FALSE;
	}

	if (   (priv->source_port_min || priv->source_port_max)
	    && (priv->source_port_min > priv->source_port_max)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("%d is greater than local port max %d"),
		             priv->source_port_min,
		             priv->source_port_max);
		g_prefix_error (error, "%s.%s: ",
		                NM_SETTING_VXLAN_SETTING_NAME,
		                NM_SETTING_VXLAN_SOURCE_PORT_MIN);
		return FALSE;
	}

	return TRUE;
}