diff options
Diffstat (limited to 'libnm-core')
| -rw-r--r-- | libnm-core/meson.build | 5 | ||||
| -rw-r--r-- | libnm-core/nm-connection-private.h | 1 | ||||
| -rw-r--r-- | libnm-core/nm-connection.c | 1 | ||||
| -rw-r--r-- | libnm-core/nm-setting-bond.c | 4 | ||||
| -rw-r--r-- | libnm-core/nm-setting-connection.c | 71 | ||||
| -rw-r--r-- | libnm-core/nm-setting-infiniband.c | 4 | ||||
| -rw-r--r-- | libnm-core/nm-setting-ip-config.c | 15 | ||||
| -rw-r--r-- | libnm-core/nm-setting-ip-tunnel.c | 2 | ||||
| -rw-r--r-- | libnm-core/nm-setting-ip6-config.c | 63 | ||||
| -rw-r--r-- | libnm-core/nm-setting-ip6-config.h | 4 | ||||
| -rw-r--r-- | libnm-core/nm-setting-macvlan.c | 2 | ||||
| -rw-r--r-- | libnm-core/nm-setting-ovs-interface.c | 51 | ||||
| -rw-r--r-- | libnm-core/nm-setting-pppoe.c | 2 | ||||
| -rw-r--r-- | libnm-core/nm-setting-vlan.c | 2 | ||||
| -rw-r--r-- | libnm-core/nm-setting-vxlan.c | 2 | ||||
| -rw-r--r-- | libnm-core/nm-utils.c | 43 | ||||
| -rw-r--r-- | libnm-core/nm-version.h | 6 | ||||
| -rw-r--r-- | libnm-core/tests/test-general.c | 194 |
18 files changed, 382 insertions, 90 deletions
diff --git a/libnm-core/meson.build b/libnm-core/meson.build index 4c72590e..469d4161 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -188,9 +188,12 @@ links = [ libnm_libnm_core_intern, ] +libnm_core_c_args = common_c_flags + if enable_json_validation libnm_core_sources += files('nm-json.c') deps += jansson_dep + libnm_core_c_args += ['-fcommon'] endif libnm_core = static_library( @@ -198,7 +201,7 @@ libnm_core = static_library( sources: libnm_core_sources + libnm_core_enum_sources + nm_meta_setting_source + [nm_version_macro_header], include_directories: top_inc, dependencies: deps, - c_args: common_c_flags, + c_args: libnm_core_c_args, link_with: links, ) diff --git a/libnm-core/nm-connection-private.h b/libnm-core/nm-connection-private.h index ea7583e0..034c350f 100644 --- a/libnm-core/nm-connection-private.h +++ b/libnm-core/nm-connection-private.h @@ -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__ */ diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 307b9d62..4146fd55 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -1235,6 +1235,7 @@ _normalize_ovs_interface_type (NMConnection *self) self, TRUE, &modified, + NULL, NULL); if (v != TRUE) g_return_val_if_reached (modified); diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 52da8ccf..f4c35663 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -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, diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index a13e3f23..17058ea7 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -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), @@ -2173,13 +2187,16 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * * Whether mDNS is enabled for the connection. * - * The permitted values are: yes: register hostname and resolving - * for the connection, no: disable mDNS for the interface, resolve: - * do not register hostname but allow resolving of mDNS host names. - * - * This feature requires a plugin which supports mDNS. One such - * plugin is dns-systemd-resolved. + * The permitted values are: "yes" (2) register hostname and resolving + * for the connection, "no" (0) disable mDNS for the interface, "resolve" + * (1) do not register hostname but allow resolving of mDNS host names + * and "default" (-1) to allow lookup of a global default in NetworkManager.conf. + * If unspecified, "default" ultimately depends on the DNS plugin (which + * for systemd-resolved currently means "no"). * + * This feature requires a plugin which supports mDNS. Otherwise the + * setting has no effect. One such plugin is dns-systemd-resolved. +* * Since: 1.12 **/ /* ---ifcfg-rh--- @@ -2206,12 +2223,14 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass) * System (DNS) packet format that allows both IPv4 and IPv6 hosts * to perform name resolution for hosts on the same local link. * - * The permitted values are: yes: register hostname and resolving - * for the connection, no: disable LLMNR for the interface, resolve: - * do not register hostname but allow resolving of LLMNR host names. + * The permitted values are: "yes" (2) register hostname and resolving + * for the connection, "no" (0) disable LLMNR for the interface, "resolve" + * (1) do not register hostname but allow resolving of LLMNR host names + * If unspecified, "default" ultimately depends on the DNS plugin (which + * for systemd-resolved currently means "yes"). * - * This feature requires a plugin which supports LLMNR. One such - * plugin is dns-systemd-resolved. + * This feature requires a plugin which supports LLMNR. Otherwise the + * setting has no effect. One such plugin is dns-systemd-resolved. * * Since: 1.14 **/ diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index d03a7a2a..fcaa1f9a 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -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. diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 49a3efbd..7f1690ac 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -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; } @@ -5637,10 +5637,11 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) * When using dns=default, servers with higher priority will be on top of * resolv.conf. To prioritize a given server over another one within the * same connection, just specify them in the desired order. When multiple - * devices have configurations with the same priority, the one with an - * active default route will be preferred. Negative values have the special + * devices have configurations with the same priority, VPNs will be + * considered first, then devices with the best (lowest metric) default + * route and then all other devices. Negative values have the special * effect of excluding other configurations with a greater priority value; - * so in presence of at least a negative priority, only DNS servers from + * so in presence of at least one negative priority, only DNS servers from * connections with the lowest priority value will be used. * * When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or @@ -5871,7 +5872,11 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass) /** * NMSettingIPConfig:dhcp-timeout: * - * A timeout for a DHCP transaction in seconds. + * A timeout for a DHCP transaction in seconds. If zero (the default), a + * globally configured default is used. If still unspecified, a device specific + * timeout is used (usually 45 seconds). + * + * Set to 2147483647 (MAXINT32) for infinity. **/ obj_properties[PROP_DHCP_TIMEOUT] = g_param_spec_int (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, "", "", diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 3df89cdd..ae1df194 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -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, diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 4cbda830..f3306ade 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -43,13 +43,15 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_ADDR_GEN_MODE, PROP_TOKEN, PROP_DHCP_DUID, + PROP_RA_TIMEOUT, ); typedef struct { - NMSettingIP6ConfigPrivacy ip6_privacy; - NMSettingIP6ConfigAddrGenMode addr_gen_mode; char *token; char *dhcp_duid; + NMSettingIP6ConfigPrivacy ip6_privacy; + NMSettingIP6ConfigAddrGenMode addr_gen_mode; + gint32 ra_timeout; } NMSettingIP6ConfigPrivate; G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG) @@ -134,6 +136,23 @@ nm_setting_ip6_config_get_dhcp_duid (NMSettingIP6Config *setting) return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dhcp_duid; } +/** + * nm_setting_ip6_config_get_ra_timeout: + * @setting: the #NMSettingIP6Config + * + * Returns: The configured %NM_SETTING_IP6_CONFIG_RA_TIMEOUT value with the + * timeout for router advertisements in seconds. + * + * Since: 1.24, 1.22.8 + **/ +gint32 +nm_setting_ip6_config_get_ra_timeout (NMSettingIP6Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), 0); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ra_timeout; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -475,6 +494,9 @@ get_property (GObject *object, guint prop_id, case PROP_DHCP_DUID: g_value_set_string (value, priv->dhcp_duid); break; + case PROP_RA_TIMEOUT: + g_value_set_int (value, priv->ra_timeout); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -502,6 +524,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->dhcp_duid); priv->dhcp_duid = g_value_dup_string (value); break; + case PROP_RA_TIMEOUT: + priv->ra_timeout = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -658,6 +683,14 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) */ /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: IPV6_DHCP_TIMEOUT(+) + * description: A timeout after which the DHCP transaction fails in case of no response. + * example: IPV6_DHCP_TIMEOUT=10 + * ---end--- + */ + + /* ---ifcfg-rh--- * property: dhcp-hostname-flags * variable: DHCPV6_HOSTNAME_FLAGS * description: flags for the DHCP hostname property @@ -829,6 +862,32 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass) G_PARAM_STATIC_STRINGS); /** + * NMSettingIP6Config:ra-timeout: + * + * A timeout for waiting Router Advertisements in seconds. If zero (the default), a + * globally configured default is used. If still unspecified, the timeout depends on the + * sysctl settings of the device. + * + * Set to 2147483647 (MAXINT32) for infinity. + * + * Since: 1.24, 1.22.8 + **/ + /* ---ifcfg-rh--- + * property: dhcp-timeout + * variable: IPV6_RA_TIMEOUT(+) + * description: A timeout for waiting Router Advertisements in seconds. + * example: IPV6_RA_TIMEOUT=10 + * ---end--- + */ + + obj_properties[PROP_RA_TIMEOUT] = + g_param_spec_int (NM_SETTING_IP6_CONFIG_RA_TIMEOUT, "", "", + 0, G_MAXINT32, 0, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS); + + /** * NMSettingIP6Config:dhcp-duid: * * A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h index 86a39a8e..4173c3b0 100644 --- a/libnm-core/nm-setting-ip6-config.h +++ b/libnm-core/nm-setting-ip6-config.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS #define NM_SETTING_IP6_CONFIG_DHCP_DUID "dhcp-duid" +#define NM_SETTING_IP6_CONFIG_RA_TIMEOUT "ra-timeout" + /** * NM_SETTING_IP6_CONFIG_METHOD_IGNORE: * @@ -159,6 +161,8 @@ NM_AVAILABLE_IN_1_4 const char *nm_setting_ip6_config_get_token (NMSettingIP6Config *setting); NM_AVAILABLE_IN_1_12 const char *nm_setting_ip6_config_get_dhcp_duid (NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_22_8 +gint32 nm_setting_ip6_config_get_ra_timeout (NMSettingIP6Config *setting); G_END_DECLS diff --git a/libnm-core/nm-setting-macvlan.c b/libnm-core/nm-setting-macvlan.c index cb7778f1..d62184c2 100644 --- a/libnm-core/nm-setting-macvlan.c +++ b/libnm-core/nm-setting-macvlan.c @@ -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, diff --git a/libnm-core/nm-setting-ovs-interface.c b/libnm-core/nm-setting-ovs-interface.c index ecefd6a5..849b9a4e 100644 --- a/libnm-core/nm-setting-ovs-interface.c +++ b/libnm-core/nm-setting-ovs-interface.c @@ -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; } /*****************************************************************************/ diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index d9ff2a80..0fee96a1 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -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, diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 84b974dc..30f43760 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -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, diff --git a/libnm-core/nm-setting-vxlan.c b/libnm-core/nm-setting-vxlan.c index d363ff20..4e449bc8 100644 --- a/libnm-core/nm-setting-vxlan.c +++ b/libnm-core/nm-setting-vxlan.c @@ -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, diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 4659734b..90ae4070 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -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; - - 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_return_val_if_fail (!error || !*error, 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); } /** diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h index 8cb0ac50..3fd2f346 100644 --- a/libnm-core/nm-version.h +++ b/libnm-core/nm-version.h @@ -229,6 +229,12 @@ # define NM_AVAILABLE_IN_1_22_2 #endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_22_8 +# define NM_AVAILABLE_IN_1_22_8 G_UNAVAILABLE(1,22.8) +#else +# define NM_AVAILABLE_IN_1_22_8 +#endif + /* * Synchronous API for calling D-Bus in libnm is deprecated. See * https://developer.gnome.org/libnm/stable/usage.html#sync-api diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index c1b7b84a..3b75e0f7 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -8319,6 +8319,193 @@ 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 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); + + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs-br0", + 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 +8598,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); |