Merge branch 'ac/ovs_ifname_length' into 'master'

[ac/ovs ifname length]

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/408

(cherry picked from commit 63eabe0dbf)
This commit is contained in:
Antonio Cardace 2020-02-17 17:34:49 +01:00
commit 4200d0a85b
27 changed files with 420 additions and 134 deletions

View file

@ -4252,18 +4252,10 @@ set_connection_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, co
static gboolean
set_connection_iface (NmCli *nmc, NMConnection *con, const OptionInfo *option, const char *value, GError **error)
{
GError *tmp_error = NULL;
if (value) {
/* Special value of '*' means no specific interface name */
if (strcmp (value, "*") == 0)
value = NULL;
else if (!nm_utils_is_valid_iface_name (value, &tmp_error)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: '%s': %s"), value, tmp_error->message);
g_error_free (tmp_error);
return FALSE;
}
}
return set_property (nmc->client,

View file

@ -2089,8 +2089,6 @@ _set_fcn_gobject_ifname (ARGS_SET_FCN)
if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
return _gobject_property_reset_default (setting, property_info->property_name);
if (!nm_utils_is_valid_iface_name (value, error))
return FALSE;
g_object_set (setting, property_info->property_name, value, NULL);
return TRUE;
}
@ -2567,24 +2565,6 @@ _multilist_remove_by_value_fcn_connection_permissions (NMSetting *setting,
return TRUE;
}
static gboolean
_set_fcn_connection_master (ARGS_SET_FCN)
{
if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
value = NULL;
else if (!*value)
value = NULL;
else if ( !nm_utils_is_valid_iface_name (value, NULL)
&& !nm_utils_is_uuid (value)) {
g_set_error (error, 1, 0,
_("'%s' is not valid master; use ifname or connection UUID"),
value);
return FALSE;
}
g_object_set (setting, property_info->property_name, value, NULL);
return TRUE;
}
static const char *const*
_complete_fcn_connection_master (ARGS_COMPLETE_FCN)
{
@ -5129,7 +5109,7 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
.prompt = NM_META_TEXT_PROMPT_MASTER,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
.set_fcn = _set_fcn_connection_master,
.set_fcn = _set_fcn_gobject_string,
.complete_fcn = _complete_fcn_connection_master,
),
),

View file

@ -368,7 +368,7 @@ nm_vpn_wireguard_import (const char *filename,
memcpy (ifname, cstr, len);
ifname[len] = '\0';
if (nm_utils_is_valid_iface_name (ifname, NULL))
if (nm_utils_ifname_valid_kernel (ifname, NULL))
ifname_valid = TRUE;
}
}

View file

