mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-06 04:28:29 +02:00
libnm,all: merge branch 'th/libnm-interface-name-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/416
This commit is contained in:
commit
b9f6283c80
11 changed files with 183 additions and 199 deletions
|
|
@ -368,13 +368,13 @@ nm_vpn_wireguard_import (const char *filename,
|
|||
memcpy (ifname, cstr, len);
|
||||
ifname[len] = '\0';
|
||||
|
||||
if (nm_utils_ifname_valid_kernel (ifname, NULL))
|
||||
if (nm_utils_ifname_valid (ifname, NMU_IFACE_KERNEL, NULL))
|
||||
ifname_valid = TRUE;
|
||||
}
|
||||
}
|
||||
if (!ifname_valid) {
|
||||
nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("The WireGuard config file must be a valid interface name followed by \".conf\""));
|
||||
_("The name of the WireGuard config must be a valid interface name followed by \".conf\""));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ gboolean _nm_connection_verify_required_interface_name (NMConnection *connect
|
|||
GError **error);
|
||||
|
||||
int _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
|
||||
const char *type,
|
||||
NMConnection *connection,
|
||||
gboolean normalize,
|
||||
gboolean *out_modified,
|
||||
const char **normalized_type,
|
||||
const char **out_normalized_type,
|
||||
GError **error);
|
||||
|
||||
#endif /* __NM_CONNECTION_PRIVATE_H__ */
|
||||
|
|
|
|||
|
|
@ -1236,6 +1236,7 @@ _normalize_ovs_interface_type (NMConnection *self)
|
|||
return FALSE;
|
||||
|
||||
v = _nm_setting_ovs_interface_verify_interface_type (s_ovs_interface,
|
||||
nm_setting_ovs_interface_get_interface_type (s_ovs_interface),
|
||||
self,
|
||||
TRUE,
|
||||
&modified,
|
||||
|
|
@ -1404,24 +1405,19 @@ nm_connection_verify (NMConnection *connection, GError **error)
|
|||
NMSettingVerifyResult
|
||||
_nm_connection_verify (NMConnection *connection, GError **error)
|
||||
{
|
||||
NMConnectionPrivate *priv;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIPConfig *s_ip4, *s_ip6;
|
||||
NMSettingProxy *s_proxy;
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
GSList *all_settings = NULL, *setting_i;
|
||||
gs_free NMSetting **settings = NULL;
|
||||
gs_free_error GError *normalizable_error = NULL;
|
||||
NMSettingVerifyResult normalizable_error_type = NM_SETTING_VERIFY_SUCCESS;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_SETTING_VERIFY_ERROR);
|
||||
g_return_val_if_fail (!error || !*error, NM_SETTING_VERIFY_ERROR);
|
||||
|
||||
priv = NM_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
/* First, make sure there's at least 'connection' setting */
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
if (!s_con) {
|
||||
settings = nm_connection_get_settings (connection, NULL);
|
||||
if ( !settings
|
||||
|| !NM_IS_SETTING_CONNECTION (settings[0])) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_MISSING_SETTING,
|
||||
|
|
@ -1430,25 +1426,13 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
|||
return NM_SETTING_VERIFY_ERROR;
|
||||
}
|
||||
|
||||
/* Build up the list of settings */
|
||||
g_hash_table_iter_init (&iter, priv->settings);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||
/* Order NMSettingConnection so that it will be verified first.
|
||||
* The reason is, that errors in this setting might be more fundamental
|
||||
* and should be checked and reported with higher priority.
|
||||
*/
|
||||
if (value == s_con)
|
||||
all_settings = g_slist_append (all_settings, value);
|
||||
else
|
||||
all_settings = g_slist_prepend (all_settings, value);
|
||||
}
|
||||
all_settings = g_slist_reverse (all_settings);
|
||||
|
||||
/* Now, run the verify function of each setting */
|
||||
for (setting_i = all_settings; setting_i; setting_i = setting_i->next) {
|
||||
for (i = 0; settings[i]; i++) {
|
||||
GError *verify_error = NULL;
|
||||
NMSettingVerifyResult verify_result;
|
||||
|
||||
nm_assert (NM_IS_SETTING (settings[i]));
|
||||
nm_assert (NM_IS_SETTING_CONNECTION (settings[i]) == (i == 0));
|
||||
|
||||
/* verify all settings. We stop if we find the first non-normalizable
|
||||
* @NM_SETTING_VERIFY_ERROR. If we find normalizable errors we continue
|
||||
* but remember the error to return it to the user.
|
||||
|
|
@ -1456,7 +1440,7 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
|||
* @NM_SETTING_VERIFY_NORMALIZABLE, so, if we encounter such an error type,
|
||||
* we remember it instead (to return it as output).
|
||||
**/
|
||||
verify_result = _nm_setting_verify (NM_SETTING (setting_i->data), connection, &verify_error);
|
||||
verify_result = _nm_setting_verify (settings[i], connection, &verify_error);
|
||||
if (verify_result == NM_SETTING_VERIFY_NORMALIZABLE ||
|
||||
verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR) {
|
||||
if ( verify_result == NM_SETTING_VERIFY_NORMALIZABLE_ERROR
|
||||
|
|
@ -1471,13 +1455,11 @@ _nm_connection_verify (NMConnection *connection, GError **error)
|
|||
}
|
||||
} else if (verify_result != NM_SETTING_VERIFY_SUCCESS) {
|
||||
g_propagate_error (error, verify_error);
|
||||
g_slist_free (all_settings);
|
||||
g_return_val_if_fail (verify_result == NM_SETTING_VERIFY_ERROR, NM_SETTING_VERIFY_ERROR);
|
||||
return NM_SETTING_VERIFY_ERROR;
|
||||
}
|
||||
g_clear_error (&verify_error);
|
||||
}
|
||||
g_slist_free (all_settings);
|
||||
|
||||
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
||||
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||
|
|
@ -2316,16 +2298,21 @@ nm_connection_is_type (NMConnection *connection, const char *type)
|
|||
}
|
||||
|
||||
static int
|
||||
_for_each_sort (NMSetting **p_a, NMSetting **p_b, void *unused)
|
||||
_get_settings_sort (gconstpointer p_a, gconstpointer p_b, gpointer unused)
|
||||
{
|
||||
NMSetting *a = *p_a;
|
||||
NMSetting *b = *p_b;
|
||||
int c;
|
||||
NMSetting *a = *((NMSetting **) p_a);
|
||||
NMSetting *b = *((NMSetting **) p_b);
|
||||
|
||||
c = _nm_setting_compare_priority (a, b);
|
||||
if (c != 0)
|
||||
return c;
|
||||
return strcmp (nm_setting_get_name (a), nm_setting_get_name (b));
|
||||
nm_assert (NM_IS_SETTING (a));
|
||||
nm_assert (NM_IS_SETTING (b));
|
||||
nm_assert (a != b);
|
||||
nm_assert (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b));
|
||||
|
||||
NM_CMP_RETURN (_nm_setting_compare_priority (a, b));
|
||||
NM_CMP_DIRECT_STRCMP (nm_setting_get_name (a), nm_setting_get_name (b));
|
||||
|
||||
nm_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2348,38 +2335,12 @@ NMSetting **
|
|||
nm_connection_get_settings (NMConnection *connection,
|
||||
guint *out_length)
|
||||
{
|
||||
NMConnectionPrivate *priv;
|
||||
NMSetting **arr;
|
||||
GHashTableIter iter;
|
||||
NMSetting *setting;
|
||||
guint i, size;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
|
||||
priv = NM_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
size = g_hash_table_size (priv->settings);
|
||||
|
||||
if (!size) {
|
||||
NM_SET_OUT (out_length, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arr = g_new (NMSetting *, size + 1);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->settings);
|
||||
for (i = 0; g_hash_table_iter_next (&iter, NULL, (gpointer *) &setting); i++)
|
||||
arr[i] = setting;
|
||||
nm_assert (i == size);
|
||||
arr[size] = NULL;
|
||||
|
||||
/* sort the settings. This has an effect on the order in which keyfile
|
||||
* prints them. */
|
||||
if (size > 1)
|
||||
g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
|
||||
|
||||
NM_SET_OUT (out_length, size);
|
||||
return arr;
|
||||
return (NMSetting **) nm_utils_hash_values_to_array (NM_CONNECTION_GET_PRIVATE (connection)->settings,
|
||||
_get_settings_sort,
|
||||
NULL,
|
||||
out_length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -328,9 +328,6 @@ validate_ip (const char *name, const char *value)
|
|||
static gboolean
|
||||
validate_ifname (const char *name, const char *value)
|
||||
{
|
||||
if (!value || !value[0])
|
||||
return FALSE;
|
||||
|
||||
return nm_utils_ifname_valid_kernel (value, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1032,22 +1032,50 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
|
||||
if (priv->interface_name) {
|
||||
GError *tmp_error = NULL;
|
||||
gboolean valid_ifname = FALSE;
|
||||
NMUtilsIfaceType iface_type;
|
||||
|
||||
/* do not perform a interface name length check for OVS connection types
|
||||
* as they don't have a corresponding kernel link that enforces the 15 bytes limit.
|
||||
* Here we're whitelisting the OVS interface type as well, even if most OVS
|
||||
* iface types do have the limit, to let the OVS specific nm-setting verify whether the iface name
|
||||
* is good or not according to the internal type (internal, patch, ...) */
|
||||
if (NM_IN_STRSET (type,
|
||||
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_OVS_PORT_SETTING_NAME,
|
||||
NM_SETTING_OVS_INTERFACE_SETTING_NAME))
|
||||
valid_ifname = nm_utils_ifname_valid (priv->interface_name, NMU_IFACE_OVS, &tmp_error);
|
||||
else
|
||||
valid_ifname = nm_utils_ifname_valid (priv->interface_name, NMU_IFACE_KERNEL, &tmp_error);
|
||||
NM_SETTING_OVS_PORT_SETTING_NAME))
|
||||
iface_type = NMU_IFACE_OVS;
|
||||
else if (nm_streq (type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
|
||||
NMSettingOvsInterface *s_ovs_iface = NULL;
|
||||
const char *ovs_iface_type;
|
||||
|
||||
if (!valid_ifname) {
|
||||
if (connection)
|
||||
s_ovs_iface = nm_connection_get_setting_ovs_interface (connection);
|
||||
_nm_setting_ovs_interface_verify_interface_type (s_ovs_iface,
|
||||
s_ovs_iface ? nm_setting_ovs_interface_get_interface_type (s_ovs_iface) : NULL,
|
||||
connection,
|
||||
FALSE,
|
||||
NULL,
|
||||
&ovs_iface_type,
|
||||
NULL);
|
||||
if (!ovs_iface_type) {
|
||||
/* We cannot determine to OVS interface type. Consequently, we cannot
|
||||
* fully validate the interface name.
|
||||
*
|
||||
* If we have a connection (and we do a full validation anyway), skip the
|
||||
* check. The connection will fail validation when we validate the OVS setting.
|
||||
*
|
||||
* Otherwise, do the most basic validation.
|
||||
*/
|
||||
if (connection)
|
||||
goto after_interface_name;
|
||||
iface_type = NMU_IFACE_ANY;
|
||||
} else if (NM_IN_STRSET (ovs_iface_type, "patch")) {
|
||||
/* this interface type is internal to OVS. */
|
||||
iface_type = NMU_IFACE_OVS;
|
||||
} else {
|
||||
/* This interface type also requires a netdev. We need to validate
|
||||
* for both OVS and KERNEL. */
|
||||
nm_assert (NM_IN_STRSET (ovs_iface_type, "internal", "system", "dpdk"));
|
||||
iface_type = NMU_IFACE_OVS_AND_KERNEL;
|
||||
}
|
||||
} else
|
||||
iface_type = NMU_IFACE_KERNEL;
|
||||
|
||||
if (!nm_utils_ifname_valid (priv->interface_name, iface_type, &tmp_error)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -1057,6 +1085,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
after_interface_name:
|
||||
|
||||
is_slave = FALSE;
|
||||
slave_setting_type = NULL;
|
||||
|
|
@ -1251,11 +1280,14 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
}
|
||||
|
||||
static const char *
|
||||
find_virtual_interface_name (GVariant *connection_dict)
|
||||
find_virtual_interface_name (GVariant *connection_dict,
|
||||
GVariant **variant_to_free)
|
||||
{
|
||||
GVariant *setting_dict;
|
||||
const char *interface_name;
|
||||
|
||||
nm_assert (variant_to_free && !*variant_to_free);
|
||||
|
||||
setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BOND_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
|
||||
if (!setting_dict)
|
||||
setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BRIDGE_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
|
||||
|
|
@ -1267,39 +1299,15 @@ find_virtual_interface_name (GVariant *connection_dict)
|
|||
if (!setting_dict)
|
||||
return NULL;
|
||||
|
||||
*variant_to_free = setting_dict;
|
||||
|
||||
/* All of the deprecated virtual interface name properties were named "interface-name". */
|
||||
if (!g_variant_lookup (setting_dict, "interface-name", "&s", &interface_name))
|
||||
interface_name = NULL;
|
||||
|
||||
g_variant_unref (setting_dict);
|
||||
return interface_name;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_setting_connection_set_interface_name (NMSetting *setting,
|
||||
GVariant *connection_dict,
|
||||
const char *property,
|
||||
GVariant *value,
|
||||
NMSettingParseFlags parse_flags,
|
||||
GError **error)
|
||||
{
|
||||
const char *interface_name;
|
||||
|
||||
/* For compatibility reasons, if there is an invalid virtual interface name,
|
||||
* we need to make verification fail, even if that virtual name would be
|
||||
* overridden by a valid connection.interface-name.
|
||||
*/
|
||||
interface_name = find_virtual_interface_name (connection_dict);
|
||||
if (!interface_name || nm_utils_ifname_valid_kernel (interface_name, NULL))
|
||||
interface_name = g_variant_get_string (value, NULL);
|
||||
|
||||
g_object_set (G_OBJECT (setting),
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name,
|
||||
NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_setting_connection_no_interface_name (NMSetting *setting,
|
||||
GVariant *connection_dict,
|
||||
|
|
@ -1308,8 +1316,9 @@ nm_setting_connection_no_interface_name (NMSetting *setting,
|
|||
GError **error)
|
||||
{
|
||||
const char *virtual_interface_name;
|
||||
gs_unref_variant GVariant *variant_to_free = NULL;
|
||||
|
||||
virtual_interface_name = find_virtual_interface_name (connection_dict);
|
||||
virtual_interface_name = find_virtual_interface_name (connection_dict, &variant_to_free);
|
||||
g_object_set (G_OBJECT (setting),
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME, virtual_interface_name,
|
||||
NULL);
|
||||
|
|
@ -1759,7 +1768,6 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass)
|
|||
obj_properties[PROP_INTERFACE_NAME],
|
||||
NM_SETT_INFO_PROPERT_TYPE (
|
||||
.dbus_type = G_VARIANT_TYPE_STRING,
|
||||
.from_dbus_fcn = nm_setting_connection_set_interface_name,
|
||||
.missing_from_dbus_fcn = nm_setting_connection_no_interface_name,
|
||||
));
|
||||
|
||||
|
|
|
|||
|
|
@ -211,39 +211,23 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
s_con = nm_connection_get_setting_connection (connection);
|
||||
if (s_con) {
|
||||
const char *interface_name = nm_setting_connection_get_interface_name (s_con);
|
||||
GError *tmp_error = NULL;
|
||||
|
||||
if (!interface_name)
|
||||
;
|
||||
else if (!nm_utils_ifname_valid_kernel (interface_name, &tmp_error)) {
|
||||
/* 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': %s", interface_name, tmp_error->message);
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
|
||||
g_error_free (tmp_error);
|
||||
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 ( interface_name
|
||||
&& 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,30 +64,29 @@ nm_setting_ovs_interface_get_interface_type (NMSettingOvsInterface *self)
|
|||
|
||||
int
|
||||
_nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
|
||||
const char *type,
|
||||
NMConnection *connection,
|
||||
gboolean normalize,
|
||||
gboolean *out_modified,
|
||||
const char **normalized_type,
|
||||
const char **out_normalized_type,
|
||||
GError **error)
|
||||
{
|
||||
const char *type;
|
||||
const char *type_from_setting = NULL;
|
||||
const char *type_setting = NULL;
|
||||
const char *connection_type;
|
||||
gboolean is_ovs_connection_type;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_OVS_INTERFACE (self), FALSE);
|
||||
if (normalize) {
|
||||
g_return_val_if_fail (NM_IS_SETTING_OVS_INTERFACE (self), FALSE);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
||||
nm_assert (self == nm_connection_get_setting_ovs_interface (connection));
|
||||
} else
|
||||
} else {
|
||||
g_return_val_if_fail (!self || NM_IS_SETTING_OVS_INTERFACE (self), FALSE);
|
||||
g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), FALSE);
|
||||
|
||||
g_return_val_if_fail (!normalized_type || !(*normalized_type), FALSE);
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_modified, FALSE);
|
||||
|
||||
type = self->type;
|
||||
NM_SET_OUT (out_normalized_type, NULL);
|
||||
|
||||
if ( type
|
||||
&& !NM_IN_STRSET (type, "internal", "system", "patch", "dpdk")) {
|
||||
|
|
@ -100,8 +99,10 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!connection)
|
||||
if (!connection) {
|
||||
NM_SET_OUT (out_normalized_type, type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
connection_type = nm_connection_get_connection_type (connection);
|
||||
if (!connection_type) {
|
||||
|
|
@ -192,6 +193,7 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
|
|||
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
|
||||
return FALSE;
|
||||
}
|
||||
NM_SET_OUT (out_normalized_type, type);
|
||||
return TRUE;
|
||||
}
|
||||
type = type_from_setting;
|
||||
|
|
@ -208,16 +210,17 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
|
|||
}
|
||||
}
|
||||
|
||||
if (type)
|
||||
if (type) {
|
||||
NM_SET_OUT (out_normalized_type, type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (is_ovs_connection_type)
|
||||
type = "internal";
|
||||
else
|
||||
type = "system";
|
||||
|
||||
if (normalized_type)
|
||||
*normalized_type = type;
|
||||
NM_SET_OUT (out_normalized_type, type);
|
||||
|
||||
normalize:
|
||||
if (!normalize) {
|
||||
|
|
@ -254,8 +257,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
{
|
||||
NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE (setting);
|
||||
NMSettingConnection *s_con = NULL;
|
||||
const char *normalized_type = NULL;
|
||||
int result = NM_SETTING_VERIFY_ERROR;
|
||||
|
||||
if (connection) {
|
||||
const char *slave_type;
|
||||
|
|
@ -295,39 +296,13 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
}
|
||||
}
|
||||
|
||||
result = _nm_setting_ovs_interface_verify_interface_type (self,
|
||||
connection,
|
||||
FALSE,
|
||||
NULL,
|
||||
&normalized_type,
|
||||
error);
|
||||
|
||||
/* From 'man ovs-vswitchd.conf.db': OVS patch interfaces do not have
|
||||
* a limit on interface name length, all the other types do */
|
||||
if (result != NM_SETTING_VERIFY_ERROR && s_con) {
|
||||
gs_free_error GError *ifname_error = NULL;
|
||||
const char *ifname = nm_setting_connection_get_interface_name (s_con);
|
||||
|
||||
normalized_type = self->type ? self->type : normalized_type;
|
||||
|
||||
if ( ifname
|
||||
&& !nm_streq0 (normalized_type, "patch")
|
||||
&& !nm_utils_ifname_valid (ifname,
|
||||
NMU_IFACE_KERNEL,
|
||||
&ifname_error)) {
|
||||
g_clear_error (error);
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
"'%s': %s", ifname, ifname_error->message);
|
||||
g_prefix_error (error, "%s.%s: ",
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME);
|
||||
return NM_SETTING_VERIFY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return _nm_setting_ovs_interface_verify_interface_type (self,
|
||||
self->type,
|
||||
connection,
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -4647,7 +4647,7 @@ test_connection_normalize_virtual_iface_name (void)
|
|||
g_variant_unref (setting_dict);
|
||||
g_variant_unref (var);
|
||||
|
||||
/* If vlan.interface-name is invalid, deserialization will fail. */
|
||||
/* If vlan.interface-name will be ignored. */
|
||||
NMTST_VARIANT_EDITOR (connection_dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_VLAN_SETTING_NAME,
|
||||
"interface-name",
|
||||
|
|
@ -4656,8 +4656,9 @@ test_connection_normalize_virtual_iface_name (void)
|
|||
);
|
||||
|
||||
con = _connection_new_from_dbus (connection_dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_clear_error (&error);
|
||||
nmtst_assert_success (con, error);
|
||||
g_assert_cmpstr (nm_connection_get_interface_name (con), ==, IFACE_NAME);
|
||||
g_clear_object (&con);
|
||||
|
||||
/* If vlan.interface-name is valid, but doesn't match, it will be ignored. */
|
||||
NMTST_VARIANT_EDITOR (connection_dict,
|
||||
|
|
|
|||
|
|
@ -4126,8 +4126,47 @@ nm_utils_ifname_valid_kernel (const char *name, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_nm_utils_ifname_valid_ovs (const char* name, GError **error)
|
||||
_nm_utils_ifname_valid_kernel (const char *name, GError **error)
|
||||
{
|
||||
if (!nm_utils_ifname_valid_kernel (name, error))
|
||||
return FALSE;
|
||||
|
||||
if (strchr (name, '%')) {
|
||||
/* Kernel's dev_valid_name() accepts (almost) any binary up to 15 chars.
|
||||
* However, '%' is treated special as a format specifier. Try
|
||||
*
|
||||
* ip link add 'dummy%dx' type dummy
|
||||
*
|
||||
* Don't allow that for "connection.interface-name", which either
|
||||
* matches an existing netdev name (thus, it cannot have a '%') or
|
||||
* is used to configure a name (in which case we don't want kernel
|
||||
* to replace the format specifier). */
|
||||
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("'%%' is not allowed in interface names"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NM_IN_STRSET (name, "all",
|
||||
"default",
|
||||
"bonding_masters")) {
|
||||
/* Certain names are not allowed. The "all" and "default" names are reserved
|
||||
* due to their directories in "/proc/sys/net/ipv4/conf/" and "/proc/sys/net/ipv6/conf/".
|
||||
*
|
||||
* Also, there is "/sys/class/net/bonding_masters" file.
|
||||
*/
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN,
|
||||
_("'%s' is not allowed as interface name"), name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_nm_utils_ifname_valid_ovs (const char *name, GError **error)
|
||||
{
|
||||
const char *ch;
|
||||
|
||||
|
|
@ -4169,9 +4208,23 @@ nm_utils_ifname_valid (const char* name,
|
|||
|
||||
switch (type) {
|
||||
case NMU_IFACE_KERNEL:
|
||||
return nm_utils_ifname_valid_kernel (name, error);
|
||||
return _nm_utils_ifname_valid_kernel (name, error);
|
||||
case NMU_IFACE_OVS:
|
||||
return _nm_utils_ifname_valid_ovs (name, error);
|
||||
case NMU_IFACE_OVS_AND_KERNEL:
|
||||
return _nm_utils_ifname_valid_kernel (name, error)
|
||||
&& _nm_utils_ifname_valid_ovs (name, error);
|
||||
case NMU_IFACE_ANY: {
|
||||
gs_free_error GError *local = NULL;
|
||||
|
||||
if (_nm_utils_ifname_valid_kernel (name, error ? &local : NULL))
|
||||
return TRUE;
|
||||
if (_nm_utils_ifname_valid_ovs (name, NULL))
|
||||
return TRUE;
|
||||
if (error)
|
||||
g_propagate_error (error, g_steal_pointer (&local));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
|
|
|||
|
|
@ -1678,8 +1678,10 @@ nm_utils_strdup_reset (char **dst, const char *src)
|
|||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
NMU_IFACE_KERNEL = 0,
|
||||
NMU_IFACE_ANY,
|
||||
NMU_IFACE_KERNEL,
|
||||
NMU_IFACE_OVS,
|
||||
NMU_IFACE_OVS_AND_KERNEL,
|
||||
} NMUtilsIfaceType;
|
||||
|
||||
gboolean nm_utils_ifname_valid_kernel (const char *name, GError **error);
|
||||
|
|
|
|||
|
|
@ -399,7 +399,9 @@ make_connection_setting (const char *file,
|
|||
if (v) {
|
||||
GError *error = NULL;
|
||||
|
||||
if (nm_utils_ifname_valid_kernel (v, &error)) {
|
||||
/* Only validate for NMU_IFACE_KERNEL, because ifcfg plugin anyway
|
||||
* doesn't support OVS types. */
|
||||
if (nm_utils_ifname_valid (v, NMU_IFACE_KERNEL, &error)) {
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME, v,
|
||||
NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue