libnm,all: merge branch 'th/libnm-interface-name-cleanup'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/416
This commit is contained in:
Thomas Haller 2020-02-26 17:52:22 +01:00
commit b9f6283c80
11 changed files with 183 additions and 199 deletions

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);
}
/**

View file

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

View file

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

View file

@ -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;
}
}
}

View file

@ -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);
}
/*****************************************************************************/

View file

@ -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,

View file

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

View file

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

View file

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