@ -103,7 +103,7 @@ device_entry_parse (NmtDeviceEntry *deventry,
return TRUE;
if (priv->hardware_type == G_TYPE_NONE && !priv->device_filter) {
if (nm_utils_is_valid_iface_name (text, NULL)) {
if (nm_utils_ifname_valid_kernel (text, NULL)) {
*interface_name = g_strdup (text);
return TRUE;
} else
@ -127,12 +127,12 @@ device_entry_parse (NmtDeviceEntry *deventry,
len = nm_utils_hwaddr_len (priv->arptype);
if ( nm_utils_hwaddr_aton (words[0], buf, len)
&& (!words[1] || nm_utils_is_valid_iface_name (words[1], NULL))) {
&& (!words[1] || nm_utils_ifname_valid_kernel (words[1], NULL))) {
*mac_address = words[0];
*interface_name = NULL;
g_free (words);
return TRUE;
} else if ( nm_utils_is_valid_iface_name (words[0], NULL)
} else if ( nm_utils_ifname_valid_kernel (words[0], NULL)
&& (!words[1] || nm_utils_hwaddr_aton (words[1], buf, len))) {
*interface_name = words[0];
*mac_address = NULL;

View file

@ -27,6 +27,7 @@ int _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
const char **normalized_type,
GError **error);
#endif /* __NM_CONNECTION_PRIVATE_H__ */

View file

@ -1235,6 +1235,7 @@ _normalize_ovs_interface_type (NMConnection *self)
self,
TRUE,
&modified,
NULL,
NULL);
if (v != TRUE)
g_return_val_if_reached (modified);

View file

@ -225,7 +225,7 @@ validate_ifname (const char *name, const char *value)
if (!value || !value[0])
return FALSE;
return nm_utils_is_valid_iface_name (value, NULL);
return nm_utils_ifname_valid_kernel (value, NULL);
}
/**
@ -611,7 +611,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
if (strcmp (mode_new, "active-backup") == 0) {
GError *tmp_error = NULL;
if (primary && !nm_utils_is_valid_iface_name (primary, &tmp_error)) {
if (primary && !nm_utils_ifname_valid_kernel (primary, &tmp_error)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,

View file

@ -973,20 +973,6 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if (priv->interface_name) {
GError *tmp_error = NULL;
if (!nm_utils_is_valid_iface_name (priv->interface_name, &tmp_error)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
"'%s': %s", priv->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;
}
}
type = priv->type;
if (!type) {
if ( !connection
@ -1044,6 +1030,34 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (priv->interface_name) {
GError *tmp_error = NULL;
gboolean valid_ifname = FALSE;
/* 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);
if (!valid_ifname) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
"'%s': %s", priv->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;
}
}
is_slave = FALSE;
slave_setting_type = NULL;
slave_type = priv->slave_type;
@ -1276,7 +1290,7 @@ nm_setting_connection_set_interface_name (NMSetting *setting,
* overridden by a valid connection.interface-name.
*/
interface_name = find_virtual_interface_name (connection_dict);
if (!interface_name || nm_utils_is_valid_iface_name (interface_name, NULL))
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),

View file

@ -177,7 +177,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
if (priv->parent) {
GError *tmp_error = NULL;
if (!nm_utils_is_valid_iface_name (priv->parent, &tmp_error)) {
if (!nm_utils_ifname_valid_kernel (priv->parent, &tmp_error)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -214,7 +214,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
if (!interface_name)
;
else if (!nm_utils_is_valid_iface_name (interface_name, &tmp_error)) {
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.

View file

@ -4921,7 +4921,7 @@ verify_label (const char *label)
if (!p)
return FALSE;
iface = g_strndup (label, p - label);
if (!nm_utils_is_valid_iface_name (iface, NULL)) {
if (!nm_utils_ifname_valid_kernel (iface, NULL)) {
g_free (iface);
return FALSE;
}

View file

@ -329,7 +329,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if ( priv->parent
&& !nm_utils_is_valid_iface_name (priv->parent, NULL)
&& !nm_utils_ifname_valid_kernel (priv->parent, NULL)
&& !nm_utils_is_uuid (priv->parent)) {
g_set_error (error,
NM_CONNECTION_ERROR,

View file

@ -120,7 +120,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
if (priv->parent) {
if ( !nm_utils_is_uuid (priv->parent)
&& !nm_utils_is_valid_iface_name (priv->parent, NULL)) {
&& !nm_utils_ifname_valid_kernel (priv->parent, NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,

View file

@ -67,6 +67,7 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
const char **normalized_type,
GError **error)
{
const char *type;
@ -82,9 +83,11 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
} else
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 ? self->type : NULL;
type = self->type;
if ( type
&& !NM_IN_STRSET (type, "internal", "system", "patch", "dpdk")) {
@ -212,6 +215,10 @@ _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
type = "internal";
else
type = "system";
if (normalized_type)
*normalized_type = type;
normalize:
if (!normalize) {
if (!self) {
@ -246,9 +253,11 @@ static int
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) {
NMSettingConnection *s_con;
const char *slave_type;
s_con = nm_connection_get_setting_connection (connection);
@ -286,11 +295,39 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
return _nm_setting_ovs_interface_verify_interface_type (self,
connection,
FALSE,
NULL,
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;
}
/*****************************************************************************/

View file

@ -149,7 +149,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if ( priv->parent
&& !nm_utils_is_valid_iface_name (priv->parent, &local_error)) {
&& !nm_utils_ifname_valid_kernel (priv->parent, &local_error)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,

View file

@ -603,7 +603,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
}
} else if (!nm_utils_is_valid_iface_name (priv->parent, NULL)) {
} else if (!nm_utils_ifname_valid_kernel (priv->parent, NULL)) {
/* parent must be either a UUID or an interface name */
g_set_error (error,
NM_CONNECTION_ERROR,

View file

@ -358,7 +358,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if ( priv->parent
&& !nm_utils_is_valid_iface_name (priv->parent, NULL)
&& !nm_utils_ifname_valid_kernel (priv->parent, NULL)
&& !nm_utils_is_uuid (priv->parent)) {
g_set_error (error,
NM_CONNECTION_ERROR,

View file

@ -14,7 +14,6 @@
#include <libintl.h>
#include <gmodule.h>
#include <sys/stat.h>
#include <net/if.h>
#include <linux/pkt_sched.h>
#if WITH_JSON_VALIDATION
@ -4697,7 +4696,7 @@ nm_utils_is_valid_iface_name_utf8safe (const char *utf8safe_name)
}
}
return nm_utils_is_valid_iface_name (bin, NULL);
return nm_utils_ifname_valid_kernel (bin, NULL);
}
/**
@ -4718,45 +4717,9 @@ nm_utils_is_valid_iface_name_utf8safe (const char *utf8safe_name)
gboolean
nm_utils_is_valid_iface_name (const char *name, GError **error)
{
int i;
g_return_val_if_fail (!error || !*error, FALSE);
if (!name) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is missing"));
return FALSE;
}
if (name[0] == '\0') {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is too short"));
return FALSE;
}
if ( name[0] == '.'
&& ( name[1] == '\0'
|| ( name[1] == '.'
&& name[2] == '\0'))) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is reserved"));
return FALSE;
}
for (i = 0; i < IFNAMSIZ; i++) {
char ch = name[i];
if (ch == '\0')
return TRUE;
if ( NM_IN_SET (ch, '/', ':')
|| g_ascii_isspace (ch)) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name contains an invalid character"));
return FALSE;
}
}
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is longer than 15 characters"));
return FALSE;
return nm_utils_ifname_valid_kernel (name, error);
}
/**

View file

@ -8319,6 +8319,203 @@ test_integrate_maincontext (gconstpointer test_data)
}
}
static void
test_connection_ovs_ifname (gconstpointer test_data)
{
const guint TEST_CASE = GPOINTER_TO_UINT (test_data);
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con = NULL;
NMSettingOvsBridge *s_ovs_bridge = NULL;
NMSettingOvsPort *s_ovs_port = NULL;
NMSettingOvsInterface *s_ovs_iface = NULL;
NMSettingOvsPatch *s_ovs_patch = NULL;
const char *ovs_iface_type = NULL;
switch (TEST_CASE) {
case 1:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_bridge",
NULL,
NM_SETTING_OVS_BRIDGE_SETTING_NAME, &s_con);
s_ovs_bridge = nm_connection_get_setting_ovs_bridge (con);
g_assert (s_ovs_bridge);
break;
case 2:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_port",
NULL,
NM_SETTING_OVS_PORT_SETTING_NAME, &s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER,
"master0",
NM_SETTING_CONNECTION_SLAVE_TYPE,
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
NULL);
s_ovs_port = nm_connection_get_setting_ovs_port (con);
g_assert (s_ovs_port);
break;
case 3:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_interface_patch",
NULL,
NM_SETTING_OVS_INTERFACE_SETTING_NAME, &s_con);
s_ovs_iface = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_iface);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER,
"master0",
NM_SETTING_CONNECTION_SLAVE_TYPE,
NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_iface,
NM_SETTING_OVS_INTERFACE_TYPE,
"patch",
NULL);
s_ovs_patch = NM_SETTING_OVS_PATCH (nm_setting_ovs_patch_new());
g_assert (s_ovs_patch);
g_object_set (s_ovs_patch,
NM_SETTING_OVS_PATCH_PEER, "1.2.3.4",
NULL);
nm_connection_add_setting (con, NM_SETTING (s_ovs_patch));
s_ovs_patch = nm_connection_get_setting_ovs_patch (con);
g_assert (s_ovs_patch);
ovs_iface_type = "patch";
break;
case 4:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_interface_internal",
NULL,
NM_SETTING_OVS_INTERFACE_SETTING_NAME, &s_con);
s_ovs_iface = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_iface);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER,
"master0",
NM_SETTING_CONNECTION_SLAVE_TYPE,
NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_iface,
NM_SETTING_OVS_INTERFACE_TYPE,
"internal",
NULL);
ovs_iface_type = "internal";
break;
case 5:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_interface_system",
NULL,
NM_SETTING_WIRED_SETTING_NAME, &s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER,
"master0",
NM_SETTING_CONNECTION_SLAVE_TYPE,
NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_iface = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new());
g_assert (s_ovs_iface);
g_object_set (s_ovs_iface,
NM_SETTING_OVS_INTERFACE_TYPE,
"system",
NULL);
nm_connection_add_setting (con, NM_SETTING (s_ovs_iface));
s_ovs_iface = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_iface);
ovs_iface_type = "system";
break;
case 6:
con = nmtst_create_minimal_connection ("test_connection_ovs_ifname_interface_dpdk",
NULL,
NM_SETTING_OVS_INTERFACE_SETTING_NAME, &s_con);
s_ovs_iface = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_iface);
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER,
"master0",
NM_SETTING_CONNECTION_SLAVE_TYPE,
NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_iface,
NM_SETTING_OVS_INTERFACE_TYPE,
"dpdk",
NULL);
ovs_iface_type = "dpdk";
break;
}
if (!nm_streq0 (ovs_iface_type, "system")) {
/* wrong: contains backward slash */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs\\0",
NULL);
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
/* wrong: contains forward slash */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs/0",
NULL);
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
/* wrong: contains non-alphanumerical char */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs-0",
NULL);
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs@0",
NULL);
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
}
/* wrong: contains space */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs 0",
NULL);
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
/* good */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs0",
NULL);
nmtst_assert_connection_verifies (con);
/* good if bridge, port, or patch interface */
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs123123123123130123123",
NULL);
if (!ovs_iface_type || nm_streq (ovs_iface_type, "patch"))
nmtst_assert_connection_verifies (con);
else {
nmtst_assert_connection_unnormalizable (con,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY);
}
}
/*****************************************************************************/
NMTST_DEFINE ();
@ -8411,6 +8608,13 @@ int main (int argc, char **argv)
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/11", GUINT_TO_POINTER (11), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/12", GUINT_TO_POINTER (12), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/1", GUINT_TO_POINTER (1), test_connection_ovs_ifname);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/2", GUINT_TO_POINTER (2), test_connection_ovs_ifname);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/3", GUINT_TO_POINTER (3), test_connection_ovs_ifname);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/4", GUINT_TO_POINTER (4), test_connection_ovs_ifname);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/5", GUINT_TO_POINTER (5), test_connection_ovs_ifname);
g_test_add_data_func ("/core/general/test_connection_ovs_ifname/6", GUINT_TO_POINTER (6), test_connection_ovs_ifname);
g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers);
g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property);

