diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index 567cb73e52..83ef72a6de 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -5788,7 +5788,8 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) .to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct, .from_dbus_fcn = _nm_setting_property_from_dbus_fcn_direct_ip_config_gateway), .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, gateway), - .direct_set_string_ip_address_addr_family = addr_family + 1); + .direct_set_string_ip_address_addr_family = addr_family + 1, + .direct_set_string_ip_address_addr_family_map_zero_to_null = TRUE); _nm_properties_override_gobj( properties_override, @@ -5996,7 +5997,8 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps g_free(priv->gateway); priv->gateway = _nm_utils_ipaddr_canonical_or_invalid(NM_SETTING_IP_CONFIG_GET_FAMILY(setting), - g_value_get_string(value)); + g_value_get_string(value), + TRUE); break; case PROP_ROUTES: g_ptr_array_unref(priv->routes); diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index 2ae854c9df..db12ac0fb8 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -669,9 +669,11 @@ _property_direct_set_string(const NMSettInfoProperty *property_info, char **dst, if (property_info->direct_set_string_ip_address_addr_family != 0) { s = _nm_utils_ipaddr_canonical_or_invalid( property_info->direct_set_string_ip_address_addr_family - 1, - src); + src, + property_info->direct_set_string_ip_address_addr_family_map_zero_to_null); goto out_take; - } + } else + nm_assert(!property_info->direct_set_string_ip_address_addr_family_map_zero_to_null); if (NM_FLAGS_HAS(property_info->param_spec->flags, NM_SETTING_PARAM_SECRET)) return nm_strdup_reset_secret(dst, src); diff --git a/src/libnm-core-impl/nm-utils-private.h b/src/libnm-core-impl/nm-utils-private.h index e0107cfa68..1a6f29ef9b 100644 --- a/src/libnm-core-impl/nm-utils-private.h +++ b/src/libnm-core-impl/nm-utils-private.h @@ -44,7 +44,8 @@ void _nm_utils_bytes_from_dbus(GVariant *dbus_value, GValue *prop_value); char *_nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length); -char *_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip); +char * +_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip, gboolean map_zero_to_null); gboolean _nm_utils_hwaddr_link_local_valid(const char *mac); diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 451a8603c6..55b01c159b 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -3911,7 +3911,7 @@ _nm_utils_hwaddr_canonical_or_invalid(const char *mac, gssize length) } char * -_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip) +_nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip, gboolean map_zero_to_null) { NMIPAddr addr_bin; @@ -3923,7 +3923,7 @@ _nm_utils_ipaddr_canonical_or_invalid(int addr_family, const char *ip) if (!nm_utils_parse_inaddr_bin(addr_family, ip, &addr_family, &addr_bin)) return g_strdup(ip); - if (nm_ip_addr_is_null(addr_family, &addr_bin)) + if (map_zero_to_null && nm_ip_addr_is_null(addr_family, &addr_bin)) return NULL; return nm_utils_inet_ntop_dup(addr_family, &addr_bin); diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 8e804dadfa..8b3d7bd72a 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -4592,6 +4592,9 @@ test_setting_metadata(void) AF_INET + 1, AF_INET6 + 1)); + if (sip->direct_set_string_ip_address_addr_family == 0) + g_assert(!sip->direct_set_string_ip_address_addr_family_map_zero_to_null); + /* currently, we have no cases where special options are mixed. There is no problem to support * that, but as it's not needed, don't do it for now. */ g_assert_cmpint(n_special_options, <=, 1); diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 429dc2b84f..50590f12a3 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -768,11 +768,16 @@ struct _NMSettInfoProperty { guint8 direct_set_string_mac_address_len : 5; /* If non-zero, this is the addr-family (AF_UNSPEC/AF_INET/AF_INET6) for normalizing an IP - * address. Note that AF_UNSPEC is zero, so to differentiate between zero and AF_UNSPEC + * address with _nm_utils_ipaddr_canonical_or_invalid(). + * Note that AF_UNSPEC is zero, so to differentiate between zero and AF_UNSPEC * this value is actually the address family + 1. So either zero or AF_UNSPEC+1, AF_INET+1, * or AF_INET6+1. */ guint8 direct_set_string_ip_address_addr_family : 5; + /* Only makes sense together with direct_set_string_ip_address_addr_family. This flag + * is passed to _nm_utils_ipaddr_canonical_or_invalid(). */ + bool direct_set_string_ip_address_addr_family_map_zero_to_null : 1; + /* Usually, properties that are set to the default value for the GParamSpec * are not serialized to GVariant (and NULL is returned by to_dbus_data(). * Set this flag to force always converting the property even if the value