diff options
| author | Michael Biebl <biebl@debian.org> | 2022-08-16 18:24:19 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-08-16 18:24:19 +0200 |
| commit | 0018d1f3cf71d680d7b6bceda55a5717244d8b26 (patch) | |
| tree | a058f1d106d172d3354179437ef034c9355cdf9c /src/libnm-core-impl | |
| parent | 6accbd3ec0e42d8633bbde4d47ed7bfe854e7e0b (diff) | |
New upstream version 1.39.90 upstream/1.39.90
Diffstat (limited to 'src/libnm-core-impl')
| -rw-r--r-- | src/libnm-core-impl/nm-connection.c | 18 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-keyfile-utils.c | 6 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-keyfile.c | 44 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-8021x.c | 4 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-bond.c | 42 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-bridge.c | 11 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-connection.c | 223 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ethtool.c | 4 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip-config.c | 34 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip4-config.c | 115 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip6-config.c | 101 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-wireguard.c | 5 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-wireless.c | 12 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-team-utils.c | 4 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-utils.c | 21 | ||||
| -rw-r--r-- | src/libnm-core-impl/tests/test-general.c | 250 | ||||
| -rw-r--r-- | src/libnm-core-impl/tests/test-setting.c | 10 |
17 files changed, 757 insertions, 147 deletions
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 27cea2cb..aed4be21 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -1708,7 +1708,7 @@ _normalize_required_settings(NMConnection *self) NMSetting *s_bridge; gboolean changed = FALSE; - if (nm_connection_get_setting_vlan(self)) { + if (nm_connection_get_setting_vlan(self) || nm_connection_get_setting_bridge(self)) { if (!nm_connection_get_setting_wired(self)) { nm_connection_add_setting(self, nm_setting_wired_new()); changed = TRUE; @@ -3168,22 +3168,24 @@ nm_connection_get_virtual_device_description(NMConnection *connection) iface = nm_connection_get_interface_name(connection); - if (!strcmp(type, NM_SETTING_BOND_SETTING_NAME)) + if (nm_streq(type, NM_SETTING_BOND_SETTING_NAME)) display_type = _("Bond"); - else if (!strcmp(type, NM_SETTING_TEAM_SETTING_NAME)) + else if (nm_streq(type, NM_SETTING_TEAM_SETTING_NAME)) display_type = _("Team"); - else if (!strcmp(type, NM_SETTING_BRIDGE_SETTING_NAME)) + else if (nm_streq(type, NM_SETTING_BRIDGE_SETTING_NAME)) display_type = _("Bridge"); - else if (!strcmp(type, NM_SETTING_VLAN_SETTING_NAME)) + else if (nm_streq(type, NM_SETTING_VLAN_SETTING_NAME)) display_type = _("VLAN"); - else if (!strcmp(type, NM_SETTING_INFINIBAND_SETTING_NAME)) { + else if (nm_streq(type, NM_SETTING_INFINIBAND_SETTING_NAME)) { display_type = _("InfiniBand"); iface = nm_setting_infiniband_get_virtual_interface_name( nm_connection_get_setting_infiniband(connection)); - } else if (!strcmp(type, NM_SETTING_IP_TUNNEL_SETTING_NAME)) + } else if (nm_streq(type, NM_SETTING_IP_TUNNEL_SETTING_NAME)) display_type = _("IP Tunnel"); - else if (!strcmp(type, NM_SETTING_WIREGUARD_SETTING_NAME)) + else if (nm_streq(type, NM_SETTING_WIREGUARD_SETTING_NAME)) display_type = _("WireGuard"); + else if (nm_streq(type, NM_SETTING_TUN_SETTING_NAME)) + display_type = _("TUN/TAP"); if (!iface || !display_type) return NULL; diff --git a/src/libnm-core-impl/nm-keyfile-utils.c b/src/libnm-core-impl/nm-keyfile-utils.c index c599aefa..95073bcc 100644 --- a/src/libnm-core-impl/nm-keyfile-utils.c +++ b/src/libnm-core-impl/nm-keyfile-utils.c @@ -210,7 +210,7 @@ nm_keyfile_plugin_kf_set_integer_list_uint(GKeyFile *kf, g_return_if_fail(group && group[0]); g_return_if_fail(key && key[0]); - nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + strbuf = NM_STR_BUF_INIT(length * 4u + 2u, FALSE); for (i = 0; i < length; i++) nm_str_buf_append_printf(&strbuf, "%u;", data[i]); nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); @@ -231,7 +231,7 @@ nm_keyfile_plugin_kf_set_integer_list_uint8(GKeyFile *kf, g_return_if_fail(group && group[0]); g_return_if_fail(key && key[0]); - nm_str_buf_init(&strbuf, length * 4u + 2u, FALSE); + strbuf = NM_STR_BUF_INIT(length * 4u + 2u, FALSE); for (i = 0; i < length; i++) nm_str_buf_append_printf(&strbuf, "%u;", (guint) data[i]); nm_keyfile_plugin_kf_set_value(kf, group, key, nm_str_buf_get_str(&strbuf)); @@ -542,7 +542,7 @@ _keyfile_key_encode(const char *name, char **out_to_free) len = i + strlen(&name[i]); nm_assert(len == strlen(name)); - nm_str_buf_init(&str, len + 15u, FALSE); + str = NM_STR_BUF_INIT(len + 15u, FALSE); if (name[0] == ' ') { nm_assert(i == 0); diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c index 00fb8a33..6ee68b5c 100644 --- a/src/libnm-core-impl/nm-keyfile.c +++ b/src/libnm-core-impl/nm-keyfile.c @@ -21,7 +21,6 @@ #include "libnm-glib-aux/nm-uuid.h" #include "libnm-glib-aux/nm-str-buf.h" #include "libnm-glib-aux/nm-secret-utils.h" -#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "libnm-core-aux-intern/nm-common-macros.h" #include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" @@ -1160,17 +1159,30 @@ ip6_addr_gen_mode_parser(KeyfileReaderInfo *info, NMSetting *setting, const char s, (int *) &addr_gen_mode, NULL)) { - read_handle_warn(info, - key, - key, - NM_KEYFILE_WARN_SEVERITY_WARN, - _("invalid option '%s', use one of [%s]"), - s, - "eui64,stable-privacy"); - return; + if (!read_handle_warn(info, + key, + key, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid option '%s', use one of [%s]"), + s, + "eui64,stable-privacy")) + return; + addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64; } - } else - addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; + } else { + gs_free char *s2 = NULL; + + s2 = nm_keyfile_plugin_kf_get_string(info->keyfile, + setting_name, + NM_SETTING_IP6_CONFIG_TOKEN, + NULL); + if (s2) { + /* If a token is set, but the addr-gen-mode is not, then the default + * is eui64. Otherwise, the result would not verify. */ + addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64; + } else + addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64; + } g_object_set(G_OBJECT(setting), key, (int) addr_gen_mode, NULL); } @@ -2190,8 +2202,10 @@ ip6_addr_gen_mode_writer(KeyfileWriterInfo *info, gs_free char *str = NULL; addr_gen_mode = (NMSettingIP6ConfigAddrGenMode) g_value_get_int(value); - str = nm_utils_enum_to_str(nm_setting_ip6_config_addr_gen_mode_get_type(), addr_gen_mode); - nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, str); + if (addr_gen_mode != NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64) { + str = nm_utils_enum_to_str(nm_setting_ip6_config_addr_gen_mode_get_type(), addr_gen_mode); + nm_keyfile_plugin_kf_set_string(info->keyfile, nm_setting_get_name(setting), key, str); + } } static void @@ -4062,7 +4076,7 @@ _write_setting_wireguard(NMSetting *setting, KeyfileWriterInfo *info) public_key = nm_wireguard_peer_get_public_key(peer); if (!public_key || !public_key[0] - || !NM_STRCHAR_ALL(public_key, ch, nm_sd_utils_unbase64char(ch, TRUE) >= 0)) { + || !NM_STRCHAR_ALL(public_key, ch, nm_unbase64char(ch) != -EINVAL)) { /* invalid peer. Skip it */ continue; } @@ -4375,7 +4389,7 @@ nm_keyfile_utils_create_filename(const char *name, gboolean with_extension) g_return_val_if_fail(name && name[0], NULL); - nm_str_buf_init(&str, 0, FALSE); + str = NM_STR_BUF_INIT(0, FALSE); len = strlen(name); diff --git a/src/libnm-core-impl/nm-setting-8021x.c b/src/libnm-core-impl/nm-setting-8021x.c index 41feae57..fd9a0961 100644 --- a/src/libnm-core-impl/nm-setting-8021x.c +++ b/src/libnm-core-impl/nm-setting-8021x.c @@ -2980,8 +2980,6 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) error)) return FALSE; - /* normalizable warnings from here on. */ - #define _check_strempty_and_return(priv, prop_name, field, error) \ G_STMT_START \ { \ @@ -2999,6 +2997,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } \ G_STMT_END + /* normalizable warnings from here on. */ + _check_strempty_and_return(priv, NM_SETTING_802_1X_IDENTITY, identity, error); _check_strempty_and_return(priv, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index ae2fe051..cdfc7641 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -362,15 +362,6 @@ _bond_get_option_normalized(NMSettingBond *self, const char *option, gboolean ge return _bond_get_option_or_default(self, option); } -const char * -nm_setting_bond_get_option_or_default(NMSettingBond *self, const char *option) -{ - g_return_val_if_fail(NM_IS_SETTING_BOND(self), NULL); - g_return_val_if_fail(option, NULL); - - return _bond_get_option_normalized(self, option, FALSE); -} - static int _atoi(const char *value) { @@ -773,6 +764,39 @@ _nm_setting_bond_get_option_type(NMSettingBond *setting, const char *name) return option_meta->opt_type; } +guint32 +_nm_setting_bond_opt_value_as_u32(NMSettingBond *s_bond, const char *opt) +{ + nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT); + return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt), + 10, + 0, + G_MAXUINT32, + 0); +} + +guint16 +_nm_setting_bond_opt_value_as_u16(NMSettingBond *s_bond, const char *opt) +{ + nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT); + return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt), + 10, + 0, + G_MAXUINT16, + 0); +} + +guint8 +_nm_setting_bond_opt_value_as_u8(NMSettingBond *s_bond, const char *opt) +{ + nm_assert(_get_option_meta(opt)->opt_type == NM_BOND_OPTION_TYPE_INT); + return _nm_utils_ascii_str_to_uint64(nm_setting_bond_get_option_normalized(s_bond, opt), + 10, + 0, + G_MAXUINT8, + 0); +} + /*****************************************************************************/ static gboolean diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c index 41cd6632..39a3fb60 100644 --- a/src/libnm-core-impl/nm-setting-bridge.c +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -435,7 +435,7 @@ nm_bridge_vlan_to_str(const NMBridgeVlan *vlan, GError **error) * future if more parameters are added to the object that could * make it invalid. */ - nm_str_buf_init(&string, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + string = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (vlan->vid_start == vlan->vid_end) nm_str_buf_append_printf(&string, "%u", vlan->vid_start); @@ -1311,6 +1311,15 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_SETTING_BRIDGE_VLANS)) return NM_SETTING_VERIFY_NORMALIZABLE; + if (connection && !nm_connection_get_setting_wired(connection)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + _("bridge connection should have a ethernet setting as well")); + g_prefix_error(error, "%s: ", NM_SETTING_BRIDGE_SETTING_NAME); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + return TRUE; } diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index 0d7d7cd5..0d307be3 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -65,10 +65,12 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection, PROP_MDNS, PROP_LLMNR, PROP_DNS_OVER_TLS, + PROP_MPTCP_FLAGS, PROP_STABLE_ID, PROP_AUTH_RETRIES, PROP_WAIT_DEVICE_TIMEOUT, - PROP_MUD_URL, ); + PROP_MUD_URL, + PROP_WAIT_ACTIVATION_DELAY, ); typedef struct { GArray *permissions; @@ -94,6 +96,8 @@ typedef struct { gint32 dns_over_tls; gint32 wait_device_timeout; gint32 lldp; + gint32 wait_activation_delay; + guint32 mptcp_flags; guint32 gateway_ping_timeout; bool autoconnect; bool read_only; @@ -735,6 +739,23 @@ nm_setting_connection_get_wait_device_timeout(NMSettingConnection *setting) } /** + * nm_setting_connection_get_wait_activation_delay: + * @setting: the #NMSettingConnection + * + * Returns: the %NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY property with + * the delay in milliseconds. -1 is the default. + * + * Since: 1.40 + */ +gint32 +nm_setting_connection_get_wait_activation_delay(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), -1); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->wait_activation_delay; +} + +/** * nm_setting_connection_get_autoconnect_slaves: * @setting: the #NMSettingConnection * @@ -996,6 +1017,22 @@ nm_setting_connection_get_dns_over_tls(NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->dns_over_tls; } +/** + * nm_setting_connection_get_mptcp_flags: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:mptcp-flags property of the setting. + * + * Since: 1.40 + **/ +NMMptcpFlags +nm_setting_connection_get_mptcp_flags(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_MPTCP_FLAGS_NONE); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->mptcp_flags; +} + static void _set_error_missing_base_setting(GError **error, const char *type) { @@ -1348,6 +1385,64 @@ after_interface_name: return FALSE; } + if (priv->mptcp_flags != 0) { + if (NM_FLAGS_HAS(priv->mptcp_flags, NM_MPTCP_FLAGS_DISABLED)) { + if (priv->mptcp_flags != NM_MPTCP_FLAGS_DISABLED) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("\"disabled\" flag cannot be combined with other MPTCP flags")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MPTCP_FLAGS); + return FALSE; + } + } else { + guint32 f; + + if (NM_FLAGS_ALL(priv->mptcp_flags, + NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE | NM_MPTCP_FLAGS_ENABLED)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("\"enabled\" and \"enabled-on-global-iface\" flag cannot be set together")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MPTCP_FLAGS); + return FALSE; + } + if (NM_FLAGS_ALL(priv->mptcp_flags, NM_MPTCP_FLAGS_SIGNAL | NM_MPTCP_FLAGS_FULLMESH)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot set both \"signal\" and \"fullmesh\" MPTCP flags")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MPTCP_FLAGS); + return FALSE; + } + f = NM_FLAGS_UNSET(priv->mptcp_flags, NM_MPTCP_FLAGS_ENABLED_ON_GLOBAL_IFACE) + | ((guint32) NM_MPTCP_FLAGS_ENABLED); + if (f != nm_mptcp_flags_normalize(f)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value %u is not a valid combination of MPTCP flags"), + priv->mptcp_flags); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MPTCP_FLAGS); + return FALSE; + } + } + } + if (!NM_IN_SET(priv->multi_connect, (int) NM_CONNECTION_MULTI_CONNECT_DEFAULT, (int) NM_CONNECTION_MULTI_CONNECT_SINGLE, @@ -2464,6 +2559,101 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NMSettingConnectionPrivate, dns_over_tls); + /* Notes about "mptcp-flags": + * + * It is a bit odd that NMMptcpFlags mixes flags with different purposes: + * + * - "disabled", "disabled-on-local-iface", "enable": whether MPTCP handling + * is enabled. The flag "disabled-on-local-iface" enables it based on whether + * the interface has a default route. + * - "signal", "subflow", "backup", "fullmesh": the endpoint flags + * that are used. + * + * The reason is, that it is useful to have one "connection.mptcp-flags" + * property, that can express various aspects at once. The alternatives + * would be multiple properties like "connection.mptcp-enabled", + * "connection.mptcp-addr-flags" and "connection.mptcp-notify-flags". + * More properties does not necessarily make the API simpler. In particular + * for something like MPTCP, which should just work by default and only + * in special cases require special configuration. + * + * The entire idea is to only have one "connection.mptcp-flags" property (for now). + * That one can encode multiple aspects about MPTCP, whether it's enabled at all, + * which address flags to use when configuring endpoints, and opt-in addresses + * that otherwise would not be configured as endpoints. + * + * "connection.mptcp-flags" applies to all addresses on the interface (minus the ones + * that are not included by default). The idea is that in the future we could have + * more properties like "ipv4.dhcp-mptcp-flags=subflow", "ipv6.link-local-mptcp-flags=disabled", + * "ipv4.addresses='192.168.1.5/24 mptcp-flags=signal,backup'", which can overwrite the + * flags on a per-address basis. + * + * But for that future extension, we now need a global "connection.mptcp-flags" property + * in the API that is the basis and applies to all addresses. + */ + + /** + * NMSettingConnection:mptcp-flags: + * + * Whether to configure MPTCP endpoints and the address flags. + * If MPTCP is enabled in NetworkManager, it will configure the + * addresses of the interface as MPTCP endpoints. Note that + * IPv4 loopback addresses (127.0.0.0/8), IPv4 link local + * addresses (169.254.0.0/16), the IPv6 loopback address (::1), + * IPv6 link local addresses (fe80::/10), IPv6 unique + * local addresses (ULA, fc00::/7) and IPv6 privacy extension addresses + * (rfc3041, ipv6.ip6-privacy) will be excluded from being + * configured as endpoints. + * + * If "disabled" (0x1), MPTCP handling for the interface is disabled and + * no endpoints are registered. + * + * The flag "enabled-on-global-iface" (0x2) means that MPTCP handling is enabled + * if the interface configures a default route in the main routing table. + * This choice is per-address family, for example if there is an IPv4 default route + * 0.0.0.0/0, IPv4 endpoints are configured. + * + * The "enabled" (0x4) flag means that MPTCP handling is explicitly enabled. + * This flag can also be implied from the presence of other flags. + * + * If MPTCP handling is enabled, then endpoints will be configured + * with the specified address flags "signal" (0x10), "subflow" (0x20), "backup" (0x40), + * "fullmesh" (0x80). See ip-mptcp(8) manual for additional information about the flags. + * + * If the flags are zero, the global connection default from NetworkManager.conf is + * honored. If still unspecified, the fallback is either "disabled" or + * "enabled-on-global-iface,subflow" depending on "/proc/sys/net/mptcp/enabled". + * + * NetworkManager does not change the MPTCP limits nor enable MPTCP via + * "/proc/sys/net/mptcp/enabled". That is a host configuration which the + * admin can change via sysctl and ip-mptcp. + * + * Strict reverse path filtering (rp_filter) breaks many MPTCP use cases, so when + * MPTCP handling for IPv4 addresses on the interface is enabled, NetworkManager would + * loosen the strict reverse path filtering (1) to the loose setting (2). + * + * Since: 1.40 + **/ + /* ---ifcfg-rh--- + * property: mptcp-flags + * variable: MPTCP_FLAGS(+) + * default: missing variable means global default + * description: The MPTCP flags that indicate whether MPTCP is enabled + * and which flags to use for the address endpoints. + * example: MPTCP_FLAGS="signal,subflow" + * ---end--- + */ + _nm_setting_property_define_direct_uint32(properties_override, + obj_properties, + NM_SETTING_CONNECTION_MPTCP_FLAGS, + PROP_MPTCP_FLAGS, + 0, + G_MAXUINT32, + NM_MPTCP_FLAGS_NONE, + NM_SETTING_PARAM_NONE, + NMSettingConnectionPrivate, + mptcp_flags); + /** * NMSettingConnection:wait-device-timeout: * @@ -2530,6 +2720,37 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) NMSettingConnectionPrivate, mud_url); + /** + * NMSettingConnection:wait-activation-delay: + * + * Time in milliseconds to wait for connection to be considered activated. + * The wait will start after the pre-up dispatcher event. + * + * The value 0 means no wait time. The default value is -1, which + * currently has the same meaning as no wait time. + * + * Since: 1.40 + **/ + /* ---ifcfg-rh--- + * property: wait-activation-delay + * variable: WAIT_ACTIVATION_DELAY(+) + * values: delay in milliseconds. + * description: Time in milliseconds to wait for connection to be considered activated. + * The wait will start after the pre-up dispatcher event. + * example: WAIT_ACTIVATION_DELAY=5000 + * ---end--- + */ + _nm_setting_property_define_direct_int32(properties_override, + obj_properties, + NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, + PROP_WAIT_ACTIVATION_DELAY, + -1, + G_MAXINT32, + -1, + NM_SETTING_PARAM_NONE, + NMSettingConnectionPrivate, + wait_activation_delay); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit(setting_class, diff --git a/src/libnm-core-impl/nm-setting-ethtool.c b/src/libnm-core-impl/nm-setting-ethtool.c index 49c0d780..71179efd 100644 --- a/src/libnm-core-impl/nm-setting-ethtool.c +++ b/src/libnm-core-impl/nm-setting-ethtool.c @@ -45,11 +45,11 @@ get_variant_type_from_ethtool_id(NMEthtoolID ethtool_id) * * %Returns: %TRUE, if @optname is valid * - * Since: 1.20 - * * Note that nm_ethtool_optname_is_feature() was first added to the libnm header files * in 1.14.0 but forgot to actually add to the library. This happened belatedly in 1.20.0 and * the stable versions 1.18.2, 1.16.4 and 1.14.8 (with linker version "libnm_1_14_8"). + * + * Since: 1.20 */ gboolean nm_ethtool_optname_is_feature(const char *optname) diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index cffd5b19..ab760c4e 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -1197,6 +1197,10 @@ nm_ip_route_set_attribute(NMIPRoute *route, const char *name, GVariant *value) } static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = { + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_ADVMSS, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, .v4 = TRUE, @@ -1213,6 +1217,10 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = { G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_ADVMSS, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, @@ -1241,6 +1249,14 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = { G_VARIANT_TYPE_BOOLEAN, .v4 = TRUE, .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_QUICKACK, + G_VARIANT_TYPE_BOOLEAN, + .v4 = TRUE, + .v6 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_RTO_MIN, + G_VARIANT_TYPE_UINT32, + .v4 = TRUE, + .v6 = TRUE, ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_SCOPE, G_VARIANT_TYPE_BYTE, .v4 = TRUE, @@ -2481,10 +2497,10 @@ nm_ip_routing_rule_set_suppress_prefixlength(NMIPRoutingRule *self, gint32 suppr * * Returns: %TRUE if a uid range is set. * - * Since: 1.34 - * * This API was wrongly introduced in the header files for 1.32, but the * symbols were not exported. The API only works since 1.34 and newer. + * + * Since: 1.34 */ gboolean nm_ip_routing_rule_get_uid_range(const NMIPRoutingRule *self, @@ -2509,10 +2525,10 @@ nm_ip_routing_rule_get_uid_range(const NMIPRoutingRule *self, * For a valid range, start must be less or equal to end. * If set to an invalid range, the range gets unset. * - * Since: 1.34 - * * This API was wrongly introduced in the header files for 1.32, but the * symbols were not exported. The API only works since 1.34 and newer. + * + * Since: 1.34 */ void nm_ip_routing_rule_set_uid_range(NMIPRoutingRule *self, @@ -3814,7 +3830,7 @@ nm_ip_routing_rule_to_string(const NMIPRoutingRule *self, } } - nm_str_buf_init(&str, NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); + str = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); if (self->priority_has) { nm_str_buf_append_printf(nm_str_buf_append_required_delimiter(&str, ' '), @@ -6149,7 +6165,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) /** * NMSettingIPConfig:dns-search: * - * Array of DNS search domains. Domains starting with a tilde ('~') + * List of DNS search domains. Domains starting with a tilde ('~') * are considered 'routing' domains and are used only to decide the * interface over which a query must be forwarded; they are not used * to complete unqualified host names. @@ -6158,6 +6174,12 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * Split DNS, then the search domains specify which name servers to * query. This makes the behavior different from running with plain * /etc/resolv.conf. For more information see also the dns-priority setting. + * + * When set on a profile that also enabled DHCP, the DNS search list + * received automatically (option 119 for DHCPv4 and option 24 for DHCPv6) + * gets merged with the manual list. This can be prevented by setting + * "ignore-auto-dns". Note that if no DNS searches are configured, the + * fallback will be derived from the domain from DHCP (option 15). **/ obj_properties[PROP_DNS_SEARCH] = g_param_spec_boxed(NM_SETTING_IP_CONFIG_DNS_SEARCH, diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index bf555168..ff56834e 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -38,14 +38,16 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DHCP_CLIENT_ID, PROP_DHCP_FQDN, - PROP_DHCP_VENDOR_CLASS_IDENTIFIER, ); + PROP_DHCP_VENDOR_CLASS_IDENTIFIER, + PROP_LINK_LOCAL, ); typedef struct { NMSettingIPConfigPrivate parent; - char *dhcp_client_id; - char *dhcp_fqdn; - char *dhcp_vendor_class_identifier; + char *dhcp_client_id; + char *dhcp_fqdn; + char *dhcp_vendor_class_identifier; + gint32 link_local; } NMSettingIP4ConfigPrivate; /** @@ -127,6 +129,25 @@ nm_setting_ip4_config_get_dhcp_vendor_class_identifier(NMSettingIP4Config *setti return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_vendor_class_identifier; } +/** + * nm_setting_ip4_config_get_link_local: + * @setting: the #NMSettingIP4Config + * + * Returns the value contained in the #NMSettingIP4Config:link_local + * property. + * + * Returns: the link-local configuration + * + * Since: 1.40 + **/ +NMSettingIP4LinkLocal +nm_setting_ip4_config_get_link_local(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), NM_SETTING_IP4_LL_DEFAULT); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->link_local; +} + static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { @@ -218,6 +239,46 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (!NM_IN_SET(priv->link_local, + NM_SETTING_IP4_LL_AUTO, + NM_SETTING_IP4_LL_DEFAULT, + NM_SETTING_IP4_LL_DISABLED, + NM_SETTING_IP4_LL_ENABLED)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property is invalid")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_LINK_LOCAL); + return FALSE; + } + if (priv->link_local == NM_SETTING_IP4_LL_ENABLED + && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot enable ipv4.link-local with ipv4.method=disabled")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_LINK_LOCAL); + return FALSE; + } + if (priv->link_local == NM_SETTING_IP4_LL_DISABLED + && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot disable ipv4.link-local with ipv4.method=link-local")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP4_CONFIG_LINK_LOCAL); + return FALSE; + } + if (priv->dhcp_client_id && !priv->dhcp_client_id[0]) { g_set_error_literal(error, NM_CONNECTION_ERROR, @@ -854,6 +915,39 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) NMSettingIP4ConfigPrivate, dhcp_vendor_class_identifier); + /** + * NMSettingIP4Config:link-local: + * + * Enable and disable the IPv4 link-local configuration independently of the + * ipv4.method configuration. This allows a link-local address (169.254.x.y/16) + * to be obtained in addition to other addresses, such as those manually + * configured or obtained from a DHCP server. + * + * When set to "auto", the value is dependent on "ipv4.method". + * When set to "default", it honors the global connection default, before + * falling back to "auto". Note that if "ipv4.method" is "disabled", then + * link local addressing is always disabled too. The default is "default". + * + * Since 1.40 + */ + /* ---ifcfg-rh--- + * property: link-local + * variable: IPV4_LINK_LOCAL(+) + * description: Configure link-local IP address in interaction with method + * example: IPV4_LINK_LOCAL=auto + * ---end--- + */ + _nm_setting_property_define_direct_int32(properties_override, + obj_properties, + NM_SETTING_IP4_CONFIG_LINK_LOCAL, + PROP_LINK_LOCAL, + G_MININT32, + G_MAXINT32, + NM_SETTING_IP4_LL_DEFAULT, + NM_SETTING_PARAM_NONE, + NMSettingIP4ConfigPrivate, + link_local); + /* IP4-specific property overrides */ /* ---dbus--- @@ -963,6 +1057,9 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * Various attributes are supported: * <itemizedlist> * <listitem> + * <para><literal>"advmss"</literal> - an unsigned 32 bit integer.</para> + * </listitem> + * <listitem> * <para><literal>"cwnd"</literal> - an unsigned 32 bit integer.</para> * </listitem> * <listitem> @@ -972,6 +1069,9 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * <para><literal>"initrwnd"</literal> - an unsigned 32 bit integer.</para> * </listitem> * <listitem> + * <para><literal>"lock-advmss"</literal> - a boolean value.</para> + * </listitem> + * <listitem> * <para><literal>"lock-cwnd"</literal> - a boolean value.</para> * </listitem> * <listitem> @@ -993,6 +1093,13 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * <para><literal>"onlink"</literal> - a boolean value.</para> * </listitem> * <listitem> + * <para><literal>"quickack"</literal> - a boolean value.</para> + * </listitem> + * <listitem> + * <para><literal>"rto_min"</literal> - an unsigned 32 bit integer. + * The value is in milliseconds.</para> + * </listitem> + * <listitem> * <para><literal>"scope"</literal> - an unsigned 8 bit integer. IPv4 only.</para> * </listitem> * <listitem> diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index f75c14ce..8b593b97 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -43,16 +43,18 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_IP6_PRIVACY, PROP_ADDR_GEN_MODE, PROP_TOKEN, PROP_DHCP_DUID, - PROP_RA_TIMEOUT, ); + PROP_RA_TIMEOUT, + PROP_MTU, ); typedef struct { NMSettingIPConfigPrivate parent; - char *token; - char *dhcp_duid; - int ip6_privacy; - gint32 addr_gen_mode; - gint32 ra_timeout; + char *token; + char *dhcp_duid; + int ip6_privacy; + gint32 addr_gen_mode; + gint32 ra_timeout; + guint32 mtu; } NMSettingIP6ConfigPrivate; /** @@ -110,7 +112,7 @@ NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode(NMSettingIP6Config *setting) { g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), - NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY); + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT); return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->addr_gen_mode; } @@ -171,6 +173,23 @@ nm_setting_ip6_config_get_ra_timeout(NMSettingIP6Config *setting) return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->ra_timeout; } +/** + * nm_setting_ip6_config_get_mtu: + * @setting: the #NMSettingIP6Config + * + * Returns: The configured %NM_SETTING_IP6_CONFIG_MTU value for the maximum + * transmission unit. + * + * Since: 1.40 + **/ +guint32 +nm_setting_ip6_config_get_mtu(NMSettingIP6Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP6_CONFIG(setting), 0); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting)->mtu; +} + static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { @@ -269,7 +288,9 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) if (!NM_IN_SET(priv->addr_gen_mode, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, - NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)) { + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT)) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -757,8 +778,10 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * * Configure method for creating the address for use with RFC4862 IPv6 * Stateless Address Autoconfiguration. The permitted values are: - * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 or + * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY. + * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64 + * or %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT. * * If the property is set to EUI64, the addresses will be generated * using the interface tokens derived from hardware address. This makes @@ -773,9 +796,16 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * and makes the address stable when the network interface hardware is * replaced. * - * On D-Bus, the absence of an addr-gen-mode setting equals enabling - * stable-privacy. For keyfile plugin, the absence of the setting - * on disk means EUI64 so that the property doesn't change on upgrade + * The special values "default" and "default-or-eui64" will fallback to the global + * connection default in as documented in NetworkManager.conf(5) manual. If the + * global default is not specified, the fallback value is "stable-privacy" + * or "eui64", respectively. + * + * For libnm, the property defaults to "default" since 1.40. + * Previously it defaulted to "stable-privacy". + * On D-Bus, the absence of an addr-gen-mode setting equals + * "default". For keyfile plugin, the absence of the setting + * on disk means "default-or-eui64" so that the property doesn't change on upgrade * from older versions. * * Note that this setting is distinct from the Privacy Extensions as @@ -787,8 +817,8 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) /* ---ifcfg-rh--- * property: addr-gen-mode * variable: IPV6_ADDR_GEN_MODE - * values: IPV6_ADDR_GEN_MODE: eui64, stable-privacy - * default: eui64 + * values: IPV6_ADDR_GEN_MODE: default, default-or-eui64, eui64, stable-privacy + * default: "default-or-eui64" * description: Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217). * example: IPV6_ADDR_GEN_MODE=stable-privacy * ---end--- @@ -799,10 +829,11 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) PROP_ADDR_GEN_MODE, G_MININT32, G_MAXINT32, - NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT, NM_SETTING_PARAM_NONE, NMSettingIP6ConfigPrivate, - addr_gen_mode); + addr_gen_mode, + .to_dbus_including_default = TRUE); /** * NMSettingIP6Config:token: @@ -857,6 +888,27 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) ra_timeout); /** + * NMSettingIP6Config:mtu: + * + * Maximum transmission unit size, in bytes. If zero (the default), the MTU + * is set automatically from router advertisements or is left equal to the + * link-layer MTU. If greater than the link-layer MTU, or greater than zero + * but less than the minimum IPv6 MTU of 1280, this value has no effect. + * + * Since: 1.40 + **/ + _nm_setting_property_define_direct_uint32(properties_override, + obj_properties, + NM_SETTING_IP6_CONFIG_MTU, + PROP_MTU, + 0, + G_MAXUINT32, + 0, + NM_SETTING_PARAM_FUZZY_IGNORE, + NMSettingIP6ConfigPrivate, + mtu); + + /** * NMSettingIP6Config:dhcp-duid: * * A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp @@ -936,7 +988,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * 'address-data' and 'gateway'. * * Array of IPv6 address structures. Each IPv6 address structure is - * composed of an IPv6 address, a prefix length (1 - 128), and an IPv6 + * composed of an IPv6 address, a prefix length (0 - 128), and an IPv6 * gateway address. The gateway may be zeroed out if no gateway exists for * that subnet. * ---end--- @@ -984,7 +1036,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * you send this property the daemon will ignore 'route-data'. * * Array of IPv6 route structures. Each IPv6 route structure is - * composed of an IPv6 address, a prefix length (1 - 128), an IPv6 + * composed of an IPv6 address, a prefix length (0 - 128), an IPv6 * next hop address (which may be zeroed out if there is no next hop), * and a metric. If the metric is 0, NM will choose an appropriate * default metric for the device. @@ -1003,6 +1055,9 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * Various attributes are supported: * <itemizedlist> * <listitem> + * <para><literal>"advmss"</literal> - an unsigned 32 bit integer.</para> + * </listitem> + * <listitem> * <para><literal>"cwnd"</literal> - an unsigned 32 bit integer.</para> * </listitem> * <listitem> @@ -1015,6 +1070,9 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * <para><literal>"initrwnd"</literal> - an unsigned 32 bit integer.</para> * </listitem> * <listitem> + * <para><literal>"lock-advmss"</literal> - a boolean value.</para> + * </listitem> + * <listitem> * <para><literal>"lock-cwnd"</literal> - a boolean value.</para> * </listitem> * <listitem> @@ -1036,6 +1094,13 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * <para><literal>"onlink"</literal> - a boolean value.</para> * </listitem> * <listitem> + * <para><literal>"quickack"</literal> - a boolean value.</para> + * </listitem> + * <listitem> + * <para><literal>"rto_min"</literal> - an unsigned 32 bit integer. + * The value is in milliseconds.</para> + * </listitem> + * <listitem> * <para><literal>"src"</literal> - an IPv6 address.</para> * </listitem> * <listitem> diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index d713b6a5..ad0f01d5 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -2488,7 +2488,10 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass) * * Leaving this at the default will enable this option automatically * if ipv4.never-default is not set and there are any peers that use - * a default-route as allowed-ips. + * a default-route as allowed-ips. Since this automatism only makes + * sense if you also have a peer with an /0 allowed-ips, it is usually + * not necessary to enable this explicitly. However, you can disable + * it if you want to configure your own routing and rules. * * Since: 1.20 **/ diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c index 68cc0e13..cf391598 100644 --- a/src/libnm-core-impl/nm-setting-wireless.c +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -825,10 +825,10 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) { NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE(setting); const char *valid_modes[] = {NM_SETTING_WIRELESS_MODE_INFRA, - NM_SETTING_WIRELESS_MODE_ADHOC, - NM_SETTING_WIRELESS_MODE_AP, - NM_SETTING_WIRELESS_MODE_MESH, - NULL}; + NM_SETTING_WIRELESS_MODE_ADHOC, + NM_SETTING_WIRELESS_MODE_AP, + NM_SETTING_WIRELESS_MODE_MESH, + NULL}; const char *valid_bands[] = {"a", "bg", NULL}; guint i; gsize length; @@ -1409,6 +1409,10 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) * point. This capability is highly driver dependent and not supported by * all devices. Note: this property does not control the BSSID used when * creating an Ad-Hoc network and is unlikely to in the future. + * + * Locking a client profile to a certain BSSID will prevent roaming and also + * disable background scanning. That can be useful, if there is only one access + * point for the SSID. **/ /* ---ifcfg-rh--- * property: bssid diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c index 2f62f6c6..6d87f50b 100644 --- a/src/libnm-core-impl/nm-team-utils.c +++ b/src/libnm-core-impl/nm-team-utils.c @@ -2148,11 +2148,11 @@ nm_team_setting_config_set(NMTeamSetting *self, const char *js_str) else { gboolean unrecognized_content = FALSE; bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { - FALSE, + FALSE, }; NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM]; nm_json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { - NULL, + NULL, }; gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL; gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL; diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index d5d884f2..3c4cbc65 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -23,7 +23,6 @@ #include "libnm-glib-aux/nm-enum-utils.h" #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-glib-aux/nm-secret-utils.h" -#include "libnm-systemd-shared/nm-sd-utils-shared.h" #include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-utils-private.h" #include "nm-setting-private.h" @@ -1559,29 +1558,33 @@ nm_utils_ip4_routes_from_variant(GVariant *value) /** * nm_utils_ip4_netmask_to_prefix: - * @netmask: an IPv4 netmask in network byte order + * @netmask: an IPv4 netmask in network byte order. + * Usually the netmask has all leading bits up to the prefix + * set so that the netmask is identical to having the first + * prefix bits of the address set. + * If that is not the case and there are "holes" in the + * mask, the prefix is determined based on the lowest bit + * set. * * Returns: the CIDR prefix represented by the netmask **/ guint32 nm_utils_ip4_netmask_to_prefix(guint32 netmask) { - G_STATIC_ASSERT_EXPR(__SIZEOF_INT__ == 4); - G_STATIC_ASSERT_EXPR(sizeof(int) == 4); - G_STATIC_ASSERT_EXPR(sizeof(netmask) == 4); - - return ((netmask != 0u) ? (guint32) (32 - __builtin_ctz(ntohl(netmask))) : 0u); + return _nm_utils_ip4_netmask_to_prefix(netmask); } /** * nm_utils_ip4_prefix_to_netmask: - * @prefix: a CIDR prefix + * @prefix: a CIDR prefix, must be not larger than 32. * * Returns: the netmask represented by the prefix, in network byte order **/ guint32 nm_utils_ip4_prefix_to_netmask(guint32 prefix) { + g_return_val_if_fail(prefix <= 32, 0xffffffffu); + return _nm_utils_ip4_prefix_to_netmask(prefix); } @@ -5356,7 +5359,7 @@ nm_utils_base64secret_decode(const char *base64_key, gsize required_key_len, gui base64_key_len = strlen(base64_key); - r = nm_sd_utils_unbase64mem(base64_key, base64_key_len, TRUE, &bin_arr, &bin_len); + r = nm_unbase64mem_full(base64_key, base64_key_len, TRUE, &bin_arr, &bin_len); if (r < 0) return FALSE; if (bin_len != required_key_len) { diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index 1856f6ad..3c8cd3ba 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -1338,6 +1338,7 @@ typedef struct { static int _c_list_sort_cmp(const CList *lst_a, const CList *lst_b, const void *user_data) { + const int MODFIER = user_data ? GPOINTER_TO_INT(user_data) : 0; const CListSort *a, *b; g_assert(lst_a); @@ -1351,9 +1352,36 @@ _c_list_sort_cmp(const CList *lst_a, const CList *lst_b, const void *user_data) return -1; if (a->val > b->val) return 1; + + switch (MODFIER) { + case 0: + break; + case 1: + NM_CMP_DIRECT_PTR(a, b); + g_assert_not_reached(); + break; + case 2: + NM_CMP_DIRECT_PTR(b, a); + g_assert_not_reached(); + break; + default: + g_assert_not_reached(); + break; + } + return 0; } +static int +_c_list_sort_cmp_inverse(const CList *lst_a, const CList *lst_b, const void *user_data) +{ + int c; + + c = _c_list_sort_cmp(lst_b, lst_a, user_data); + g_assert(NM_IN_SET(c, -1, 0, 1)); + return c; +} + static void _do_test_c_list_sort(CListSort *elements, guint n_list, gboolean headless) { @@ -1411,8 +1439,9 @@ static void test_c_list_sort(void) { const guint N_ELEMENTS = 10000; - guint n_list, repeat; - gs_free CListSort *elements = NULL; + gs_free CListSort *elements = NULL; + guint n_list; + guint repeat; { CList head; @@ -1441,6 +1470,97 @@ test_c_list_sort(void) /*****************************************************************************/ +static void +_do_test_c_list_insert_sorted(CListSort *elements, guint n_list, bool append_equal) +{ + CList head; + guint i; + const CListSort *el_prev; + CListSort *el; + + c_list_init(&head); + for (i = 0; i < n_list; i++) { + el = &elements[i]; + el->val = nmtst_get_rand_uint32() % (2 * n_list); + + if (nmtst_get_rand_bool()) { + c_list_insert_sorted(&head, &el->lst, TRUE, append_equal, _c_list_sort_cmp, NULL); + } else { + c_list_insert_sorted(&head, + &el->lst, + FALSE, + append_equal, + _c_list_sort_cmp_inverse, + NULL); + } + + if (nmtst_get_rand_one_case_in(20)) { + nm_assert(c_list_is_sorted(&head, TRUE, _c_list_sort_cmp, NULL)); + if (append_equal) { + nm_assert(c_list_is_sorted(&head, TRUE, _c_list_sort_cmp, GINT_TO_POINTER(1))); + } else { + nm_assert(c_list_is_sorted(&head, TRUE, _c_list_sort_cmp, GINT_TO_POINTER(2))); + } + nm_assert(c_list_is_sorted(&head, FALSE, _c_list_sort_cmp_inverse, NULL)); + if (append_equal) { + nm_assert( + c_list_is_sorted(&head, FALSE, _c_list_sort_cmp_inverse, GINT_TO_POINTER(1))); + } else { + nm_assert( + c_list_is_sorted(&head, FALSE, _c_list_sort_cmp_inverse, GINT_TO_POINTER(2))); + } + } + } + + g_assert_cmpint(c_list_length(&head), ==, n_list); + g_assert(!c_list_length_is(&head, n_list - 1)); + g_assert(c_list_length_is(&head, n_list)); + g_assert(!c_list_length_is(&head, n_list + 1)); + + el_prev = NULL; + c_list_for_each_entry (el, &head, lst) { + if (el_prev) { + int c; + + c = _c_list_sort_cmp(&el_prev->lst, &el->lst, NULL); + g_assert_cmpint(c, <=, 0); + if (c == 0) { + if (append_equal) + g_assert(&el_prev->lst < &el->lst); + else + g_assert(&el_prev->lst > &el->lst); + } + } + el_prev = el; + } +} + +static void +test_c_list_insert_sorted(void) +{ + const guint N_ELEMENTS = 1000; + gs_free CListSort *elements = NULL; + guint n_list; + guint repeat; + + elements = g_new0(CListSort, N_ELEMENTS); + for (n_list = 1; n_list < N_ELEMENTS; n_list++) { + if (n_list > 150) { + n_list += nmtst_get_rand_uint32() % n_list; + if (n_list >= N_ELEMENTS) + break; + } + { + const guint N_REPEAT = n_list > 50 ? 1 : 5; + + for (repeat = 0; repeat < N_REPEAT; repeat++) + _do_test_c_list_insert_sorted(elements, n_list, nmtst_get_rand_bool()); + } + } +} + +/*****************************************************************************/ + typedef struct { NMDedupMultiObj parent; guint val; @@ -2381,12 +2501,18 @@ test_setting_ip_route_attributes(void) TEST_ATTR("tos", byte, 127, AF_INET, TRUE, TRUE); TEST_ATTR("tos", string, "0x28", AF_INET, FALSE, TRUE); + TEST_ATTR("advmss", uint32, 1400, AF_INET, TRUE, TRUE); + TEST_ATTR("advmss", string, "1400", AF_INET, FALSE, TRUE); + TEST_ATTR("cwnd", uint32, 10, AF_INET, TRUE, TRUE); TEST_ATTR("cwnd", string, "11", AF_INET, FALSE, TRUE); TEST_ATTR("lock-mtu", boolean, TRUE, AF_INET, TRUE, TRUE); TEST_ATTR("lock-mtu", uint32, 1, AF_INET, FALSE, TRUE); + TEST_ATTR("lock-advmss", boolean, TRUE, AF_INET, TRUE, TRUE); + TEST_ATTR("lock-advmss", boolean, TRUE, AF_INET6, TRUE, TRUE); + TEST_ATTR("from", string, "fd01::1", AF_INET6, TRUE, TRUE); TEST_ATTR("from", string, "fd01::1/64", AF_INET6, TRUE, TRUE); TEST_ATTR("from", string, "fd01::1/128", AF_INET6, TRUE, TRUE); @@ -2396,6 +2522,12 @@ test_setting_ip_route_attributes(void) TEST_ATTR("from", string, "1.2.3.4", AF_INET, FALSE, TRUE); TEST_ATTR("from", string, "1.2.3.4", AF_INET6, FALSE, TRUE); + TEST_ATTR("quickack", boolean, TRUE, AF_INET, TRUE, TRUE); + TEST_ATTR("quickack", boolean, TRUE, AF_INET6, TRUE, TRUE); + + TEST_ATTR("rto_min", uint32, 1000, AF_INET, TRUE, TRUE); + TEST_ATTR("rto_min", uint32, 1000, AF_INET6, TRUE, TRUE); + TEST_ATTR("src", string, "1.2.3.4", AF_INET, TRUE, TRUE); TEST_ATTR("src", string, "1.2.3.4", AF_INET6, FALSE, TRUE); TEST_ATTR("src", string, "1.2.3.0/24", AF_INET, FALSE, TRUE); @@ -3822,8 +3954,10 @@ test_connection_diff_a_only(void) {NM_SETTING_CONNECTION_MDNS, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_LLMNR, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_DNS_OVER_TLS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_MPTCP_FLAGS, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_MUD_URL, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, NM_SETTING_DIFF_RESULT_IN_A}, {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}}}, {NM_SETTING_WIRED_SETTING_NAME, { @@ -3872,6 +4006,7 @@ test_connection_diff_a_only(void) {NM_SETTING_IP_CONFIG_DHCP_IAID, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_LINK_LOCAL, NM_SETTING_DIFF_RESULT_IN_A}, {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, }}, }; @@ -3914,11 +4049,11 @@ test_connection_diff_different(void) NMSettingIPConfig *s_ip4; gboolean same; const DiffSetting settings[] = { - {NM_SETTING_IP4_CONFIG_SETTING_NAME, - { - {NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B}, - {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + {NM_SETTING_IP4_CONFIG_SETTING_NAME, + { + {NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, }}, }; @@ -3999,10 +4134,10 @@ test_connection_diff_inferrable(void) NMSettingIPConfig *s_ip4; char *uuid; const DiffSetting settings[] = { - {NM_SETTING_CONNECTION_SETTING_NAME, - { - {NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A}, - {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, + {NM_SETTING_CONNECTION_SETTING_NAME, + { + {NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, }}, }; @@ -4923,7 +5058,7 @@ _netmask_to_prefix(guint32 netmask) /* we re-implemented the netmask-to-prefix code differently. Check * that they agree. */ - g_assert_cmpint(prefix, ==, nm_utils_ip4_netmask_to_prefix(netmask)); + g_assert_cmpint(prefix, ==, _nm_utils_ip4_netmask_to_prefix(netmask)); return prefix; } @@ -6722,53 +6857,53 @@ test_setting_ip6_gateway(void) GVariant *gateway_var; GVariantBuilder addrs_builder; guint8 addr_bytes_0[] = {0xab, - 0xcd, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0a}; + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0a}; guint8 addr_bytes_1[] = {0xab, - 0xcd, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0b}; + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0b}; guint8 gateway_bytes_1[] = {0xab, - 0xcd, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01}; + 0xcd, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01}; GError *error = NULL; /* When serializing on the daemon side, ipv6.gateway is copied to the first @@ -10824,6 +10959,7 @@ main(int argc, char **argv) g_test_add_func("/core/general/test_nm_hash", test_nm_hash); g_test_add_func("/core/general/test_nm_g_slice_free_fcn", test_nm_g_slice_free_fcn); g_test_add_func("/core/general/test_c_list_sort", test_c_list_sort); + g_test_add_func("/core/general/test_c_list_insert_sorted", test_c_list_insert_sorted); g_test_add_func("/core/general/test_dedup_multi", test_dedup_multi); g_test_add_func("/core/general/test_utils_str_utf8safe", test_utils_str_utf8safe); g_test_add_func("/core/general/test_nm_strsplit_set", test_nm_strsplit_set); diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 788f218d..5bdae716 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -3596,7 +3596,7 @@ test_roundtrip_conversion(gconstpointer test_data) "method=auto\n" "\n" "[ipv6]\n" - "addr-gen-mode=stable-privacy\n" + "addr-gen-mode=default\n" "method=auto\n" "\n" "[proxy]\n" @@ -3623,7 +3623,7 @@ test_roundtrip_conversion(gconstpointer test_data) "method=auto\n" "\n" "[ipv6]\n" - "addr-gen-mode=stable-privacy\n" + "addr-gen-mode=default\n" "method=auto\n" "", ID, @@ -3660,7 +3660,7 @@ test_roundtrip_conversion(gconstpointer test_data) "method=disabled\n" "\n" "[ipv6]\n" - "addr-gen-mode=stable-privacy\n" + "addr-gen-mode=default\n" "method=disabled\n" "\n" "[proxy]\n" @@ -3714,7 +3714,7 @@ test_roundtrip_conversion(gconstpointer test_data) "method=disabled\n" "\n" "[ipv6]\n" - "addr-gen-mode=stable-privacy\n" + "addr-gen-mode=default\n" "method=disabled\n" "\n" "[proxy]\n" @@ -3795,7 +3795,7 @@ test_roundtrip_conversion(gconstpointer test_data) "routing-rule3=priority 3 from 192.168.2.0/26 table 1002\n" "\n" "[ipv6]\n" - "addr-gen-mode=stable-privacy\n" + "addr-gen-mode=default\n" "method=auto\n" "routing-rule1=priority 1 from ::/0 table 1000\n" "routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n" |