Пример #1
0
static gboolean
device_entry_parse (NmtDeviceEntry  *deventry,
                    const char      *text,
                    char           **interface_name,
                    char           **mac_address)
{
    NmtDeviceEntryPrivate *priv = NMT_DEVICE_ENTRY_GET_PRIVATE (deventry);
    guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
    char **words;
    int len;

    *interface_name = *mac_address = NULL;
    if (!*text)
        return TRUE;

    if (priv->hardware_type == G_TYPE_NONE && !priv->device_filter) {
        if (nm_utils_iface_valid_name (text)) {
            *interface_name = g_strdup (text);
            return TRUE;
        } else
            return FALSE;
    }

    words = g_strsplit (text, " ", -1);
    if (g_strv_length (words) > 2) {
        g_strfreev (words);
        return FALSE;
    }

    if (words[1]) {
        len = strlen (words[1]);
        if (len < 3 || words[1][0] != '(' || words[1][len - 1] != ')')
            goto fail;

        memmove (words[1], words[1] + 1, len - 2);
        words[1][len - 2] = '\0';
    }

    len = nm_utils_hwaddr_len (priv->arptype);
    if (   nm_utils_hwaddr_aton (words[0], buf, len)
            && (!words[1] || nm_utils_iface_valid_name (words[1]))) {
        *mac_address = words[0];
        *interface_name = NULL;
        g_free (words);
        return TRUE;
    } else if (   nm_utils_iface_valid_name (words[0])
                  && (!words[1] || nm_utils_hwaddr_aton (words[1], buf, len))) {
        *interface_name = words[0];
        *mac_address = NULL;
        g_free (words);
        return TRUE;
    }

fail:
    g_strfreev (words);
    return FALSE;
}
Пример #2
0
gboolean
ce_page_device_entry_get (GtkEntry *entry, int type, gboolean check_ifname,
                          char **ifname, char **mac, const char *device_name, GError **error)
{
	char *first, *second;
	const char *ifname_tmp = NULL, *mac_tmp = NULL;
	gboolean valid = TRUE;
	const char *str;

	g_return_val_if_fail (entry != NULL, FALSE);
	g_return_val_if_fail (GTK_IS_ENTRY (entry), FALSE);

	str = gtk_entry_get_text (entry);

	valid = _device_entry_parse (str, &first, &second);

	if (first) {
		if (nm_utils_hwaddr_valid (first, nm_utils_hwaddr_len (type)))
			mac_tmp = first;
		else if (!check_ifname || nm_utils_iface_valid_name (first))
			ifname_tmp = first;
		else
			valid = FALSE;
	}
	if (second) {
		if (nm_utils_hwaddr_valid (second, nm_utils_hwaddr_len (type))) {
			if (!mac_tmp)
				mac_tmp = second;
			else
				valid = FALSE;
		} else if (!check_ifname || nm_utils_iface_valid_name (second)) {
			if (!ifname_tmp)
				ifname_tmp = second;
			else
				valid = FALSE;
		} else
			valid = FALSE;
	}

	if (ifname)
		*ifname = g_strdup (ifname_tmp);
	if (mac)
		*mac = g_strdup (mac_tmp);

	g_free (first);
	g_free (second);

	if (!valid) {
		g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
		             _("invalid %s (%s)"),
		             device_name ? device_name : _("device"),
		             str);
	}

	return valid;
}
Пример #3
0
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);

	if (priv->mac_address && priv->mac_address->len != INFINIBAND_ALEN) {
		g_set_error_literal (error,
		                     NM_SETTING_INFINIBAND_ERROR,
		                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS);
		return FALSE;
	}

	if (!g_strcmp0 (priv->transport_mode, "datagram")) {
		if (priv->mtu > 2044)
			priv->mtu = 2044;
	} else if (!g_strcmp0 (priv->transport_mode, "connected")) {
		if (priv->mtu > 65520)
			priv->mtu = 65520;
	} else {
		g_set_error_literal (error,
		                     NM_SETTING_INFINIBAND_ERROR,
		                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE);
		return FALSE;
	}

	if (priv->parent) {
		if (!nm_utils_iface_valid_name (priv->parent)) {
			g_set_error_literal (error,
			                     NM_SETTING_INFINIBAND_ERROR,
			                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
			                     _("not a valid interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
		if (priv->p_key == -1) {
			g_set_error_literal (error,
			                     NM_SETTING_INFINIBAND_ERROR,
			                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
			                     _("Must specify a P_Key if specifying parent"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
		}
	}

	if (priv->p_key != -1) {
		if (!priv->mac_address && !priv->parent) {
			g_set_error_literal (error,
			                     NM_SETTING_INFINIBAND_ERROR,
			                     NM_SETTING_INFINIBAND_ERROR_MISSING_PROPERTY,
			                     _("InfiniBand P_Key connection did not specify parent interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
	}

	return TRUE;
}
Пример #4
0
static gboolean
validate_ifname (const char *name, const char *value)
{
	if (!value || !value[0])
		return FALSE;

	return nm_utils_iface_valid_name (value);
}
Пример #5
0
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;
}
Пример #6
0
static NMDevice *
find_vlan_parent (GSList *connections, NMApplet *applet)
{
	const GPtrArray *devices;
	NMDevice *parent_device;
	GSList *iter;

	devices = nm_client_get_devices (applet->nm_client);
	if (!devices)
		return NULL;

	for (iter = connections; iter; iter = iter->next) {
		NMConnection *connection = iter->data;
		NMSettingVlan *s_vlan;
		const char *parent;

		s_vlan = nm_connection_get_setting_vlan (connection);
		g_return_val_if_fail (s_vlan != NULL, NULL);

		parent = nm_setting_vlan_get_parent (s_vlan);
		if (parent && nm_utils_iface_valid_name (parent)) {
			parent_device = find_device_by_iface (parent, devices);
		} else {
			NMSettingConnection *s_con;
			NMSetting *s_hw;
			const char *type;
			GByteArray *mac;

			s_con = nm_connection_get_setting_connection (connection);
			type = nm_setting_connection_get_connection_type (s_con);
			s_hw = nm_connection_get_setting_by_name (connection, type);
			if (!s_hw) {
				g_warn_if_reached ();
				continue;
			}

			if (!g_object_class_find_property (G_OBJECT_GET_CLASS (s_hw),
			                                   "mac-address"))
				continue;

			g_object_get (G_OBJECT (s_hw),
			              "mac-address", &mac,
			              NULL);
			if (mac) {
				parent_device = find_device_by_mac (mac, devices);
				g_byte_array_unref (mac);
			} else
				parent_device = NULL;
		}
		
		if (parent_device)
			return parent_device;
	}

	return NULL;
}
Пример #7
0
static gboolean
verify (NMSetting *setting, GSList *all_settings, GError **error)
{
	NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);

	if (!priv->interface_name || !strlen(priv->interface_name)) {
		g_set_error (error,
		             NM_SETTING_BRIDGE_ERROR,
		             NM_SETTING_BRIDGE_ERROR_MISSING_PROPERTY,
		             NM_SETTING_BRIDGE_INTERFACE_NAME);
		return FALSE;
	}

	if (!nm_utils_iface_valid_name (priv->interface_name)) {
		g_set_error (error,
		             NM_SETTING_BRIDGE_ERROR,
		             NM_SETTING_BRIDGE_ERROR_INVALID_PROPERTY,
		             NM_SETTING_BRIDGE_INTERFACE_NAME);
		return FALSE;
	}

	if (!check_range (priv->forward_delay,
	                  BR_MIN_FORWARD_DELAY,
	                  BR_MAX_FORWARD_DELAY,
	                  NM_SETTING_BRIDGE_FORWARD_DELAY,
	                  error))
		return FALSE;

	if (!check_range (priv->hello_time,
	                  BR_MIN_HELLO_TIME,
	                  BR_MAX_HELLO_TIME,
	                  NM_SETTING_BRIDGE_HELLO_TIME,
	                  error))
		return FALSE;

	if (!check_range (priv->max_age,
	                  BR_MIN_MAX_AGE,
	                  BR_MAX_MAX_AGE,
	                  NM_SETTING_BRIDGE_MAX_AGE,
	                  error))
		return FALSE;

	if (!check_range (priv->ageing_time,
	                  BR_MIN_AGEING_TIME,
	                  BR_MAX_AGEING_TIME,
	                  NM_SETTING_BRIDGE_AGEING_TIME,
	                  error))
		return FALSE;

	return TRUE;
}
Пример #8
0
gboolean
ce_page_interface_name_valid (const char *iface, const char *property_name, GError **error)
{
	if (iface && *iface) {
		if (!nm_utils_iface_valid_name (iface)) {
			if (property_name) {
				g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
				             _("invalid interface-name for %s (%s)"),
				             property_name, iface);
			} else {
				g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
				             _("invalid interface-name (%s)"),
				             iface);
			}
			return FALSE;
		}
	}
	return TRUE;
}
Пример #9
0
char *
nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
                                        NMConnection *connection,
                                        const char *parent_iface,
                                        GError **error)
{
	NMDeviceFactoryInterface *klass;
	char *ifname;

	g_return_val_if_fail (factory != NULL, NULL);
	g_return_val_if_fail (connection != NULL, NULL);
	g_return_val_if_fail (!error || !*error, NULL);

	klass = NM_DEVICE_FACTORY_GET_INTERFACE (factory);

	if (klass->get_connection_iface)
		ifname = klass->get_connection_iface (factory, connection, parent_iface);
	else
		ifname = g_strdup (nm_connection_get_interface_name (connection));

	if (!ifname) {
		g_set_error (error,
		             NM_MANAGER_ERROR,
		             NM_MANAGER_ERROR_FAILED,
		             "failed to determine interface name: error determine name for %s",
		             nm_connection_get_connection_type (connection));
		return NULL;
	}

	if (!nm_utils_iface_valid_name (ifname)) {
		g_set_error (error,
		             NM_MANAGER_ERROR,
		             NM_MANAGER_ERROR_FAILED,
		             "failed to determine interface name: name \"%s\" is invalid",
		             ifname);
		g_free (ifname);
		return NULL;
	}

	return ifname;
}
Пример #10
0
static gboolean
validate (CEPage *page, NMConnection *connection, GError **error)
{
    CEPageVlan *self = CE_PAGE_VLAN (page);
    CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
    gboolean invalid = FALSE;
    GByteArray *ignore;
    int parent_id;
    const char *parent;
    char *parent_iface;

    parent_id = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->parent));
    if (parent_id == -1) {
        gboolean valid;

        parent = gtk_entry_get_text (priv->parent_entry);
        parent_iface = g_strndup (parent, strcspn (parent, " "));
        valid = nm_utils_iface_valid_name (parent_iface);
        g_free (parent_iface);
        if (!valid)
            return FALSE;
    }

    ignore = ce_page_entry_to_mac (priv->cloned_mac, ARPHRD_ETHER, &invalid);
    if (invalid)
        return FALSE;
    if (ignore)
        g_byte_array_free (ignore, TRUE);

    ui_to_setting (self);

    if (   priv->s_hw
            && !nm_setting_verify (priv->s_hw, NULL, error))
        return FALSE;

    return nm_setting_verify (NM_SETTING (priv->setting), NULL, error);
}
Пример #11
0
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingConnection *s_con;
	NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);
	guint32 normerr_max_mtu = 0;

	if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, INFINIBAND_ALEN)) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS);
		return FALSE;
	}

	if (!g_strcmp0 (priv->transport_mode, "datagram")) {
		if (priv->mtu > 2044)
			normerr_max_mtu = 2044;
	} else if (!g_strcmp0 (priv->transport_mode, "connected")) {
		if (priv->mtu > 65520)
			normerr_max_mtu = 65520;
	} else {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE);
		return FALSE;
	}

	if (priv->parent) {
		if (!nm_utils_iface_valid_name (priv->parent)) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("not a valid interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
		if (priv->p_key == -1) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("Must specify a P_Key if specifying parent"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
		}
	}

	if (priv->p_key != -1) {
		if (!priv->mac_address && !priv->parent) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_MISSING_PROPERTY,
			                     _("InfiniBand P_Key connection did not specify parent interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
	}

	s_con = nm_connection_get_setting_connection (connection);
	if (s_con) {
		const char *interface_name = nm_setting_connection_get_interface_name (s_con);

		if (!interface_name)
			;
		else if (!nm_utils_iface_valid_name (interface_name)) {
			/* report the error for NMSettingConnection:interface-name, because
			 * it's that property that is invalid -- although we currently verify()
			 * NMSettingInfiniband.
			 **/
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid interface name"),
			             interface_name);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
			return FALSE;
		} else {
			if (priv->p_key != -1) {
				if (!priv->virtual_iface_name)
					priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key);

				if (strcmp (interface_name, priv->virtual_iface_name) != 0) {
					/* We don't support renaming software infiniband devices. Later we might, but
					 * for now just reject such connections.
					 **/
					g_set_error (error,
					             NM_CONNECTION_ERROR,
					             NM_CONNECTION_ERROR_INVALID_PROPERTY,
					             _("interface name of software infiniband device must be '%s' or unset (instead it is '%s')"),
					             priv->virtual_iface_name, interface_name);
					g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
					return FALSE;
				}
			}
		}
	}

	/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */

	if (normerr_max_mtu > 0) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("mtu for transport mode '%s' can be at most %d but it is %d"),
		             priv->transport_mode, normerr_max_mtu, priv->mtu);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU);
		return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
	}

	return TRUE;
}
Пример #12
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;
}
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)
{
	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;
}
Пример #16
0
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingBondPrivate *priv = NM_SETTING_BOND_GET_PRIVATE (setting);
	GHashTableIter iter;
	const char *key, *value;
	int mode, miimon = 0, arp_interval = 0;
	int num_grat_arp = -1, num_unsol_na = -1;
	const char *mode_orig, *mode_new;
	const char *arp_ip_target = NULL;
	const char *lacp_rate;
	const char *primary;

	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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("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);
	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP);
	if (value)
		num_grat_arp = atoi (value);
	value = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
	if (value)
		num_unsol_na = atoi (value);

	/* Can only set one of miimon and arp_interval */
	if (miimon > 0 && arp_interval > 0) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("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);
		return FALSE;
	}

	/* Verify bond mode */
	mode_orig = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_MODE);
	if (!mode_orig) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("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;
	}
	mode = nm_utils_bond_mode_string_to_int (mode_orig);
	if (mode == -1) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%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;
	}
	mode_new = nm_utils_bond_mode_int_to_string (mode);

	/* Make sure mode is compatible with other settings */
	if (   strcmp (mode_new, "balance-alb") == 0
	    || strcmp (mode_new, "balance-tlb") == 0) {
		if (arp_interval > 0) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s=%s' is incompatible with '%s > 0'"),
			             NM_SETTING_BOND_OPTION_MODE, mode_new, 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 (mode_new, "active-backup") == 0) {
		if (primary && !nm_utils_iface_valid_name (primary)) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_connection_get_setting_infiniband (connection)) {
		if (strcmp (mode_new, "active-backup") != 0) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s=%s' is not a valid configuration for '%s'"),
			             NM_SETTING_BOND_OPTION_MODE, mode_new, 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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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_CONNECTION_ERROR,
				             NM_CONNECTION_ERROR_INVALID_PROPERTY,
				             _("'%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_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%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;
		}
	}

	lacp_rate = g_hash_table_lookup (priv->options, NM_SETTING_BOND_OPTION_LACP_RATE);
	if (   lacp_rate
	    && g_strcmp0 (mode_new, "802.3ad")
	    && strcmp (lacp_rate, "slow") != 0
	    && strcmp (lacp_rate, "0") != 0) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' option is only valid with mode '%s'"),
		             NM_SETTING_BOND_OPTION_LACP_RATE, "802.3ad");
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
		return FALSE;
	}

	if (   (num_grat_arp != -1 && num_unsol_na != -1)
	    && (num_grat_arp != num_unsol_na)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' and '%s' cannot have different values"),
		             NM_SETTING_BOND_OPTION_NUM_GRAT_ARP,
		             NM_SETTING_BOND_OPTION_NUM_UNSOL_NA);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
		return FALSE;
	}

	if (!_nm_connection_verify_required_interface_name (connection, error))
		return FALSE;

	/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */

	if (g_strcmp0 (mode_orig, mode_new) != 0) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("'%s' option should be string"),
		             NM_SETTING_BOND_OPTION_MODE);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
		return NM_SETTING_VERIFY_NORMALIZABLE;
	}

	return TRUE;
}
Пример #17
0
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;
}