View file

@ -12,6 +12,7 @@
#include <fcntl.h>
#include <sys/syscall.h>
#include <glib-unix.h>
#include <net/if.h>
#include "nm-errno.h"
@ -3987,3 +3988,91 @@ nm_utils_g_main_context_create_integrate_source (GMainContext *inner_context)
return &ctx_src->source;
}
gboolean
nm_utils_ifname_valid_kernel (const char *name, GError **error)
{
int i;
if (!name) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is missing"));
return FALSE;
}
if (name[0] == '\0') {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is too short"));
return FALSE;
}
if ( name[0] == '.'
&& ( name[1] == '\0'
|| ( name[1] == '.'
&& name[2] == '\0'))) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is reserved"));
return FALSE;
}
for (i = 0; i < IFNAMSIZ; i++) {
char ch = name[i];
if (ch == '\0')
return TRUE;
if ( NM_IN_SET (ch, '/', ':')
|| g_ascii_isspace (ch)) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name contains an invalid character"));
return FALSE;
}
}
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is longer than 15 characters"));
return FALSE;
}
static gboolean
_nm_utils_ifname_valid_ovs (const char* name, GError **error)
{
const char *ch;
for (ch = name; *ch; ++ch) {
if ( *ch == '\\'
|| *ch == '/'
|| g_ascii_isspace (*ch)
|| !g_ascii_isalnum (*ch)) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name must be alphanumerical with "
"no forward or backward slashes"));
return FALSE;
}
};
return TRUE;
}
gboolean
nm_utils_ifname_valid (const char* name,
NMUtilsIfaceType type,
GError **error)
{
g_return_val_if_fail (!error || !(*error), FALSE);
if (!name || !(name[0])) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name must not be empty"));
return FALSE;
}
g_return_val_if_fail (g_utf8_validate (name, -1, NULL), FALSE);
switch (type) {
case NMU_IFACE_KERNEL:
return nm_utils_ifname_valid_kernel (name, error);
case NMU_IFACE_OVS:
return _nm_utils_ifname_valid_ovs (name, error);
}
g_return_val_if_reached (FALSE);
}

