diff options
Diffstat (limited to 'src/libnm-core-impl')
| -rw-r--r-- | src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in | 4 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-connection.c | 2 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-8021x.c | 9 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-bond.c | 16 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-connection.c | 5 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-geneve.c | 26 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip-config.c | 9 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip4-config.c | 90 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-ip6-config.c | 8 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-private.h | 3 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-setting-wireless.c | 23 | ||||
| -rw-r--r-- | src/libnm-core-impl/nm-utils.c | 267 | ||||
| -rw-r--r-- | src/libnm-core-impl/tests/test-general.c | 327 | ||||
| -rw-r--r-- | src/libnm-core-impl/tests/test-setting.c | 15 |
14 files changed, 642 insertions, 162 deletions
diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index 8d5d3bc9..7308db4d 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -1680,6 +1680,10 @@ dbus-type="i" gprop-type="NMTernary" /> + <property name="clat" + dbus-type="i" + gprop-type="gint" + /> <property name="dad-timeout" dbus-type="i" gprop-type="gint" diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 180fcbbc..9ce72b41 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -3535,7 +3535,7 @@ nm_connection_get_setting_generic(NMConnection *connection) * * Returns: (transfer none): an #NMSettingGeneve if the connection contains one, otherwise NULL * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ NMSettingGeneve * nm_connection_get_setting_geneve(NMConnection *connection) diff --git a/src/libnm-core-impl/nm-setting-8021x.c b/src/libnm-core-impl/nm-setting-8021x.c index f9333803..ac148efa 100644 --- a/src/libnm-core-impl/nm-setting-8021x.c +++ b/src/libnm-core-impl/nm-setting-8021x.c @@ -3133,6 +3133,12 @@ need_secrets(NMSetting *setting, gboolean check_rerequest) /*****************************************************************************/ +static NMSetting8021xCKScheme +_ck_scheme_path(NMSetting8021x *_sett) +{ + return NM_SETTING_802_1X_CK_SCHEME_PATH; +} + static void get_private_files(NMSetting *setting, GPtrArray *files) { @@ -3159,6 +3165,7 @@ get_private_files(NMSetting *setting, GPtrArray *files) {NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, nm_setting_802_1x_get_phase2_private_key_scheme, nm_setting_802_1x_get_phase2_private_key_path}, + {NM_SETTING_802_1X_PAC_FILE, _ck_scheme_path, nm_setting_802_1x_get_pac_file}, }; NMSetting8021x *s_8021x = NM_SETTING_802_1X(setting); const char *path; @@ -3390,7 +3397,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass) obj_properties, NM_SETTING_802_1X_PAC_FILE, PROP_PAC_FILE, - NM_SETTING_PARAM_NONE, + NM_SETTING_PARAM_CERT_KEY_FILE, NMSetting8021xPrivate, pac_file, .direct_string_allow_empty = TRUE); diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c index 7204df48..6e390159 100644 --- a/src/libnm-core-impl/nm-setting-bond.c +++ b/src/libnm-core-impl/nm-setting-bond.c @@ -197,7 +197,7 @@ static NM_UTILS_STRING_TABLE_LOOKUP_STRUCT_DEFINE( {"any", NM_BOND_OPTION_TYPE_BOTH, 0, 1, _option_default_strv_arp_all_targets}}, {NM_SETTING_BOND_OPTION_ARP_INTERVAL, {"0", NM_BOND_OPTION_TYPE_INT, 0, G_MAXINT}}, {NM_SETTING_BOND_OPTION_ARP_IP_TARGET, {"", NM_BOND_OPTION_TYPE_IP}}, - {NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, {"0", NM_BOND_OPTION_TYPE_INT, 0, 255}}, + {NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, {"2", NM_BOND_OPTION_TYPE_INT, 0, 255}}, {NM_SETTING_BOND_OPTION_ARP_VALIDATE, {"none", NM_BOND_OPTION_TYPE_BOTH, 0, 6, _option_default_strv_arp_validate}}, {NM_SETTING_BOND_OPTION_BALANCE_SLB, {"0", NM_BOND_OPTION_TYPE_INT, 0, 1}}, @@ -364,6 +364,10 @@ _bond_get_option_normalized(NMSettingBond *self, const char *option, gboolean ge /* balance-slb implies vlan+srcmac */ return "5"; } + } else if (nm_streq(option, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX)) { + value = _bond_get_option(self, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX) ?: "0"; + if (nm_streq(value, "0")) + value = _bond_get_option_default(self, option); } else value = _bond_get_option(self, option); @@ -894,13 +898,16 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) miimon = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_MIIMON)); arp_interval = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_ARP_INTERVAL)); - arp_missed_max = - _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX)); num_grat_arp = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP)); num_unsol_na = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_NUM_UNSOL_NA)); peer_notif_delay = _atoi(_bond_get_option_or_default(self, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY)); + /* "0" is an invalid value in the kernel, but we used to accept it to indicate "default value". + * Keep accepting "0" as a valid value, although we'll apply a different value, actually. + * Bond modes that don't accept arp_missed_max must just ignore the "0" value, too. */ + arp_missed_max = _atoi(_bond_get_option(self, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX) ?: "0"); + /* Option restrictions: * * arp_interval conflicts [ alb, tlb ] @@ -950,6 +957,9 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS); return FALSE; } + } + + if (NM_IN_SET(bond_mode, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB, NM_BOND_MODE_8023AD)) { if (arp_missed_max > 0) { g_set_error(error, NM_CONNECTION_ERROR, diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index 0ad97846..96dff146 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -3328,9 +3328,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) * * The number of retries for the authentication. Zero means to try indefinitely; -1 means * to use a global default. If the global default is not set, the authentication - * retries for 3 times before failing the connection. - * - * Currently, this only applies to 802-1x authentication. + * retries for 3 times before failing the connection. Connections using a pre-shared key + * to authenticate will only prompt for a new key during the last authentication attempt. * * Since: 1.10 **/ diff --git a/src/libnm-core-impl/nm-setting-geneve.c b/src/libnm-core-impl/nm-setting-geneve.c index b01fcd9a..d6426a06 100644 --- a/src/libnm-core-impl/nm-setting-geneve.c +++ b/src/libnm-core-impl/nm-setting-geneve.c @@ -65,7 +65,7 @@ G_DEFINE_TYPE(NMSettingGeneve, nm_setting_geneve, NM_TYPE_SETTING) * * Returns: the #NMSettingGeneve:id property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ guint nm_setting_geneve_get_id(NMSettingGeneve *setting) @@ -81,7 +81,7 @@ nm_setting_geneve_get_id(NMSettingGeneve *setting) * * Returns: the #NMSettingGeneve:remote property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ const char * nm_setting_geneve_get_remote(NMSettingGeneve *setting) @@ -97,7 +97,7 @@ nm_setting_geneve_get_remote(NMSettingGeneve *setting) * * Returns: the #NMSettingGeneve:destination-port property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ guint nm_setting_geneve_get_destination_port(NMSettingGeneve *setting) @@ -113,7 +113,7 @@ nm_setting_geneve_get_destination_port(NMSettingGeneve *setting) * * Returns: the #NMSettingGeneve:tos property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ guint nm_setting_geneve_get_tos(NMSettingGeneve *setting) @@ -129,7 +129,7 @@ nm_setting_geneve_get_tos(NMSettingGeneve *setting) * * Returns: the #NMSettingGeneve:ttl property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ guint nm_setting_geneve_get_ttl(NMSettingGeneve *setting) @@ -145,7 +145,7 @@ nm_setting_geneve_get_ttl(NMSettingGeneve *setting) * * Returns: the #NMSettingGeneve:df property of the setting * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ NMSettingGeneveDf nm_setting_geneve_get_df(NMSettingGeneve *setting) @@ -206,7 +206,7 @@ nm_setting_geneve_init(NMSettingGeneve *self) * * Returns: (transfer full): the new empty #NMSettingGeneve object * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ NMSetting * nm_setting_geneve_new(void) @@ -232,7 +232,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * Specifies the GENEVE Network Identifier (or GENEVE Segment Identifier) to * use. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_uint32(properties_override, obj_properties, @@ -251,7 +251,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * Specifies the unicast destination IP address to use in outgoing packets * when communicating with the remote GENEVE tunnel endpoint. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_string(properties_override, obj_properties, @@ -270,7 +270,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * Specifies the UDP destination port to communicate to the remote GENEVE * tunnel endpoint. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_uint32(properties_override, obj_properties, @@ -289,7 +289,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * Specifies the TOS value to use in outgoing packets. * The special value "inherit" (1) means inherit from outer packet. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_uint32(properties_override, obj_properties, @@ -308,7 +308,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * Specifies the time-to-live value to use in outgoing packets. * The special value "inherit" (-1) means inherit from outer packet, 0 means auto, 1-255 are fixed values. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_int32(properties_override, obj_properties, @@ -331,7 +331,7 @@ nm_setting_geneve_class_init(NMSettingGeneveClass *klass) * %NM_SETTING_GENEVE_DF_SET (1): Always set the DF flag, packets will not be fragmented. * %NM_SETTING_GENEVE_DF_INHERIT (2): Inherit the DF flag from the inner IP header. * - * Since: 1.58, 1.56.1 + * Since: 1.58 **/ _nm_setting_property_define_direct_enum(properties_override, obj_properties, diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index f4ee094c..cee35159 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -1401,7 +1401,7 @@ _ip_route_attribute_validate(const char *name, NM_CONNECTION_ERROR_FAILED, family == AF_INET ? _("'%s' is not a valid IPv4 address") : _("'%s' is not a valid IPv6 address"), - string); + addr); return FALSE; } break; @@ -6960,7 +6960,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * activation will fail. The property is currently implemented only for IPv4. * * A zero value means that no duplicate address detection is performed, -1 means - * the default value (either the value configured globally in NetworkManger.conf + * the default value (either the value configured globally in NetworkManager.conf * or 200ms). A value greater than zero is a timeout in milliseconds. Note that * the time intervals are subject to randomization as per RFC 5227 and so the * actual duration can be between half and the full time specified in this @@ -7006,7 +7006,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * This property is useful for example if both IPv4 and IPv6 are enabled and * are allowed to fail. Normally the connection succeeds as soon as one of * the two address families completes; by setting a required timeout for - * e.g. IPv4, one can ensure that even if IP6 succeeds earlier than IPv4, + * e.g. IPv4, one can ensure that even if IPv6 succeeds earlier than IPv4, * NetworkManager waits some time for IPv4 before the connection becomes * active. * @@ -7050,8 +7050,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) * values "duid" and "ipv6-duid" to generate the client-id. * * For DHCPv6, note that at the moment this property is - * only supported by the "internal" DHCPv6 plugin. The "dhclient" DHCPv6 - * plugin always derives the IAID from the MAC address. + * only supported by the "internal" DHCPv6 plugin. * * The actually used DHCPv6 IAID for a currently activated interface is * exposed in the lease information of the device. diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index a4fccc6d..2eea98f6 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -40,7 +40,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DHCP_CLIENT_ID, PROP_DHCP_FQDN, PROP_DHCP_VENDOR_CLASS_IDENTIFIER, PROP_LINK_LOCAL, - PROP_DHCP_IPV6_ONLY_PREFERRED, ); + PROP_DHCP_IPV6_ONLY_PREFERRED, + PROP_CLAT, ); typedef struct { NMSettingIPConfigPrivate parent; @@ -50,6 +51,7 @@ typedef struct { char *dhcp_vendor_class_identifier; gint32 link_local; gint32 dhcp_ipv6_only_preferred; + gint32 clat; } NMSettingIP4ConfigPrivate; /** @@ -168,6 +170,24 @@ nm_setting_ip4_config_get_dhcp_ipv6_only_preferred(NMSettingIP4Config *setting) return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_ipv6_only_preferred; } +/** + * nm_setting_ip4_config_get_clat: + * @setting: the #NMSettingIP4Config + * + * Returns the value in the #NMSettingIP4Config:clat property. + * + * Returns: the CLAT property value + * + * Since: 1.58 + */ +NMSettingIp4ConfigClat +nm_setting_ip4_config_get_clat(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), NM_SETTING_IP4_CONFIG_CLAT_DEFAULT); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->clat; +} + static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { @@ -186,12 +206,15 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) if (!strcmp(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { if (nm_setting_ip_config_get_num_addresses(s_ip) == 0 - && nm_setting_ip_config_get_num_routes(s_ip) == 0) { - g_set_error(error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("method '%s' requires at least an address or a route"), - method); + && nm_setting_ip_config_get_num_routes(s_ip) == 0 + && nm_setting_ip4_config_get_clat(NM_SETTING_IP4_CONFIG(s_ip)) + != NM_SETTING_IP4_CONFIG_CLAT_FORCE) { + g_set_error( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("method '%s' requires at least an address, a route, or CLAT set to 'force'"), + method); g_prefix_error(error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, @@ -930,10 +953,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * this is normally not recommended. * * If unset, a globally configured default from NetworkManager.conf is - * used. If still unset, the default depends on the DHCP plugin. The - * internal dhcp client will default to "mac" and the dhclient plugin will - * try to use one from its config file if present, or won't sent any - * client-id otherwise. + * used. If still unset, internal dhcp client will default to "mac". **/ /* ---nmcli--- * property: dhcp-client-id @@ -1259,7 +1279,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * won't get merged. If the route finds no merge partner, it is * configured as single hop route.</para> <para>Note that in * NetworkManager, currently all nexthops of a ECMP route must share - * the same "onlink" flag in order to be mergable.</para> + * the same "onlink" flag in order to be mergeable.</para> * </listitem> * <listitem> * <para><literal>"window"</literal> - an unsigned 32 bit integer.</para> @@ -1353,18 +1373,25 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) /** * NMSettingIP4Config:dhcp-ipv6-only-preferred * - * Controls the "IPv6-Only Preferred" DHCPv4 option (RFC 8925). + * Controls the "IPv6-Only Preferred" DHCPv4 option (option 108 - RFC 8925). * * When set to %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_YES, the host adds the * option to the parameter request list; if the DHCP server sends the option back, * the host stops the DHCP client for the time interval specified in the option. * * Enable this feature if the host supports an IPv6-only mode, i.e. either all - * applications are IPv6-only capable or there is a form of 464XLAT deployed. + * applications are IPv6-only capable or there is a form of CLAT (464XLAT) + * deployed. + * + * If set to %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_AUTO, the option is + * automatically turned on when the IPv6 method is "auto" and the connection + * profile has ipv4.clat set to "yes" or "auto". If these two conditions are + * met, the host can operate in IPv6-only mode and therefore it is safe to + * disable DHCPv4 when the network also supports it. * * When set to %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT, the actual value * is looked up in the global configuration; if not specified, it defaults to - * %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO. + * %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_AUTO. * * If the connection has IPv6 method set to "disabled", this property does not * have effect and the "IPv6-Only Preferred" option is always disabled. @@ -1382,6 +1409,39 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) NMSettingIP4ConfigPrivate, dhcp_ipv6_only_preferred); + /** + * NMSettingIP4Config:clat + * + * Controls the CLAT (Customer-side translator) functionality. CLAT is used to implement the + * client part of 464XLAT (RFC 6877), an architecture that provides IPv4 connectivity to hosts + * on IPv6-only networks. + * + * When CLAT is enabled, NetworkManager discovers the NAT64 prefix from IPv6 Router Advertisements; + * if a NAT64 prefix is announced, NetworkManager installs a BPF program to perform the stateless + * translation of packets between IPv4 and IPv6. + * + * Setting %NM_SETTING_IP4_CONFIG_CLAT_NO completely disables CLAT. %NM_SETTING_IP4_CONFIG_CLAT_AUTO + * enables CLAT only when the IPv4 method is 'auto' and the device doesn't have a native IPv4 gateway. + * %NM_SETTING_IP4_CONFIG_CLAT_FORCE enables CLAT even if the IPv4 method is not 'auto' and even if + * the device has a native IPv4 gateway. + * + * When set to %NM_SETTING_IP4_CONFIG_CLAT_DEFAULT, the actual value is looked up in the global + * configuration; if not specified it defaults to %NM_SETTING_IP4_CONFIG_CLAT_NO. In the future the + * default fall back value will change to %NM_SETTING_IP4_CONFIG_CLAT_AUTO. + * + * Since: 1.58 + */ + _nm_setting_property_define_direct_enum(properties_override, + obj_properties, + NM_SETTING_IP4_CONFIG_CLAT, + PROP_CLAT, + NM_TYPE_SETTING_IP4_CONFIG_CLAT, + NM_SETTING_IP4_CONFIG_CLAT_DEFAULT, + NM_SETTING_PARAM_NONE, + NULL, + NMSettingIP4ConfigPrivate, + clat); + 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-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index c68be991..25997f75 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -1265,11 +1265,9 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) * DUID and filled as an opaque value in the Client Identifier option. * * The special value "lease" will retrieve the DUID previously used from the - * lease file belonging to the connection. If no DUID is found and "dhclient" - * is the configured dhcp client, the DUID is searched in the system-wide - * dhclient lease file. If still no DUID is found, or another dhcp client is - * used, a global and permanent DUID-UUID (RFC 6355) will be generated based - * on the machine-id. + * lease file belonging to the connection. If no DUID is found, a global + * and permanent DUID-UUID (RFC 6355) will be generated based on the + * machine-id. * * The special values "llt" and "ll" will generate a DUID of type LLT or LL * (see RFC 3315) based on the current MAC address of the device. In order to diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index 61f96789..b3678d7c 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -809,7 +809,8 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p G_STATIC_ASSERT(!NM_FLAGS_ANY((param_flags), \ ~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_FUZZY_IGNORE \ | NM_SETTING_PARAM_INFERRABLE | NM_SETTING_PARAM_REQUIRED \ - | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \ + | NM_SETTING_PARAM_REAPPLY_IMMEDIATELY \ + | NM_SETTING_PARAM_CERT_KEY_FILE))); \ \ nm_assert(_property_type); \ nm_assert(g_variant_type_equal(_property_type->dbus_type, "s")); \ diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c index 1c5486bf..318e864b 100644 --- a/src/libnm-core-impl/nm-setting-wireless.c +++ b/src/libnm-core-impl/nm-setting-wireless.c @@ -1086,7 +1086,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_SETTING_WIRELESS_MODE_AP, NM_SETTING_WIRELESS_MODE_MESH, NULL}; - const char *valid_bands[] = {"a", "bg", NULL}; + const char *valid_bands[] = {"a", "bg", "6GHz", NULL}; guint i; gsize length; GError *local = NULL; @@ -1363,11 +1363,11 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } if (priv->channel_width == NM_SETTING_WIRELESS_CHANNEL_WIDTH_80MHZ - && !nm_streq0(priv->band, "a")) { + && !NM_IN_STRSET(priv->band, "a", "6GHz")) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("80MHz channels are only supported in the 5GHz band")); + _("80MHz channels are only supported in the 5GHz and 6GHz bands")); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, @@ -1636,17 +1636,18 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) /** * NMSettingWireless:band: * - * 802.11 frequency band of the network. One of "a" for 5GHz 802.11a or - * "bg" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network - * to the specific band, i.e. if "a" is specified, the device will not - * associate with the same network in the 2.4GHz band even if the network's - * settings are compatible. This setting depends on specific driver - * capability and may not work with all drivers. + * 802.11 frequency band of the network. One of "a" for 5GHz, + * "bg" for 2.4GHz or "6GHz". This will lock associations to the + * Wi-Fi network to the specific band, i.e. if "a" is specified, + * the device will not associate with the same network in the + * 2.4GHz (bg) or 6GHz bands even if the network's settings are + * compatible. This setting depends on specific driver capability + * and may not work with all drivers. **/ /* ---ifcfg-rh--- * property: band * variable: BAND(+) - * values: a, bg + * values: a, bg, 6GHz * description: BAND alone is honored, but CHANNEL overrides BAND since it * implies a band. * example: BAND=bg @@ -1673,8 +1674,6 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass) * property: channel * variable: CHANNEL * description: Channel used for the Wi-Fi communication. - * Channels greater than 14 mean "a" band, otherwise the - * band is "bg". * example: CHANNEL=6 * ---end--- */ diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 1bf00831..50862708 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -25,6 +25,7 @@ #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-glib-aux/nm-secret-utils.h" #include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "nm-utils-private.h" #include "nm-setting-private.h" #include "nm-setting-bond.h" @@ -3697,43 +3698,78 @@ struct cf_pair { guint32 freq; }; -static const struct cf_pair a_table[] = { - /* A band */ - {7, 5035}, {8, 5040}, {9, 5045}, {11, 5055}, {12, 5060}, {16, 5080}, {34, 5170}, - {36, 5180}, {38, 5190}, {40, 5200}, {42, 5210}, {44, 5220}, {46, 5230}, {48, 5240}, - {50, 5250}, {52, 5260}, {56, 5280}, {58, 5290}, {60, 5300}, {64, 5320}, {100, 5500}, - {104, 5520}, {108, 5540}, {112, 5560}, {116, 5580}, {120, 5600}, {124, 5620}, {128, 5640}, - {132, 5660}, {136, 5680}, {140, 5700}, {149, 5745}, {152, 5760}, {153, 5765}, {157, 5785}, - {160, 5800}, {161, 5805}, {165, 5825}, {183, 4915}, {184, 4920}, {185, 4925}, {187, 4935}, - {188, 4945}, {192, 4960}, {196, 4980}, {0, 0}}; - -static const guint a_table_freqs[G_N_ELEMENTS(a_table)] = { - /* A band */ - 5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, 5250, 5260, - 5280, 5290, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5745, - 5760, 5765, 5785, 5800, 5805, 5825, 4915, 4920, 4925, 4935, 4945, 4960, 4980, 0, -}; +static const struct cf_pair table_5ghz[] = { + /* Special, 20MHz only */ + {32, 5160}, + + /* UNII-1 (Indoor) */ + {36, 5180}, + {40, 5200}, + {44, 5220}, + {48, 5240}, + + /* UNII-2 (DFS) */ + {52, 5260}, + {56, 5280}, + {60, 5300}, + {64, 5320}, + + /* UNII-2C (DFS) */ + {100, 5500}, + {104, 5520}, + {108, 5540}, + {112, 5560}, + {116, 5580}, + {120, 5600}, + {124, 5620}, + {128, 5640}, + {132, 5660}, + {136, 5680}, + {140, 5700}, + {144, 5720}, + + /* UNII-3 */ + {149, 5745}, + {153, 5765}, + {157, 5785}, + {161, 5805}, + {165, 5825}, + + /* 4.9 GHz Public Safety Band (802.11y/j) */ + {183, 4915}, + {184, 4920}, + {185, 4925}, + {187, 4935}, + {188, 4940}, + {189, 4945}, + {192, 4960}, + {196, 4980}, -static const struct cf_pair bg_table[] = { - /* B/G band */ - {1, 2412}, - {2, 2417}, - {3, 2422}, - {4, 2427}, - {5, 2432}, - {6, 2437}, - {7, 2442}, - {8, 2447}, - {9, 2452}, - {10, 2457}, - {11, 2462}, - {12, 2467}, - {13, 2472}, - {14, 2484}, {0, 0}}; -static const guint bg_table_freqs[G_N_ELEMENTS(bg_table)] = { - /* B/G band */ +static const guint table_5ghz_freqs[G_N_ELEMENTS(table_5ghz)] = { + 5160, 5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, + 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700, 5720, 5745, 5765, 5785, + 5805, 5825, 4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980, 0, +}; + +static const struct cf_pair table_2ghz[] = {{1, 2412}, + {2, 2417}, + {3, 2422}, + {4, 2427}, + {5, 2432}, + {6, 2437}, + {7, 2442}, + {8, 2447}, + {9, 2452}, + {10, 2457}, + {11, 2462}, + {12, 2467}, + {13, 2472}, + {14, 2484}, + {0, 0}}; + +static const guint table_2ghz_freqs[G_N_ELEMENTS(table_2ghz)] = { 2412, 2417, 2422, @@ -3751,6 +3787,24 @@ static const guint bg_table_freqs[G_N_ELEMENTS(bg_table)] = { 0, }; +static const struct cf_pair table_6ghz[] = { + {1, 5955}, {5, 5975}, {9, 5995}, {13, 6015}, {17, 6035}, {21, 6055}, {25, 6075}, + {29, 6095}, {33, 6115}, {37, 6135}, {41, 6155}, {45, 6175}, {49, 6195}, {53, 6215}, + {57, 6235}, {61, 6255}, {65, 6275}, {69, 6295}, {73, 6315}, {77, 6335}, {81, 6355}, + {85, 6375}, {89, 6395}, {93, 6415}, {97, 6435}, {101, 6455}, {105, 6475}, {109, 6495}, + {113, 6515}, {117, 6535}, {121, 6555}, {125, 6575}, {129, 6595}, {133, 6615}, {137, 6635}, + {141, 6655}, {145, 6675}, {149, 6695}, {153, 6715}, {157, 6735}, {161, 6755}, {169, 6775}, + {173, 6815}, {177, 6835}, {181, 6855}, {185, 6875}, {189, 6895}, {193, 6915}, {197, 6935}, + {201, 6955}, {205, 6975}, {209, 6995}, {213, 7015}, {217, 7035}, {221, 7055}, {225, 7075}, + {229, 7095}, {233, 7115}, {0, 0}}; + +static const guint table_6ghz_freqs[G_N_ELEMENTS(table_6ghz)] = { + 5955, 5975, 5995, 6015, 6035, 6055, 6075, 6095, 6115, 6135, 6155, 6175, 6195, 6215, 6235, + 6255, 6275, 6295, 6315, 6335, 6355, 6375, 6395, 6415, 6435, 6455, 6475, 6495, 6515, 6535, + 6555, 6575, 6595, 6615, 6635, 6655, 6675, 6695, 6715, 6735, 6755, 6775, 6815, 6835, 6855, + 6875, 6895, 6915, 6935, 6955, 6975, 6995, 7015, 7035, 7055, 7075, 7095, 7115, 0, +}; + /** * nm_utils_wifi_freq_to_channel: * @freq: frequency @@ -3762,42 +3816,51 @@ static const guint bg_table_freqs[G_N_ELEMENTS(bg_table)] = { guint32 nm_utils_wifi_freq_to_channel(guint32 freq) { - int i = 0; + const struct cf_pair *table; + int i = 0; - if (freq > 4900) { - while (a_table[i].freq && (a_table[i].freq != freq)) - i++; - return a_table[i].chan; + if (freq >= _NM_WIFI_FREQ_MIN_6GHZ) { + table = table_6ghz; + } else if (freq >= _NM_WIFI_FREQ_MIN_5GHZ) { + table = table_5ghz; + } else { + table = table_2ghz; } - while (bg_table[i].freq && (bg_table[i].freq != freq)) + while (table[i].freq && (table[i].freq != freq)) i++; - return bg_table[i].chan; + + return table[i].chan; } /** * nm_utils_wifi_freq_to_band: * @freq: frequency * - * Utility function to translate a Wi-Fi frequency to its corresponding band. + * Translates a Wi-Fi frequency to its corresponding band. * - * Returns: the band containing the frequency or NULL if freq is invalid + * Returns: the band containing the frequency or %NM_WIFI_BAND_UNKNOWN if + * the frequency does not belong to a known band. + * + * Since: 1.58 **/ -const char * +NMWifiBand nm_utils_wifi_freq_to_band(guint32 freq) { - if (freq >= 4915 && freq <= 5825) - return "a"; - else if (freq >= 2412 && freq <= 2484) - return "bg"; + if (freq >= _NM_WIFI_FREQ_MIN_2GHZ && freq <= _NM_WIFI_FREQ_MAX_2GHZ) + return NM_WIFI_BAND_2_4_GHZ; + else if (freq >= _NM_WIFI_FREQ_MIN_5GHZ && freq <= _NM_WIFI_FREQ_MAX_5GHZ) + return NM_WIFI_BAND_5_GHZ; + else if (freq >= _NM_WIFI_FREQ_MIN_6GHZ && freq <= _NM_WIFI_FREQ_MAX_6GHZ) + return NM_WIFI_BAND_6_GHZ; - return NULL; + return NM_WIFI_BAND_UNKNOWN; } /** * nm_utils_wifi_channel_to_freq: * @channel: channel - * @band: frequency band for wireless ("a" or "bg") + * @band: frequency band for wireless ("a", "bg", "6GHz") * * Utility function to translate a Wi-Fi channel to its corresponding frequency. * @@ -3808,34 +3871,33 @@ nm_utils_wifi_freq_to_band(guint32 freq) guint32 nm_utils_wifi_channel_to_freq(guint32 channel, const char *band) { - int i; + const struct cf_pair *table; + int i; g_return_val_if_fail(band, 0); - if (nm_streq(band, "a")) { - for (i = 0; a_table[i].chan; i++) { - if (a_table[i].chan == channel) - return a_table[i].freq; - } - return ((guint32) -1); + if (nm_streq0(band, "a")) { + table = table_5ghz; + } else if (nm_streq0(band, "bg")) { + table = table_2ghz; + } else if (nm_streq0(band, "6GHz")) { + table = table_6ghz; + } else { + return 0; } - if (nm_streq(band, "bg")) { - for (i = 0; bg_table[i].chan; i++) { - if (bg_table[i].chan == channel) - return bg_table[i].freq; - } - return ((guint32) -1); + for (i = 0; table[i].chan; i++) { + if (table[i].chan == channel) + return table[i].freq; } - - return 0; + return ((guint32) -1); } /** * nm_utils_wifi_find_next_channel: * @channel: current channel * @direction: whether going downward (0 or less) or upward (1 or more) - * @band: frequency band for wireless ("a" or "bg") + * @band: frequency band for wireless ("a", "bg", "6GHz") * * Utility function to find out next/previous Wi-Fi channel for a channel. * @@ -3844,35 +3906,36 @@ nm_utils_wifi_channel_to_freq(guint32 channel, const char *band) guint32 nm_utils_wifi_find_next_channel(guint32 channel, int direction, char *band) { - size_t a_size = G_N_ELEMENTS(a_table); - size_t bg_size = G_N_ELEMENTS(bg_table); - const struct cf_pair *pair; - - if (nm_streq(band, "a")) { - if (channel < a_table[0].chan) - return a_table[0].chan; - if (channel > a_table[a_size - 2].chan) - return a_table[a_size - 2].chan; - pair = &a_table[0]; - } else if (nm_streq(band, "bg")) { - if (channel < bg_table[0].chan) - return bg_table[0].chan; - if (channel > bg_table[bg_size - 2].chan) - return bg_table[bg_size - 2].chan; - pair = &bg_table[0]; + const struct cf_pair *table; + guint table_size; + + if (nm_streq0(band, "a")) { + table = table_5ghz; + table_size = G_N_ELEMENTS(table_5ghz); + } else if (nm_streq0(band, "bg")) { + table = table_2ghz; + table_size = G_N_ELEMENTS(table_2ghz); + } else if (nm_streq0(band, "6GHz")) { + table = table_6ghz; + table_size = G_N_ELEMENTS(table_6ghz); } else g_return_val_if_reached(0); - while (pair->chan) { - if (channel == pair->chan) + if (channel < table[0].chan) + return table[0].chan; + if (channel > table[table_size - 2].chan) + return table[table_size - 2].chan; + + while (table->chan) { + if (channel == table->chan) return channel; - if ((channel < (pair + 1)->chan) && (channel > pair->chan)) { + if ((channel < (table + 1)->chan) && (channel > table->chan)) { if (direction > 0) - return (pair + 1)->chan; + return (table + 1)->chan; else - return pair->chan; + return table->chan; } - pair++; + table++; } return 0; } @@ -3880,7 +3943,7 @@ nm_utils_wifi_find_next_channel(guint32 channel, int direction, char *band) /** * nm_utils_wifi_is_channel_valid: * @channel: channel - * @band: frequency band for wireless ("a" or "bg") + * @band: frequency band for wireless ("a", "bg", "6GHz") * * Utility function to verify Wi-Fi channel validity. * @@ -3930,8 +3993,8 @@ nm_utils_wifi_is_channel_valid(guint32 channel, const char *band) const guint * nm_utils_wifi_2ghz_freqs(void) { - _nm_assert_wifi_freqs(bg_table, bg_table_freqs); - return bg_table_freqs; + _nm_assert_wifi_freqs(table_2ghz, table_2ghz_freqs); + return table_2ghz_freqs; } /** @@ -3946,8 +4009,24 @@ nm_utils_wifi_2ghz_freqs(void) const guint * nm_utils_wifi_5ghz_freqs(void) { - _nm_assert_wifi_freqs(a_table, a_table_freqs); - return a_table_freqs; + _nm_assert_wifi_freqs(table_5ghz, table_5ghz_freqs); + return table_5ghz_freqs; +} + +/** + * nm_utils_wifi_6ghz_freqs: + * + * Utility function to return 6 GHz Wi-Fi frequencies (802.11ax/be, Wi-Fi 6E). + * + * Returns: zero-terminated array of frequencies numbers (in MHz) + * + * Since: 1.58 + **/ +const guint * +nm_utils_wifi_6ghz_freqs(void) +{ + _nm_assert_wifi_freqs(table_6ghz, table_6ghz_freqs); + return table_6ghz_freqs; } /** @@ -6427,7 +6506,7 @@ nm_utils_copy_cert_as_user(const char *filename, const char *user, GError **erro nm_str_buf_destroy(&info.output_buffer); nm_str_buf_destroy(&info.error_buffer); - mkdir(RUN_CERT_DIR, 0600); + mkdir(RUN_CERT_DIR, 0700); fd = mkstemp(dst_path); if (fd < 0) { g_set_error_literal(error, diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index cd480045..1e2904a1 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -4094,6 +4094,7 @@ test_connection_diff_a_only(void) {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}, {NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_CLAT, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE, NM_SETTING_DIFF_RESULT_IN_A}, @@ -11140,7 +11141,7 @@ _do_wifi_ghz_freqs(const guint *freqs, const char *band) int j; int i; - g_assert(NM_IN_STRSET(band, "a", "bg")); + g_assert(NM_IN_STRSET(band, "a", "bg", "6GHz")); g_assert(freqs); g_assert(freqs[0] != 0); @@ -11178,6 +11179,7 @@ test_nm_utils_wifi_ghz_freqs(void) { _do_wifi_ghz_freqs(nm_utils_wifi_2ghz_freqs(), "bg"); _do_wifi_ghz_freqs(nm_utils_wifi_5ghz_freqs(), "a"); + _do_wifi_ghz_freqs(nm_utils_wifi_6ghz_freqs(), "6GHz"); } /*****************************************************************************/ @@ -11611,6 +11613,328 @@ test_dhcp_iaid_hexstr(void) /*****************************************************************************/ +static void +test_unreachable_gateways(void) +{ + NMConnection *conn; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + gs_free const char **result = NULL; + + /* IPv4 gateway reachable via address prefix route */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "192.168.1.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* IPv4 gateway NOT reachable */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "10.0.0.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_address(s_ip4, "172.16.1.1", 16); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 1); + g_assert_cmpstr(result[0], ==, "10.0.0.1"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* IPv4 gateway NOT reachable. It's ignored because of method "auto" */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_GATEWAY, + "10.0.0.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_address(s_ip4, "172.16.1.1", 16); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* Route gateway reachable via address prefix route */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_route(s_ip4, "10.0.0.0", 8, "192.168.1.254", 100); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* Route gateway NOT reachable, check sorting */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_route(s_ip4, "10.0.0.0", 16, "172.16.0.2", 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.1.0.0", 16, "172.16.0.4", 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.2.0.0", 16, "172.16.0.3", 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.3.0.0", 16, "172.16.0.1", 100); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 4); + g_assert_cmpstr(result[0], ==, "172.16.0.1"); + g_assert_cmpstr(result[1], ==, "172.16.0.2"); + g_assert_cmpstr(result[2], ==, "172.16.0.3"); + g_assert_cmpstr(result[3], ==, "172.16.0.4"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* Route gateway reachable via a direct route in the setting */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_route(s_ip4, "172.16.0.0", 16, NULL, 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.0.0.0", 8, "172.16.0.1", 100); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* No gateways */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* Both default gateway and route gateway unreachable */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "10.0.0.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_route(s_ip4, "10.0.0.0", 8, "172.16.0.1", 100); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 2); + g_assert_cmpstr(result[0], ==, "10.0.0.1"); + g_assert_cmpstr(result[1], ==, "172.16.0.1"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* Test deduplication */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "192.168.1.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_route(s_ip4, "10.0.0.0", 16, "172.16.0.1", 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.1.0.0", 16, "172.16.0.1", 100); + nmtst_setting_ip_config_add_route(s_ip4, "10.2.0.0", 16, "172.16.0.1", 100); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 1); + g_assert_cmpstr(result[0], ==, "172.16.0.1"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* IPv6 gateway reachable via address prefix route */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "fd01::1", + NULL); + nmtst_setting_ip_config_add_address(s_ip6, "fd01::10", 64); + nm_connection_add_setting(conn, NM_SETTING(s_ip6)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* IPv6 gateway NOT reachable */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "fd02::1", + NULL); + nmtst_setting_ip_config_add_address(s_ip6, "fd01::10", 64); + nm_connection_add_setting(conn, NM_SETTING(s_ip6)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 1); + g_assert_cmpstr(result[0], ==, "fd02::1"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* Multiple addresses, gateway reachable via second address */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "10.0.0.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nmtst_setting_ip_config_add_address(s_ip4, "10.0.0.5", 24); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } + + /* Unreachable gateways in both IPv4 and IPv6 */ + { + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "10.0.0.1", + NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, + "fd02::1", + NULL); + nmtst_setting_ip_config_add_address(s_ip6, "fd01::10", 64); + nm_connection_add_setting(conn, NM_SETTING(s_ip6)); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(result); + g_assert_cmpint(g_strv_length((char **) result), ==, 2); + g_assert_cmpstr(result[0], ==, "10.0.0.1"); + g_assert_cmpstr(result[1], ==, "fd02::1"); + nm_clear_g_free(&result); + g_object_unref(conn); + } + + /* Onlink and IPv6-link-local routes */ + { + NMIPRoute *route; + + conn = + nmtst_create_minimal_connection("test-ugw", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new(); + g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip4, "192.168.1.5", 24); + + route = nm_ip_route_new(AF_INET, "10.0.0.1", 8, "192.168.20.1", 100, NULL); + g_assert(route); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean(TRUE)); + g_assert(nm_setting_ip_config_add_route(s_ip4, route)); + nm_ip_route_unref(route); + + nm_connection_add_setting(conn, NM_SETTING(s_ip4)); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new(); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); + nmtst_setting_ip_config_add_address(s_ip6, "fd01::10", 64); + nm_connection_add_setting(conn, NM_SETTING(s_ip6)); + + route = nm_ip_route_new(AF_INET6, "fd02::", 64, "fd03::1111", 100, NULL); + g_assert(route); + nm_ip_route_set_attribute(route, NM_IP_ROUTE_ATTRIBUTE_ONLINK, g_variant_new_boolean(TRUE)); + g_assert(nm_setting_ip_config_add_route(s_ip6, route)); + nm_ip_route_unref(route); + + nmtst_setting_ip_config_add_route(s_ip6, "fd04::", 64, "fe80::1111", 100); + + result = nm_connection_get_unreachable_gateways(conn); + g_assert(!result); + g_object_unref(conn); + } +} + +/*****************************************************************************/ + NMTST_DEFINE(); int @@ -11961,6 +12285,7 @@ main(int argc, char **argv) g_test_add_func("/core/general/test_dns_uri_get_legacy", test_dns_uri_parse_plain); g_test_add_func("/core/general/test_dns_uri_normalize", test_dns_uri_normalize); g_test_add_func("/core/general/test_dhcp_iaid_hexstr", test_dhcp_iaid_hexstr); + g_test_add_func("/core/general/test_unreachable_gateways", test_unreachable_gateways); return g_test_run(); } diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index f3070c17..b9cafe4a 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4082,13 +4082,12 @@ test_roundtrip_conversion(gconstpointer test_data) if (flag == NM_CONNECTION_SERIALIZE_ALL) { s_wg2 = NM_SETTING_WIREGUARD( nm_connection_get_setting(con2, NM_TYPE_SETTING_WIREGUARD)); - - if (flag == NM_CONNECTION_SERIALIZE_ALL) - _rndt_wg_peers_assert_equal(s_wg2, wg_peers, TRUE, TRUE, FALSE); - else if (flag == NM_CONNECTION_SERIALIZE_WITH_NON_SECRET) - _rndt_wg_peers_assert_equal(s_wg2, wg_peers, FALSE, FALSE, TRUE); - else - g_assert_not_reached(); + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, TRUE, TRUE, FALSE); + } else if (flag == NM_CONNECTION_SERIALIZE_WITH_NON_SECRET) { + con2 = _connection_new_from_dbus_strict(con_var, FALSE); + s_wg2 = NM_SETTING_WIREGUARD( + nm_connection_get_setting(con2, NM_TYPE_SETTING_WIREGUARD)); + _rndt_wg_peers_assert_equal(s_wg2, wg_peers, FALSE, FALSE, TRUE); } break; } @@ -5533,7 +5532,7 @@ test_bond_meta(void) _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_ACTOR_SYS_PRIO, 0, EINVAL); _A(_nm_setting_bond_opt_value_as_u16, set, NM_SETTING_BOND_OPTION_AD_USER_PORT_KEY, 0, EINVAL); _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, 1, 0); - _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, 0, 0); + _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ARP_MISSED_MAX, 2, 0); _A(_nm_setting_bond_opt_value_as_u8, set, NM_SETTING_BOND_OPTION_ALL_SLAVES_ACTIVE, 0, 0); _A(_nm_setting_bond_opt_value_as_intbool, set, NM_SETTING_BOND_OPTION_USE_CARRIER, 1, 0); _A(_nm_setting_bond_opt_value_as_intbool, |