diff options
author | Dan Winship <danw@gnome.org> | 2014-10-21 08:33:18 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2014-11-07 07:49:40 -0500 |
commit | d16905df633ceea08c93b6e982f660627d06ff34 (patch) | |
tree | 2578344aa6e4fcbfb0191c85880fbdc8d5845a0e /libnm-core | |
parent | f17699f4e3dacb9358a8503c8b15efe3cb852b48 (diff) | |
download | NetworkManager-d16905df633ceea08c93b6e982f660627d06ff34.tar.gz |
libnm-core, libnm, core: add AddressData and RouteData properties
Add AddressData and RouteData properties to NMSettingIPConfig and
NMIP[46]Config. These are like the existing "addresses" and "routes"
properties, but using strings and containing additional attributes,
like NMIPAddress and NMIPRoute.
This only affects the D-Bus representations; there are no API changes
to NMSettingIP{,4,6}Config or NMIP{4,6}Config as a result of this; the
additional information is just added to the existing 'addresses' and
'routes' properties.
NMSettingIP4Config and NMSettingIP6Config now always generate both
old-style data ('addresses', 'address-labels', 'routes') and new-style
data ('address-data', 'gateway', 'route-data') when serializing to
D-Bus, for backward compatibility. When deserializing, they will fill
in the 'addresses' and 'routes' properties from the new-style data if
it is present (ignoring the old-style data), or from the old-style
data if the new-style isn't present.
The daemon-side NMIP4Config and NMIP6Config always emit changes for
both 'Addresses'/'Routes' and 'AddressData'/'RouteData'. The
libnm-side classes initially listen for changes on both properties,
but start ignoring the 'Addresses' and 'Routes' properties once they
know the daemon is also providing 'AddressData' and 'RouteData'.
Diffstat (limited to 'libnm-core')
-rw-r--r-- | libnm-core/nm-setting-ip-config.c | 3 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip4-config.c | 122 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip6-config.c | 121 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 239 | ||||
-rw-r--r-- | libnm-core/nm-utils.h | 7 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 70 |
6 files changed, 530 insertions, 32 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 0ed612cd06..30e7b267c8 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -472,6 +472,7 @@ nm_ip_address_set_attribute (NMIPAddress *address, const char *name, GVariant *v { g_return_if_fail (address != NULL); g_return_if_fail (name != NULL && *name != '\0'); + g_return_if_fail (strcmp (name, "address") != 0 && strcmp (name, "prefix") != 0); if (!address->attributes) { address->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -1009,6 +1010,8 @@ nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value) { g_return_if_fail (route != NULL); g_return_if_fail (name != NULL && *name != '\0'); + g_return_if_fail ( strcmp (name, "dest") != 0 && strcmp (name, "prefix") != 0 + && strcmp (name, "next-hop") != 0 && strcmp (name, "metric") != 0); if (!route->attributes) { route->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 66f2ea997e..9eab49d7f5 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -269,9 +269,14 @@ ip4_addresses_set (NMSetting *setting, char **labels, *gateway = NULL; int i; - addrs = nm_utils_ip4_addresses_from_variant (value, &gateway); - s_ip4 = g_variant_lookup_value (connection_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + /* If 'address-data' is set then ignore 'addresses' */ + if (g_variant_lookup (s_ip4, "address-data", "aa{sv}", NULL)) { + g_variant_unref (s_ip4); + return; + } + + addrs = nm_utils_ip4_addresses_from_variant (value, &gateway); if (g_variant_lookup (s_ip4, "address-labels", "^as", &labels)) { for (i = 0; i < addrs->len && labels[i]; i++) @@ -319,16 +324,95 @@ ip4_address_labels_get (NMSetting *setting, } static GVariant * -ip4_routes_to_dbus (const GValue *prop_value) +ip4_address_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *addrs; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + ret = nm_utils_ip_addresses_to_variant (addrs); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip4_address_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref (addrs); +} + +static GVariant * +ip4_routes_get (NMSetting *setting, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, property, &routes, NULL); + ret = nm_utils_ip4_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip4_routes_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + GVariant *s_ip4; + + s_ip4 = g_variant_lookup_value (connection_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + /* If 'route-data' is set then ignore 'routes' */ + if (g_variant_lookup (s_ip4, "route-data", "aa{sv}", NULL)) { + g_variant_unref (s_ip4); + return; + } + g_variant_unref (s_ip4); + + routes = nm_utils_ip4_routes_from_variant (value); + g_object_set (setting, property, routes, NULL); + g_ptr_array_unref (routes); +} + +static GVariant * +ip4_route_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) { - return nm_utils_ip4_routes_to_variant (g_value_get_boxed (prop_value)); + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + ret = nm_utils_ip_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; } static void -ip4_routes_from_dbus (GVariant *dbus_value, - GValue *prop_value) +ip4_route_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) { - g_value_take_boxed (prop_value, nm_utils_ip4_routes_from_variant (dbus_value)); + GPtrArray *routes; + + routes = nm_utils_ip_routes_from_variant (value, AF_INET); + g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref (routes); } @@ -381,9 +465,23 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *ip4_class) ip4_address_labels_get, NULL); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_IP_CONFIG_ROUTES, - G_VARIANT_TYPE ("aau"), - ip4_routes_to_dbus, - ip4_routes_from_dbus); + _nm_setting_class_add_dbus_only_property (setting_class, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_address_data_get, + ip4_address_data_set); + + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ROUTES, + G_VARIANT_TYPE ("aau"), + ip4_routes_get, + ip4_routes_set, + NULL); + + _nm_setting_class_add_dbus_only_property (setting_class, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip4_route_data_get, + ip4_route_data_set); + } diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 9e3001157e..6e3ff6164e 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -214,9 +214,14 @@ ip6_addresses_set (NMSetting *setting, GVariant *s_ip6; char *gateway = NULL; - addrs = nm_utils_ip6_addresses_from_variant (value, &gateway); - s_ip6 = g_variant_lookup_value (connection_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + /* If 'address-data' is set then ignore 'addresses' */ + if (g_variant_lookup (s_ip6, "address-data", "aa{sv}", NULL)) { + g_variant_unref (s_ip6); + return; + } + + addrs = nm_utils_ip6_addresses_from_variant (value, &gateway); if (gateway && !g_variant_lookup (s_ip6, "gateway", "s", NULL)) { g_object_set (setting, @@ -232,16 +237,95 @@ ip6_addresses_set (NMSetting *setting, } static GVariant * -ip6_routes_to_dbus (const GValue *prop_value) +ip6_address_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) +{ + GPtrArray *addrs; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL); + ret = nm_utils_ip_addresses_to_variant (addrs); + g_ptr_array_unref (addrs); + + return ret; +} + +static void +ip6_address_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *addrs; + + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET6); + g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL); + g_ptr_array_unref (addrs); +} + +static GVariant * +ip6_routes_get (NMSetting *setting, + const char *property) +{ + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, property, &routes, NULL); + ret = nm_utils_ip6_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; +} + +static void +ip6_routes_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) +{ + GPtrArray *routes; + GVariant *s_ip6; + + s_ip6 = g_variant_lookup_value (connection_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); + /* If 'route-data' is set then ignore 'routes' */ + if (g_variant_lookup (s_ip6, "route-data", "aa{sv}", NULL)) { + g_variant_unref (s_ip6); + return; + } + g_variant_unref (s_ip6); + + routes = nm_utils_ip6_routes_from_variant (value); + g_object_set (setting, property, routes, NULL); + g_ptr_array_unref (routes); +} + +static GVariant * +ip6_route_data_get (NMSetting *setting, + NMConnection *connection, + const char *property) { - return nm_utils_ip6_routes_to_variant (g_value_get_boxed (prop_value)); + GPtrArray *routes; + GVariant *ret; + + g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL); + ret = nm_utils_ip_routes_to_variant (routes); + g_ptr_array_unref (routes); + + return ret; } static void -ip6_routes_from_dbus (GVariant *dbus_value, - GValue *prop_value) +ip6_route_data_set (NMSetting *setting, + GVariant *connection_dict, + const char *property, + GVariant *value) { - g_value_take_boxed (prop_value, nm_utils_ip6_routes_from_variant (dbus_value)); + GPtrArray *routes; + + routes = nm_utils_ip_routes_from_variant (value, AF_INET6); + g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL); + g_ptr_array_unref (routes); } static void @@ -324,9 +408,22 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) ip6_addresses_set, NULL); - _nm_setting_class_transform_property (setting_class, - NM_SETTING_IP_CONFIG_ROUTES, - G_VARIANT_TYPE ("a(ayuayu)"), - ip6_routes_to_dbus, - ip6_routes_from_dbus); + _nm_setting_class_add_dbus_only_property (setting_class, + "address-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_address_data_get, + ip6_address_data_set); + + _nm_setting_class_override_property (setting_class, + NM_SETTING_IP_CONFIG_ROUTES, + G_VARIANT_TYPE ("a(ayuayu)"), + ip6_routes_get, + ip6_routes_set, + NULL); + + _nm_setting_class_add_dbus_only_property (setting_class, + "route-data", + G_VARIANT_TYPE ("aa{sv}"), + ip6_route_data_get, + ip6_route_data_set); } diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 62698eefc8..f8105da810 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -1712,6 +1712,245 @@ nm_utils_ip6_routes_from_variant (GVariant *value) } /** + * nm_utils_ip_addresses_to_variant: + * @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects + * + * Utility function to convert a #GPtrArray of #NMIPAddress objects representing + * IPv4 or IPv6 addresses into a #GVariant of type 'aa{sv}' representing an + * array of new-style NetworkManager IP addresses. All addresses will include + * "address" (an IP address string), and "prefix" (a uint). Some addresses may + * include additional attributes. + * + * Returns: (transfer none): a new floating #GVariant representing @addresses. + **/ +GVariant * +nm_utils_ip_addresses_to_variant (GPtrArray *addresses) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIPAddress *addr = addresses->pdata[i]; + GVariantBuilder addr_builder; + char **names; + int n; + + g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&addr_builder, "{sv}", + "address", + g_variant_new_string (nm_ip_address_get_address (addr))); + g_variant_builder_add (&addr_builder, "{sv}", + "prefix", + g_variant_new_uint32 (nm_ip_address_get_prefix (addr))); + + names = nm_ip_address_get_attribute_names (addr); + for (n = 0; names[n]; n++) { + g_variant_builder_add (&addr_builder, "{sv}", + names[n], + nm_ip_address_get_attribute (addr, names[n])); + } + g_strfreev (names); + + g_variant_builder_add (&builder, "a{sv}", &addr_builder); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip_addresses_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (as described in the documentation for + * nm_utils_ip_addresses_to_variant()) into a #GPtrArray of #NMIPAddress + * objects. + * + * Returns: (transfer full) (element-type NMIPAddress): a newly allocated + * #GPtrArray of #NMIPAddress objects + **/ +GPtrArray * +nm_utils_ip_addresses_from_variant (GVariant *value, + int family) +{ + GPtrArray *addresses; + GVariantIter iter, attrs_iter; + GVariant *addr_var; + const char *ip; + guint32 prefix; + const char *attr_name; + GVariant *attr_val; + NMIPAddress *addr; + GError *error = NULL; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL); + + g_variant_iter_init (&iter, value); + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + + while (g_variant_iter_next (&iter, "@a{sv}", &addr_var)) { + if ( !g_variant_lookup (addr_var, "address", "&s", &ip) + || !g_variant_lookup (addr_var, "prefix", "u", &prefix)) { + g_warning ("Ignoring invalid address"); + g_variant_unref (addr_var); + continue; + } + + addr = nm_ip_address_new (family, ip, prefix, &error); + if (!addr) { + g_warning ("Ignoring invalid address: %s", error->message); + g_clear_error (&error); + g_variant_unref (addr_var); + continue; + } + + g_variant_iter_init (&attrs_iter, addr_var); + while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if ( strcmp (attr_name, "address") != 0 + && strcmp (attr_name, "prefix") != 0) + nm_ip_address_set_attribute (addr, attr_name, attr_val); + g_variant_unref (attr_val); + } + + g_ptr_array_add (addresses, addr); + } + + return addresses; +} + +/** + * nm_utils_ip_routes_to_variant: + * @routes: (element-type NMIPRoute): an array of #NMIPRoute objects + * + * Utility function to convert a #GPtrArray of #NMIPRoute objects representing + * IPv4 or IPv6 routes into a #GVariant of type 'aa{sv}' representing an array + * of new-style NetworkManager IP routes (which are tuples of destination, + * prefix, next hop, metric, and additional attributes). + * + * Returns: (transfer none): a new floating #GVariant representing @routes. + **/ +GVariant * +nm_utils_ip_routes_to_variant (GPtrArray *routes) +{ + GVariantBuilder builder; + int i; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIPRoute *route = routes->pdata[i]; + GVariantBuilder route_builder; + char **names; + int n; + + g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&route_builder, "{sv}", + "dest", + g_variant_new_string (nm_ip_route_get_dest (route))); + g_variant_builder_add (&route_builder, "{sv}", + "prefix", + g_variant_new_uint32 (nm_ip_route_get_prefix (route))); + if (nm_ip_route_get_next_hop (route)) { + g_variant_builder_add (&route_builder, "{sv}", + "next-hop", + g_variant_new_string (nm_ip_route_get_next_hop (route))); + } + if (nm_ip_route_get_metric (route)) { + g_variant_builder_add (&route_builder, "{sv}", + "metric", + g_variant_new_uint32 (nm_ip_route_get_metric (route))); + } + + names = nm_ip_route_get_attribute_names (route); + for (n = 0; names[n]; n++) { + g_variant_builder_add (&route_builder, "{sv}", + names[n], + nm_ip_route_get_attribute (route, names[n])); + } + g_strfreev (names); + + g_variant_builder_add (&builder, "a{sv}", &route_builder); + } + } + + return g_variant_builder_end (&builder); +} + +/** + * nm_utils_ip_routes_from_variant: + * @value: a #GVariant of type 'aa{sv}' + * @family: an IP address family + * + * Utility function to convert a #GVariant representing a list of new-style + * NetworkManager IPv4 or IPv6 addresses (which are tuples of destination, + * prefix, next hop, metric, and additional attributes) into a #GPtrArray of + * #NMIPRoute objects. + * + * Returns: (transfer full) (element-type NMIPRoute): a newly allocated + * #GPtrArray of #NMIPRoute objects + **/ +GPtrArray * +nm_utils_ip_routes_from_variant (GVariant *value, + int family) +{ + GPtrArray *routes; + GVariantIter iter, attrs_iter; + GVariant *route_var; + const char *dest, *next_hop; + guint32 prefix, metric; + const char *attr_name; + GVariant *attr_val; + NMIPRoute *route; + GError *error = NULL; + + g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL); + + g_variant_iter_init (&iter, value); + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + + while (g_variant_iter_next (&iter, "@a{sv}", &route_var)) { + if ( !g_variant_lookup (route_var, "dest", "&s", &dest) + || !g_variant_lookup (route_var, "prefix", "u", &prefix)) { + g_warning ("Ignoring invalid address"); + g_variant_unref (route_var); + continue; + } + if (!g_variant_lookup (route_var, "next-hop", "&s", &next_hop)) + next_hop = NULL; + if (!g_variant_lookup (route_var, "metric", "u", &metric)) + metric = 0; + + route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &error); + if (!route) { + g_warning ("Ignoring invalid route: %s", error->message); + g_clear_error (&error); + g_variant_unref (route_var); + continue; + } + + g_variant_iter_init (&attrs_iter, route_var); + while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_val)) { + if ( strcmp (attr_name, "dest") != 0 + && strcmp (attr_name, "prefix") != 0 + && strcmp (attr_name, "next-hop") != 0 + && strcmp (attr_name, "metric") != 0) + nm_ip_route_set_attribute (route, attr_name, attr_val); + g_variant_unref (attr_val); + } + + g_ptr_array_add (routes, route); + } + + return routes; +} + +/** * nm_utils_uuid_generate: * * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h index 628fa0f5a6..25f09c45ea 100644 --- a/libnm-core/nm-utils.h +++ b/libnm-core/nm-utils.h @@ -117,6 +117,13 @@ GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value, GVariant *nm_utils_ip6_routes_to_variant (GPtrArray *routes); GPtrArray *nm_utils_ip6_routes_from_variant (GVariant *value); +GVariant *nm_utils_ip_addresses_to_variant (GPtrArray *addresses); +GPtrArray *nm_utils_ip_addresses_from_variant (GVariant *value, + int family); +GVariant *nm_utils_ip_routes_to_variant (GPtrArray *routes); +GPtrArray *nm_utils_ip_routes_from_variant (GVariant *value, + int family); + char *nm_utils_uuid_generate (void); char *nm_utils_uuid_generate_from_string (const char *s); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index d66a9c9f6e..1bab4e011c 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -329,7 +329,7 @@ test_setting_ip4_config_labels (void) GPtrArray *addrs; char **labels; NMConnection *conn; - GVariant *dict, *setting_dict, *value; + GVariant *dict, *dict2, *setting_dict, *value; GError *error = NULL; s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); @@ -395,7 +395,9 @@ test_setting_ip4_config_labels (void) label = nm_ip_address_get_attribute (addr, "label"); g_assert (label == NULL); - /* The labels should appear in the D-Bus serialization */ + /* The labels should appear in the D-Bus serialization under both + * 'address-labels' and 'address-data'. + */ conn = nmtst_create_minimal_connection ("label test", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); nm_connection_add_setting (conn, NM_SETTING (s_ip4)); dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL); @@ -403,19 +405,41 @@ test_setting_ip4_config_labels (void) setting_dict = g_variant_lookup_value (dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING); g_assert (setting_dict != NULL); + value = g_variant_lookup_value (setting_dict, "address-labels", G_VARIANT_TYPE_STRING_ARRAY); g_assert (value != NULL); - g_variant_get (value, "^as", &labels); g_assert_cmpint (g_strv_length (labels), ==, 2); g_assert_cmpstr (labels[0], ==, "eth0:1"); g_assert_cmpstr (labels[1], ==, ""); - - g_variant_unref (setting_dict); g_variant_unref (value); g_strfreev (labels); - /* And should be deserialized */ + value = g_variant_lookup_value (setting_dict, "address-data", G_VARIANT_TYPE ("aa{sv}")); + addrs = nm_utils_ip_addresses_from_variant (value, AF_INET); + g_variant_unref (value); + g_assert (addrs != NULL); + g_assert_cmpint (addrs->len, ==, 2); + addr = addrs->pdata[0]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label != NULL); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + addr = addrs->pdata[1]; + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + g_ptr_array_unref (addrs); + + g_variant_unref (setting_dict); + + /* We should be able to deserialize the labels from either 'address-labels' + * or 'address-data'. + */ + dict2 = g_variant_ref (dict); + + NMTST_VARIANT_EDITOR (dict, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); + ); conn = nm_simple_connection_new_from_dbus (dict, &error); g_assert_no_error (error); g_variant_unref (dict); @@ -433,6 +457,28 @@ test_setting_ip4_config_labels (void) label = nm_ip_address_get_attribute (addr, "label"); g_assert (label == NULL); + g_object_unref (conn); + + NMTST_VARIANT_EDITOR (dict2, + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-labels"); + ); + conn = nm_simple_connection_new_from_dbus (dict2, &error); + g_assert_no_error (error); + g_variant_unref (dict2); + + s_ip4 = nm_connection_get_setting_ip4_config (conn); + + addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "2.2.2.2"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1"); + + addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "3.3.3.3"); + label = nm_ip_address_get_attribute (addr, "label"); + g_assert (label == NULL); + /* Test explicit property assignment */ g_object_get (G_OBJECT (s_ip4), NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, @@ -3391,10 +3437,14 @@ test_setting_ip4_gateway (void) g_variant_unref (ip4_dict); - /* When deserializing, the first gateway in ipv4.addresses is copied to ipv4.gateway */ + /* When deserializing an old-style connection, the gateway from the first address + * is copied to :gateway. + */ NMTST_VARIANT_EDITOR (conn_dict, NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-data"); ); conn = nm_simple_connection_new_from_dbus (conn_dict, &error); @@ -3460,10 +3510,14 @@ test_setting_ip6_gateway (void) g_variant_unref (ip6_dict); - /* When deserializing, the first gateway in ipv4.addresses is copied to ipv4.gateway */ + /* When deserializing an old-style connection, the gateway from the first address + * is copied to :gateway. + */ NMTST_VARIANT_EDITOR (conn_dict, NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_GATEWAY); + NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME, + "address-data"); ); conn = nm_simple_connection_new_from_dbus (conn_dict, &error); |