Пример #1
0
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting);
	GHashTableIter iter;
	const char *key, *value;
	const char *valid_modes[] = { "balance-rr",
	                              "active-backup",
	                              "balance-xor",
	                              "broadcast",
	                              "802.3ad",
	                              "balance-tlb",
	                              "balance-alb",
	                              NULL };
	int miimon = 0, arp_interval = 0;
	const char *arp_ip_target = NULL;
	const char *primary;

	if (!priv->interface_name || !strlen(priv->interface_name)) {
		g_set_error_literal (error,
		                     NM_SETTING_BOND_ERROR,
		                     NM_SETTING_BOND_ERROR_MISSING_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME);
		return FALSE;
	}

	if (!nm_utils_iface_valid_name (priv->interface_name)) {
		g_set_error_literal (error,
		                     NM_SETTING_BOND_ERROR,
		                     NM_SETTING_BOND_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_INTERFACE_NAME);
		return FALSE;
	}

	g_hash_table_iter_init (&iter, priv->options);
	while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) {
		if (!value[0] || !nm_setting_bond_validate_option (key, value)) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("invalid option '%s' or its value '%s'"),
			             key, value);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MIIMON);
	if (value)
		miimon = atoi (value);
	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
	if (value)
		arp_interval = atoi (value);

	/* Can only set one of miimon and arp_interval */
	if (miimon > 0 && arp_interval > 0) {
		g_set_error (error,
		             NM_SETTING_BOND_ERROR,
		             NM_SETTING_BOND_ERROR_INVALID_OPTION,
		             _("only one of '%s' and '%s' can be set"),
		             NM_SETTING_BOND_OPTION_MIIMON,
		             NM_SETTING_BOND_OPTION_ARP_INTERVAL);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
	}

	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
	if (!value) {
		g_set_error (error,
		             NM_SETTING_BOND_ERROR,
		             NM_SETTING_BOND_ERROR_MISSING_OPTION,
		             _("mandatory option '%s' is missing"),
		             NM_SETTING_BOND_OPTION_MODE);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
		return FALSE;
	}
	if (!_nm_utils_string_in_list (value, valid_modes)) {
		g_set_error (error,
		             NM_SETTING_BOND_ERROR,
		             NM_SETTING_BOND_ERROR_INVALID_OPTION,
		             _("'%s' is not a valid value for '%s'"),
		             value, NM_SETTING_BOND_OPTION_MODE);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
		return FALSE;
	}

	/* Make sure mode is compatible with other settings */
	if (   strcmp (value, "balance-alb") == 0
	    || strcmp (value, "balance-tlb") == 0) {
		if (arp_interval > 0) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s=%s' is incompatible with '%s > 0'"),
			             NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	primary = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_PRIMARY);
	if (strcmp (value, "active-backup") == 0) {
		if (primary && !nm_utils_iface_valid_name (primary)) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' is not a valid interface name for '%s' option"),
			             primary, NM_SETTING_BOND_OPTION_PRIMARY);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	} else {
		if (primary) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' option is only valid for '%s=%s'"),
			             NM_SETTING_BOND_OPTION_PRIMARY,
			             NM_SETTING_BOND_OPTION_MODE, "active-backup");
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	if (nm_setting_find_in_list (all_settings, NM_SETTING_INFINIBAND_SETTING_NAME)) {
		if (strcmp (value, "active-backup") != 0) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s=%s' is not a valid configuration for '%s'"),
			             NM_SETTING_BOND_OPTION_MODE, value, NM_SETTING_INFINIBAND_SETTING_NAME);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	if (miimon == 0) {
		/* updelay and downdelay can only be used with miimon */
		if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_UPDELAY)) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' option requires '%s' option to be set"),
			             NM_SETTING_BOND_OPTION_UPDELAY, NM_SETTING_BOND_OPTION_MIIMON);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
		if (g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY)) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' option requires '%s' option to be set"),
			             NM_SETTING_BOND_OPTION_DOWNDELAY, NM_SETTING_BOND_OPTION_MIIMON);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	/* arp_ip_target can only be used with arp_interval, and must
	 * contain a comma-separated list of IPv4 addresses.
	 */
	arp_ip_target = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
	if (arp_interval > 0) {
		char **addrs;
		guint32 addr;
		int i;

		if (!arp_ip_target) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_MISSING_OPTION,
			             _("'%s' option requires '%s' option to be set"),
			             NM_SETTING_BOND_OPTION_ARP_INTERVAL, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}

		addrs = g_strsplit (arp_ip_target, ",", -1);
		if (!addrs[0]) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' option is empty"),
			             NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			g_strfreev (addrs);
			return FALSE;
		}

		for (i = 0; addrs[i]; i++) {
			if (!inet_pton (AF_INET, addrs[i], &addr)) {
				g_set_error (error,
				             NM_SETTING_BOND_ERROR,
				             NM_SETTING_BOND_ERROR_INVALID_OPTION,
				             _("'%s' is not a valid IPv4 address for '%s' option"),
				             NM_SETTING_BOND_OPTION_ARP_IP_TARGET, addrs[i]);
				g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
				g_strfreev (addrs);
				return FALSE;
			}
		}
		g_strfreev (addrs);
	} else {
		if (arp_ip_target) {
			g_set_error (error,
			             NM_SETTING_BOND_ERROR,
			             NM_SETTING_BOND_ERROR_INVALID_OPTION,
			             _("'%s' option requires '%s' option to be set"),
			             NM_SETTING_BOND_OPTION_ARP_IP_TARGET, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
			return FALSE;
		}
	}

	return TRUE;
}
Пример #2
0
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (setting);

	if (!priv->bdaddr) {
		g_set_error_literal (error,
		                     NM_SETTING_BLUETOOTH_ERROR,
		                     NM_SETTING_BLUETOOTH_ERROR_MISSING_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR);
		return FALSE;
	}

	if (priv->bdaddr && priv->bdaddr->len != ETH_ALEN) {
		g_set_error_literal (error,
		                     NM_SETTING_BLUETOOTH_ERROR,
		                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR);
		return FALSE;
	}

	if (!priv->type) {
		g_set_error_literal (error,
		                     NM_SETTING_BLUETOOTH_ERROR,
		                     NM_SETTING_BLUETOOTH_ERROR_MISSING_PROPERTY,
		                     _("property is missing"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
		return FALSE;
	} else if (!g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN) &&
	           !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) {
		g_set_error (error,
		             NM_SETTING_BLUETOOTH_ERROR,
		             NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
		             _("'%s' is not a valid value for the property"),
		             priv->type);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
		return FALSE;
	}

	/* Make sure the corresponding 'type' setting is present */
	if (   all_settings
	    && !strcmp (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN)) {
		gboolean gsm = FALSE, cdma = FALSE;

		gsm = !!nm_setting_find_in_list (all_settings, NM_SETTING_GSM_SETTING_NAME);
		cdma = !!nm_setting_find_in_list (all_settings, NM_SETTING_CDMA_SETTING_NAME);

		if (!gsm && !cdma) {
			g_set_error (error,
			             NM_SETTING_BLUETOOTH_ERROR,
			             NM_SETTING_BLUETOOTH_ERROR_TYPE_SETTING_NOT_FOUND,
			             _("requires '%s' or '%s' setting"),
			             NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
			return FALSE;
		}
	}
	/* PANU doesn't need a 'type' setting since no further configuration
	 * is required at the interface level.
	 */

	return TRUE;
}