diff --git a/clients/cli/connections.c b/clients/cli/connections.c index f97775b7d0..851ed85f21 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -3991,16 +3991,18 @@ set_connection_type (NmCli *nmc, NMConnection *con, OptionInfo *option, const ch static gboolean set_connection_iface (NmCli *nmc, NMConnection *con, OptionInfo *option, const char *value, GError **error) { + GError *tmp_error = NULL; + if (value) { - if (!nm_utils_iface_valid_name (value) && strcmp (value, "*") != 0) { - g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: '%s' is not a valid interface nor '*'."), - value); - return FALSE; - } /* 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 (con, option->setting_name, option->property, value, '\0', error); diff --git a/clients/cli/settings.c b/clients/cli/settings.c index dc46633be3..3b1f0ecb9c 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -3080,10 +3080,8 @@ nmc_property_set_ifname (NMSetting *setting, const char *prop, const char *val, { g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!nm_utils_iface_valid_name (val)) { - g_set_error (error, 1, 0, _("'%s' is not a valid interface name"), val); + if (!nm_utils_is_valid_iface_name (val, error)) return FALSE; - } g_object_set (setting, prop, val, NULL); return TRUE; } @@ -3345,7 +3343,7 @@ nmc_property_con_set_master (NMSetting *setting, const char *prop, const char *v ; else if (!*val) val = NULL; - else if ( !nm_utils_iface_valid_name (val) + else if ( !nm_utils_is_valid_iface_name (val, NULL) && !nm_utils_is_uuid (val)) { g_set_error (error, 1, 0, _("'%s' is not valid master; use ifname or connection UUID"), diff --git a/clients/tui/nmt-device-entry.c b/clients/tui/nmt-device-entry.c index 86e92ca5ba..be1ad492c9 100644 --- a/clients/tui/nmt-device-entry.c +++ b/clients/tui/nmt-device-entry.c @@ -118,7 +118,7 @@ device_entry_parse (NmtDeviceEntry *deventry, return TRUE; if (priv->hardware_type == G_TYPE_NONE && !priv->device_filter) { - if (nm_utils_iface_valid_name (text)) { + if (nm_utils_is_valid_iface_name (text, NULL)) { *interface_name = g_strdup (text); return TRUE; } else @@ -142,12 +142,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_iface_valid_name (words[1]))) { + && (!words[1] || nm_utils_is_valid_iface_name (words[1], NULL))) { *mac_address = words[0]; *interface_name = NULL; g_free (words); return TRUE; - } else if ( nm_utils_iface_valid_name (words[0]) + } else if ( nm_utils_is_valid_iface_name (words[0], NULL) && (!words[1] || nm_utils_hwaddr_aton (words[1], buf, len))) { *interface_name = words[0]; *mac_address = NULL; diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 0364c49d0f..a01adc12b9 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -245,7 +245,7 @@ validate_ifname (const char *name, const char *value) if (!value || !value[0]) return FALSE; - return nm_utils_iface_valid_name (value); + return nm_utils_is_valid_iface_name (value, NULL); } /** @@ -618,13 +618,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) 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)) { + GError *tmp_error = NULL; + + if (primary && !nm_utils_is_valid_iface_name (primary, &tmp_error)) { 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); + _("'%s' is not a valid for '%s' option: %s"), + primary, NM_SETTING_BOND_OPTION_PRIMARY, tmp_error->message); g_prefix_error (error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); + g_error_free (tmp_error); return FALSE; } } else { diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 205a32199f..d7a0d2fc11 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -891,13 +891,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } if (priv->interface_name) { - if (!nm_utils_iface_valid_name (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' is not a valid interface name"), - priv->interface_name); + "'%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; } } @@ -1104,7 +1106,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_iface_valid_name (interface_name)) + if (!interface_name || nm_utils_is_valid_iface_name (interface_name, NULL)) interface_name = g_variant_get_string (value, NULL); g_object_set (G_OBJECT (setting), diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index f0856ee79f..1bbe2b3fb5 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -210,12 +210,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } 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")); + GError *tmp_error = NULL; + + if (!nm_utils_is_valid_iface_name (priv->parent, &tmp_error)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "'%s': %s", priv->parent, tmp_error->message); g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT); + g_error_free (tmp_error); return FALSE; } if (priv->p_key == -1) { @@ -241,10 +244,11 @@ 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_iface_valid_name (interface_name)) { + else if (!nm_utils_is_valid_iface_name (interface_name, &tmp_error)) { /* report the error for NMSettingConnection:interface-name, because * it's that property that is invalid -- although we currently verify() * NMSettingInfiniband. @@ -252,9 +256,9 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("'%s' is not a valid interface name"), - interface_name); + "'%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) { diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index b441795136..09c5798a25 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -2233,7 +2233,7 @@ verify_label (const char *label) if (!p) return FALSE; iface = g_strndup (label, p - label); - if (!nm_utils_iface_valid_name (iface)) { + if (!nm_utils_is_valid_iface_name (iface, NULL)) { g_free (iface); return FALSE; } diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 50630a4572..4589f766af 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -322,7 +322,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } if ( priv->parent - && !nm_utils_iface_valid_name (priv->parent) + && !nm_utils_is_valid_iface_name (priv->parent, NULL) && !nm_utils_is_uuid (priv->parent)) { g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c index 836e6d5e7c..f5edc6e842 100644 --- a/libnm-core/nm-setting-macvlan.c +++ b/libnm-core/nm-setting-macvlan.c @@ -160,7 +160,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) if (priv->parent) { if ( !nm_utils_is_uuid (priv->parent) - && !nm_utils_iface_valid_name (priv->parent)) { + && !nm_utils_is_valid_iface_name (priv->parent, NULL)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index e00acf03dd..6126478479 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -637,7 +637,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } } - } else if (!nm_utils_iface_valid_name (priv->parent)) { + } else if (!nm_utils_is_valid_iface_name (priv->parent, NULL)) { /* parent must be either a UUID or an interface name */ g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c index deedd919ae..f6717a2fdf 100644 --- a/libnm-core/nm-setting-vxlan.c +++ b/libnm-core/nm-setting-vxlan.c @@ -395,7 +395,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } if ( priv->parent - && !nm_utils_iface_valid_name (priv->parent) + && !nm_utils_is_valid_iface_name (priv->parent, NULL) && !nm_utils_is_uuid (priv->parent)) { g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 17ecafed72..5b4566bf41 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3737,8 +3737,11 @@ _nm_utils_generate_mac_address_mask_parse (const char *value, /*****************************************************************************/ /** - * nm_utils_iface_valid_name: + * nm_utils_is_valid_iface_name: * @name: Name of interface + * @error: location to store the error occurring, or %NULL to ignore + * + * Validate the network interface name. * * This function is a 1:1 copy of the kernel's interface validation * function in net/core/dev.c. @@ -3746,28 +3749,56 @@ _nm_utils_generate_mac_address_mask_parse (const char *value, * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. */ gboolean -nm_utils_iface_valid_name (const char *name) +nm_utils_is_valid_iface_name (const char *name, GError **error) { g_return_val_if_fail (name != NULL, FALSE); - if (*name == '\0') + if (*name == '\0') { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("interface name is too short")); return FALSE; + } - if (strlen (name) >= 16) + if (strlen (name) >= 16) { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("interface name is longer than 15 characters")); return FALSE; + } - if (!strcmp (name, ".") || !strcmp (name, "..")) + if (!strcmp (name, ".") || !strcmp (name, "..")) { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("interface name is reserved")); return FALSE; + } while (*name) { - if (*name == '/' || g_ascii_isspace (*name)) + if (*name == '/' || g_ascii_isspace (*name)) { + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + _("interface name contains an invalid character")); return FALSE; + } name++; } return TRUE; } +/** + * nm_utils_iface_valid_name: + * @name: Name of interface + * + * Validate the network interface name. + * + * Deprecated: 1.6: use nm_utils_is_valid_iface_name() insteead, with better error reporting. + * + * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned. + */ +gboolean +nm_utils_iface_valid_name (const char *name) +{ + return nm_utils_is_valid_iface_name (name, NULL); +} + /** * nm_utils_is_uuid: * @str: a string that might be a UUID diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index dfffb33506..caf2e62e02 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -177,7 +177,10 @@ gboolean nm_utils_hwaddr_matches (gconstpointer hwaddr1, char *nm_utils_bin2hexstr (gconstpointer src, gsize len, int final_len); GBytes *nm_utils_hexstr2bin (const char *hex); -gboolean nm_utils_iface_valid_name(const char *name); +NM_DEPRECATED_IN_1_6_FOR(nm_utils_is_valid_iface_name) +gboolean nm_utils_iface_valid_name (const char *name); +NM_AVAILABLE_IN_1_6 +gboolean nm_utils_is_valid_iface_name (const char *name, GError **error); gboolean nm_utils_is_uuid (const char *str); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index aaafe536e3..309c4b82d8 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1108,4 +1108,5 @@ global: nm_setting_proxy_get_pac_script; nm_utils_is_json_object; nm_utils_version; + nm_utils_is_valid_iface_name; } libnm_1_4_0; diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index 58bf8b7e95..dc8e26605b 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -202,12 +202,10 @@ nm_device_factory_get_connection_iface (NMDeviceFactory *factory, 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); + 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; } diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index a1f01b3f81..f2d55652eb 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -3606,7 +3606,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_iface_valid_name (name)); + nm_assert (nm_utils_is_valid_iface_name (name, NULL)); if (g_strlcpy (dst, name, IFNAMSIZ) >= IFNAMSIZ) g_return_if_reached (); diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 22e723626e..65fb01bc2c 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -723,7 +723,7 @@ nmp_utils_sysctl_open_netdir (int ifindex, return -1; } - nm_assert (nm_utils_iface_valid_name (ifname)); + nm_assert (nm_utils_is_valid_iface_name (ifname, NULL)); if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ) g_return_val_if_reached (-1); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 89cbd188ed..0e42a727d7 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -226,7 +226,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 gs_free_error GError *error = NULL; gs_free char *metric_pattern = NULL; - g_assert (ifname && nm_utils_iface_valid_name (ifname)); + g_assert (ifname && nm_utils_is_valid_iface_name (ifname, NULL)); g_assert (!strstr (ifname, " metric ")); g_assert (plen >= 0 && plen <= 32); @@ -933,7 +933,7 @@ nmtstp_link_dummy_add (NMPlatform *platform, const NMPlatformLink *pllink = NULL; gboolean success; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -962,7 +962,7 @@ nmtstp_link_gre_add (NMPlatform *platform, gboolean success; char buffer[INET_ADDRSTRLEN]; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1002,7 +1002,7 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean success; char buffer[INET6_ADDRSTRLEN]; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1056,7 +1056,7 @@ nmtstp_link_ipip_add (NMPlatform *platform, gboolean success; char buffer[INET_ADDRSTRLEN]; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1097,7 +1097,7 @@ nmtstp_link_macvlan_add (NMPlatform *platform, gboolean success; NMLinkType link_type; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1144,7 +1144,7 @@ nmtstp_link_sit_add (NMPlatform *platform, gboolean success; char buffer[INET_ADDRSTRLEN]; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1189,7 +1189,7 @@ nmtstp_link_vxlan_add (NMPlatform *platform, NMPlatformError plerr; int err; - g_assert (nm_utils_iface_valid_name (name)); + g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); @@ -1273,7 +1273,7 @@ nmtstp_link_get_typed (NMPlatform *platform, g_assert_cmpstr (name, ==, pllink->name); } - g_assert (!name || nm_utils_iface_valid_name (name)); + g_assert (!name || nm_utils_is_valid_iface_name (name, NULL)); if (pllink && link_type != NM_LINK_TYPE_NONE) g_assert_cmpint (pllink->type, ==, link_type); diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 6f8824d0b2..b64cad3576 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -159,12 +159,16 @@ make_connection_setting (const char *file, value = svGetValueString (ifcfg, "DEVICE"); if (value) { - if (nm_utils_iface_valid_name (value)) { + GError *error = NULL; + + if (nm_utils_is_valid_iface_name (value, &error)) { g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, value, NULL); - } else - PARSE_WARNING ("invalid DEVICE name '%s'", value); + } else { + PARSE_WARNING ("invalid DEVICE name '%s': %s", value, error->message); + g_error_free (error); + } g_free (value); }