View file

@ -1440,4 +1440,17 @@ guint nm_utils_parse_debug_string (const char *string,
const GDebugKey *keys,
guint nkeys);
/*****************************************************************************/
typedef enum {
NMU_IFACE_KERNEL = 0,
NMU_IFACE_OVS,
} NMUtilsIfaceType;
gboolean nm_utils_ifname_valid_kernel (const char *name, GError **error);
gboolean nm_utils_ifname_valid (const char* name,
NMUtilsIfaceType type,
GError **error);
#endif /* __NM_SHARED_UTILS_H__ */

View file

@ -143,14 +143,6 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory,
return NULL;
}
if (!nm_utils_is_valid_iface_name (ifname, error)) {
g_prefix_error (error,
"failed to determine interface name: name \"%s\" is invalid",
ifname);
g_free (ifname);
return NULL;
}
return ifname;
}

View file

@ -1010,8 +1010,8 @@ set_property (GObject *object, guint prop_id,
case PROP_IFACE:
/* construct-only */
priv->iface = g_value_dup_string (value);
g_return_if_fail ( priv->iface
&& nm_utils_is_valid_iface_name (priv->iface, NULL));
g_return_if_fail (priv->iface);
nm_assert (nm_utils_ifname_valid_kernel (priv->iface, NULL));
break;
case PROP_IFINDEX:
/* construct-only */

View file

@ -430,7 +430,7 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device)
*
* Instead, try the interface-name... */
ifname = nm_device_get_ip_iface (device);
if (!nm_utils_is_valid_iface_name (ifname, NULL))
if (!nm_utils_ifname_valid_kernel (ifname, NULL))
return;
spec_to_free = g_strdup_printf (NM_MATCH_SPEC_INTERFACE_NAME_TAG"=%s", ifname);

View file

@ -2145,7 +2145,7 @@ nm_utils_sysctl_ip_conf_path (int addr_family, char *buf, const char *ifname, co
nm_assert (buf);
nm_assert_addr_family (addr_family);
g_assert (nm_utils_is_valid_iface_name (ifname, NULL));
g_assert (nm_utils_ifname_valid_kernel (ifname, NULL));
property = NM_ASSERT_VALID_PATH_COMPONENT (property);
len = g_snprintf (buf,
@ -2163,7 +2163,7 @@ nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char *
{
g_return_val_if_fail (path, FALSE);
NM_ASSERT_VALID_PATH_COMPONENT (property);
g_assert (!ifname || nm_utils_is_valid_iface_name (ifname, NULL));
g_assert (!ifname || nm_utils_ifname_valid_kernel (ifname, NULL));
if (addr_family == AF_INET) {
if (!g_str_has_prefix (path, IPV4_PROPERTY_DIR))
@ -2196,7 +2196,7 @@ nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char *
return FALSE;
memcpy (buf, path, l);
buf[l] = '\0';
if (!nm_utils_is_valid_iface_name (buf, NULL))
if (!nm_utils_ifname_valid_kernel (buf, NULL))
return FALSE;
path = slash + 1;
}
@ -3635,7 +3635,7 @@ nm_utils_ifname_cpy (char *dst, const char *name)
g_return_if_fail (dst);
g_return_if_fail (name && name[0]);
nm_assert (nm_utils_is_valid_iface_name (name, NULL));
nm_assert (nm_utils_ifname_valid_kernel (name, NULL));
/* ensures NUL padding of the entire IFNAMSIZ buffer. */

View file

@ -155,7 +155,7 @@ again:
const char *ifname = known_ifnames[try_count % 2];
nm_assert (ifindex > 0);
nm_assert (ifname && nm_utils_is_valid_iface_name (ifname, NULL));
nm_assert (ifname && nm_utils_ifname_valid_kernel (ifname, NULL));
nm_assert (fd >= 0);
memset (&ifr, 0, sizeof (ifr));
@ -1416,7 +1416,7 @@ nmp_utils_sysctl_open_netdir (int ifindex,
return -1;
}
nm_assert (nm_utils_is_valid_iface_name (ifname, NULL));
nm_assert (nm_utils_ifname_valid_kernel (ifname, NULL));
if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ)
g_return_val_if_reached (-1);

View file

@ -1175,7 +1175,7 @@ nmtstp_link_veth_add (NMPlatform *platform,
const NMPlatformLink *pllink = NULL;
gboolean success;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1204,7 +1204,7 @@ nmtstp_link_dummy_add (NMPlatform *platform,
const NMPlatformLink *pllink = NULL;
gboolean success;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1235,7 +1235,7 @@ nmtstp_link_gre_add (NMPlatform *platform,
char b2[INET_ADDRSTRLEN];
NMLinkType link_type;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE;
@ -1287,7 +1287,7 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
gboolean encap_ignore;
gboolean tclass_inherit;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
g_assert (!lnk->is_gre);
external_command = nmtstp_run_command_check_external (external_command);
@ -1348,7 +1348,7 @@ nmtstp_link_ip6gre_add (NMPlatform *platform,
char tclass[20];
gboolean tclass_inherit;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
g_assert (lnk->is_gre);
external_command = nmtstp_run_command_check_external (external_command);
@ -1397,7 +1397,7 @@ nmtstp_link_ipip_add (NMPlatform *platform,
char b1[INET_ADDRSTRLEN];
char b2[INET_ADDRSTRLEN];
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1438,7 +1438,7 @@ nmtstp_link_macvlan_add (NMPlatform *platform,
gboolean success;
NMLinkType link_type;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1486,7 +1486,7 @@ nmtstp_link_sit_add (NMPlatform *platform,
char b1[INET_ADDRSTRLEN];
char b2[INET_ADDRSTRLEN];
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1532,7 +1532,7 @@ nmtstp_link_tun_add (NMPlatform *platform,
int err;
int r;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
g_assert (lnk);
g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP));
g_assert (!out_fd || *out_fd == -1);
@ -1595,7 +1595,7 @@ nmtstp_link_vxlan_add (NMPlatform *platform,
int err;
int r;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (nm_utils_ifname_valid_kernel (name, NULL));
external_command = nmtstp_run_command_check_external (external_command);
@ -1684,7 +1684,7 @@ nmtstp_link_get_typed (NMPlatform *platform,
g_assert_cmpstr (name, ==, pllink->name);
}
g_assert (!name || nm_utils_is_valid_iface_name (name, NULL));
g_assert (!name || nm_utils_ifname_valid_kernel (name, NULL));
if (pllink && link_type != NM_LINK_TYPE_NONE)
g_assert_cmpint (pllink->type, ==, link_type);

View file

@ -399,7 +399,7 @@ make_connection_setting (const char *file,
if (v) {
GError *error = NULL;
if (nm_utils_is_valid_iface_name (v, &error)) {
if (nm_utils_ifname_valid_kernel (v, &error)) {
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME, v,
NULL);