diff options
author | Thomas Haller <thaller@redhat.com> | 2020-07-30 11:02:56 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-08-05 12:47:55 +0200 |
commit | 52c9504ef4a9e6a15d43704a9b130396249fc8b4 (patch) | |
tree | e97a05542a36b8270ee3d50639feea6c422d06a0 | |
parent | 3acddf9dc67bb858c1ccf33f3db53cd843ea1c99 (diff) | |
download | NetworkManager-52c9504ef4a9e6a15d43704a9b130396249fc8b4.tar.gz |
core: extract helper functions for creating address/route variant for D-Bus
This code will change, but in essence we will still need such a function
to convert a list of addresses/routes to D-Bus. Extract the code, so it
can be better reused and adjusted.
-rw-r--r-- | src/NetworkManagerUtils.c | 334 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 22 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 163 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 149 |
4 files changed, 397 insertions, 271 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 230ffcda53..a9910af3f0 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1365,4 +1365,338 @@ nm_utils_ip_route_attribute_to_platform (int addr_family, #undef GET_ATTR } +/*****************************************************************************/ + +static int +_addresses_sort_cmp_4 (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return nm_platform_ip4_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) a)), + NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) b))); +} + +static int +_addresses_sort_cmp_prop_6 (gconstpointer a, gconstpointer b, gpointer user_data) +{ + return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) a)), + NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) b)), + (((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); +} + +void +nm_utils_ip4_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry, + const NMPObject *best_default_route, + GVariant **out_address_data, + GVariant **out_addresses) +{ + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + GVariantBuilder builder_data; + GVariantBuilder builder_legacy; + guint i; + + if (out_address_data) + g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); + if (out_addresses) + g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau")); + + if (head_entry) { + gs_free const NMPObject **addresses = NULL; + guint naddr; + + addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr); + + nm_assert (addresses && naddr); + + g_qsort_with_data (addresses, + naddr, + sizeof (addresses[0]), + _addresses_sort_cmp_4, + NULL); + + /* Build address data variant */ + for (i = 0; i < naddr; i++) { + const NMPlatformIP4Address *address = NMP_OBJECT_CAST_IP4_ADDRESS (addresses[i]); + + if (out_address_data) { + GVariantBuilder addr_builder; + + g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&addr_builder, "{sv}", + "address", + g_variant_new_string (_nm_utils_inet4_ntop (address->address, addr_str))); + g_variant_builder_add (&addr_builder, "{sv}", + "prefix", + g_variant_new_uint32 (address->plen)); + if (address->peer_address != address->address) { + g_variant_builder_add (&addr_builder, "{sv}", + "peer", + g_variant_new_string (_nm_utils_inet4_ntop (address->peer_address, addr_str))); + } + + if (*address->label) { + g_variant_builder_add (&addr_builder, "{sv}", + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string (address->label)); + } + g_variant_builder_add (&builder_data, "a{sv}", &addr_builder); + } + + if (out_addresses) { + const guint32 dbus_addr[3] = { + address->address, + address->plen, + ( i == 0 + && best_default_route) + ? NMP_OBJECT_CAST_IP4_ROUTE (best_default_route)->gateway + : (guint32) 0, + }; + + g_variant_builder_add (&builder_legacy, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + dbus_addr, 3, sizeof (guint32))); + } + } + } + + NM_SET_OUT (out_address_data, g_variant_builder_end (&builder_data)); + NM_SET_OUT (out_addresses, g_variant_builder_end (&builder_legacy)); +} + +void +nm_utils_ip6_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry, + NMSettingIP6ConfigPrivacy ipv6_privacy, + const NMPObject *best_default_route, + GVariant **out_address_data, + GVariant **out_addresses) +{ + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + GVariantBuilder builder_data; + GVariantBuilder builder_legacy; + + if (out_address_data) + g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); + if (out_addresses) + g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuay)")); + + if (head_entry) { + gs_free const NMPObject **addresses = NULL; + guint naddr; + guint i; + + addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr); + + nm_assert (addresses && naddr); + + g_qsort_with_data (addresses, + naddr, + sizeof (addresses[0]), + _addresses_sort_cmp_prop_6, + GINT_TO_POINTER (ipv6_privacy)); + + for (i = 0; i < naddr; i++) { + const NMPlatformIP6Address *address = NMP_OBJECT_CAST_IP6_ADDRESS (addresses[i]); + + if (out_address_data) { + GVariantBuilder addr_builder; + g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&addr_builder, "{sv}", + "address", + g_variant_new_string (_nm_utils_inet6_ntop (&address->address, sbuf))); + g_variant_builder_add (&addr_builder, "{sv}", + "prefix", + g_variant_new_uint32 (address->plen)); + if ( !IN6_IS_ADDR_UNSPECIFIED (&address->peer_address) + && !IN6_ARE_ADDR_EQUAL (&address->peer_address, &address->address)) { + g_variant_builder_add (&addr_builder, "{sv}", + "peer", + g_variant_new_string (_nm_utils_inet6_ntop (&address->peer_address, sbuf))); + } + + g_variant_builder_add (&builder_data, "a{sv}", &addr_builder); + } + + if (out_addresses) { + g_variant_builder_add (&builder_legacy, "(@ayu@ay)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &address->address, 16, 1), + address->plen, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + ( i == 0 + && best_default_route) + ? &NMP_OBJECT_CAST_IP6_ROUTE (best_default_route)->gateway + : &in6addr_any, + 16, 1)); + } + } + } + + NM_SET_OUT (out_address_data, g_variant_builder_end (&builder_data)); + NM_SET_OUT (out_addresses, g_variant_builder_end (&builder_legacy)); +} + +static gboolean +_route_valid_4 (const NMPlatformIP4Route *r) +{ + return r + && r->plen <= 32 + && r->network == nm_utils_ip4_address_clear_host_address (r->network, r->plen); +} + +static gboolean +_route_valid_6 (const NMPlatformIP6Route *r) +{ + struct in6_addr n; + + return r + && r->plen <= 128 + && (memcmp (&r->network, + nm_utils_ip6_address_clear_host_address (&n, &r->network, r->plen), + sizeof (n)) == 0); +} + +void +nm_utils_ip4_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry, + GVariant **out_route_data, + GVariant **out_routes) +{ + NMDedupMultiIter iter; + const NMPlatformIP4Route *route; + GVariantBuilder builder_data; + GVariantBuilder builder_legacy; + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + + if (out_route_data) + g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); + if (out_routes) + g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau")); + + nm_dedup_multi_iter_init (&iter, head_entry); + while (nm_platform_dedup_multi_iter_next_ip4_route (&iter, &route)) { + GVariantBuilder route_builder; + + nm_assert (_route_valid_4 (route)); + + if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST)) + continue; + + if (out_route_data) { + g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&route_builder, "{sv}", + "dest", + g_variant_new_string (_nm_utils_inet4_ntop (route->network, addr_str))); + g_variant_builder_add (&route_builder, "{sv}", + "prefix", + g_variant_new_uint32 (route->plen)); + if (route->gateway) { + g_variant_builder_add (&route_builder, "{sv}", + "next-hop", + g_variant_new_string (_nm_utils_inet4_ntop (route->gateway, addr_str))); + } + g_variant_builder_add (&route_builder, "{sv}", + "metric", + g_variant_new_uint32 (route->metric)); + + if (!nm_platform_route_table_is_main (route->table_coerced)) { + g_variant_builder_add (&route_builder, "{sv}", + "table", + g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE))); + } + + g_variant_builder_add (&builder_data, "a{sv}", &route_builder); + } + + if (out_routes) { + /* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the + * plen is positive. Skip the default routes not to break older clients. */ + if ( nm_platform_route_table_is_main (route->table_coerced) + && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { + const guint32 dbus_route[4] = { + route->network, + route->plen, + route->gateway, + route->metric, + }; + + g_variant_builder_add (&builder_legacy, "@au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + dbus_route, 4, sizeof (guint32))); + } + } + } + + NM_SET_OUT (out_route_data, g_variant_builder_end (&builder_data)); + NM_SET_OUT (out_routes, g_variant_builder_end (&builder_legacy)); +} + +void +nm_utils_ip6_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry, + GVariant **out_route_data, + GVariant **out_routes) +{ + NMDedupMultiIter iter; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + const NMPlatformIP6Route *route; + GVariantBuilder builder_data; + GVariantBuilder builder_legacy; + + if (out_route_data) + g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); + if (out_routes) + g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuayu)")); + + nm_dedup_multi_iter_init (&iter, head_entry); + while (nm_platform_dedup_multi_iter_next_ip6_route (&iter, &route)) { + + nm_assert (_route_valid_6 (route)); + + if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST)) + continue; + + if (out_route_data) { + GVariantBuilder route_builder; + + g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&route_builder, "{sv}", + "dest", + g_variant_new_string (_nm_utils_inet6_ntop (&route->network, sbuf))); + g_variant_builder_add (&route_builder, "{sv}", + "prefix", + g_variant_new_uint32 (route->plen)); + if (!IN6_IS_ADDR_UNSPECIFIED (&route->gateway)) { + g_variant_builder_add (&route_builder, "{sv}", + "next-hop", + g_variant_new_string (_nm_utils_inet6_ntop (&route->gateway, sbuf))); + } + + g_variant_builder_add (&route_builder, "{sv}", + "metric", + g_variant_new_uint32 (route->metric)); + + if (!nm_platform_route_table_is_main (route->table_coerced)) { + g_variant_builder_add (&route_builder, "{sv}", + "table", + g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE))); + } + + g_variant_builder_add (&builder_data, "a{sv}", &route_builder); + } + + if (out_routes) { + /* legacy versions of nm_ip6_route_set_prefix() in libnm-util assert that the + * plen is positive. Skip the default routes not to break older clients. */ + if ( nm_platform_route_table_is_main (route->table_coerced) + && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { + g_variant_builder_add (&builder_legacy, "(@ayu@ayu)", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &route->network, 16, 1), + (guint32) route->plen, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &route->gateway, 16, 1), + (guint32) route->metric); + } + } + } + + NM_SET_OUT (out_route_data, g_variant_builder_end (&builder_data)); + NM_SET_OUT (out_routes, g_variant_builder_end (&builder_legacy)); +} diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index b0cb68e306..6159ca9d84 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -8,8 +8,9 @@ #define __NETWORKMANAGER_UTILS_H__ #include "nm-core-utils.h" - +#include "nm-glib-aux/nm-dedup-multi.h" #include "nm-setting-ip-config.h" +#include "nm-setting-ip6-config.h" #include "platform/nm-platform.h" /*****************************************************************************/ @@ -146,4 +147,23 @@ void nm_utils_ip_route_attribute_to_platform (int addr_family, NMPlatformIPRoute *r, guint32 route_table); +void nm_utils_ip4_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry, + const NMPObject *best_default_route, + GVariant **out_address_data, + GVariant **out_addresses); + +void nm_utils_ip6_addresses_to_dbus (const NMDedupMultiHeadEntry *head_entry, + NMSettingIP6ConfigPrivacy ipv6_privacy, + const NMPObject *best_default_route, + GVariant **out_address_data, + GVariant **out_addresses); + +void nm_utils_ip4_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry, + GVariant **out_route_data, + GVariant **out_routes); + +void nm_utils_ip6_routes_to_dbus (const NMDedupMultiHeadEntry *head_entry, + GVariant **out_route_data, + GVariant **out_routes); + #endif /* __NETWORKMANAGER_UTILS_H__ */ diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index a31b24c84f..794e74a74e 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -497,15 +497,6 @@ _notify_routes (NMIP4Config *self) /*****************************************************************************/ static int -_addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data) -{ - return nm_platform_ip4_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) a)), - NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) b))); -} - -/*****************************************************************************/ - -static int sort_captured_addresses (const CList *lst_a, const CList *lst_b, gconstpointer user_data) { const NMPlatformIP4Address *addr_a = NMP_OBJECT_CAST_IP4_ADDRESS (c_list_entry (lst_a, NMDedupMultiEntry, lst_entries)->obj); @@ -2952,12 +2943,9 @@ get_property (GObject *object, guint prop_id, { NMIP4Config *self = NM_IP4_CONFIG (object); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter ipconf_iter; - const NMPlatformIP4Route *route; - GVariantBuilder builder_data, builder_legacy; - guint i; char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + GVariantBuilder builder_data; + guint i; switch (prop_id) { case PROP_IFINDEX: @@ -2967,145 +2955,36 @@ get_property (GObject *object, guint prop_id, case PROP_ADDRESSES: nm_assert (!!priv->address_data_variant == !!priv->addresses_variant); - if (priv->address_data_variant) - goto out_addresses_cached; - - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); - g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau")); - - head_entry = nm_ip4_config_lookup_addresses (self); - if (head_entry) { - gs_free const NMPObject **addresses = NULL; - guint naddr; - - addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr); - nm_assert (addresses && naddr); - - g_qsort_with_data (addresses, - naddr, - sizeof (addresses[0]), - _addresses_sort_cmp, - NULL); - - /* Build address data variant */ - for (i = 0; i < naddr; i++) { - GVariantBuilder addr_builder; - const NMPlatformIP4Address *address = NMP_OBJECT_CAST_IP4_ADDRESS (addresses[i]); - - g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&addr_builder, "{sv}", - "address", - g_variant_new_string (_nm_utils_inet4_ntop (address->address, addr_str))); - g_variant_builder_add (&addr_builder, "{sv}", - "prefix", - g_variant_new_uint32 (address->plen)); - if (address->peer_address != address->address) { - g_variant_builder_add (&addr_builder, "{sv}", - "peer", - g_variant_new_string (_nm_utils_inet4_ntop (address->peer_address, addr_str))); - } - - if (*address->label) { - g_variant_builder_add (&addr_builder, "{sv}", - NM_IP_ADDRESS_ATTRIBUTE_LABEL, - g_variant_new_string (address->label)); - } - - g_variant_builder_add (&builder_data, "a{sv}", &addr_builder); - - { - const guint32 dbus_addr[3] = { - address->address, - address->plen, - ( i == 0 - && priv->best_default_route) - ? NMP_OBJECT_CAST_IP4_ROUTE (priv->best_default_route)->gateway - : (guint32) 0, - }; - - g_variant_builder_add (&builder_legacy, "@au", - g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, - dbus_addr, 3, sizeof (guint32))); - } - } + if (!priv->address_data_variant) { + nm_utils_ip4_addresses_to_dbus (nm_ip4_config_lookup_addresses (self), + priv->best_default_route, + &priv->address_data_variant, + &priv->addresses_variant); + g_variant_ref_sink (priv->address_data_variant); + g_variant_ref_sink (priv->addresses_variant); } - priv->address_data_variant = g_variant_ref_sink (g_variant_builder_end (&builder_data)); - priv->addresses_variant = g_variant_ref_sink (g_variant_builder_end (&builder_legacy)); - -out_addresses_cached: g_value_set_variant (value, - prop_id == PROP_ADDRESS_DATA ? - priv->address_data_variant : - priv->addresses_variant); + prop_id == PROP_ADDRESS_DATA + ? priv->address_data_variant + : priv->addresses_variant); break; case PROP_ROUTE_DATA: case PROP_ROUTES: nm_assert (!!priv->route_data_variant == !!priv->routes_variant); - if (priv->route_data_variant) - goto out_routes_cached; - - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); - g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("aau")); - - nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, self, &route) { - GVariantBuilder route_builder; - - nm_assert (_route_valid (route)); - - if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST)) - continue; - - g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&route_builder, "{sv}", - "dest", - g_variant_new_string (_nm_utils_inet4_ntop (route->network, addr_str))); - g_variant_builder_add (&route_builder, "{sv}", - "prefix", - g_variant_new_uint32 (route->plen)); - if (route->gateway) { - g_variant_builder_add (&route_builder, "{sv}", - "next-hop", - g_variant_new_string (_nm_utils_inet4_ntop (route->gateway, addr_str))); - } - g_variant_builder_add (&route_builder, "{sv}", - "metric", - g_variant_new_uint32 (route->metric)); - - if (!nm_platform_route_table_is_main (route->table_coerced)) { - g_variant_builder_add (&route_builder, "{sv}", - "table", - g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE))); - } - - g_variant_builder_add (&builder_data, "a{sv}", &route_builder); - - /* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the - * plen is positive. Skip the default routes not to break older clients. */ - if ( nm_platform_route_table_is_main (route->table_coerced) - && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { - const guint32 dbus_route[4] = { - route->network, - route->plen, - route->gateway, - route->metric, - }; - - g_variant_builder_add (&builder_legacy, "@au", - g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, - dbus_route, 4, sizeof (guint32))); - } + if (!priv->route_data_variant) { + nm_utils_ip4_routes_to_dbus (nm_ip4_config_lookup_routes (self), + &priv->route_data_variant, + &priv->routes_variant); + g_variant_ref_sink (priv->route_data_variant); + g_variant_ref_sink (priv->routes_variant); } - priv->route_data_variant = g_variant_ref_sink (g_variant_builder_end (&builder_data)); - priv->routes_variant = g_variant_ref_sink (g_variant_builder_end (&builder_legacy)); - -out_routes_cached: g_value_set_variant (value, - prop_id == PROP_ROUTE_DATA ? - priv->route_data_variant : - priv->routes_variant); + prop_id == PROP_ROUTE_DATA + ? priv->route_data_variant + : priv->routes_variant); break; case PROP_GATEWAY: if (priv->best_default_route) { diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index cf7aa59f0d..10b7305335 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -213,14 +213,6 @@ _notify_routes (NMIP6Config *self) /*****************************************************************************/ static int -_addresses_sort_cmp_prop (gconstpointer a, gconstpointer b, gpointer user_data) -{ - return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) a)), - NMP_OBJECT_CAST_IP6_ADDRESS (*((const NMPObject **) b)), - (((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT (user_data)) == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); -} - -static int sort_captured_addresses (const CList *lst_a, const CList *lst_b, gconstpointer user_data) { return nm_platform_ip6_address_pretty_sort_cmp (NMP_OBJECT_CAST_IP6_ADDRESS (c_list_entry (lst_a, NMDedupMultiEntry, lst_entries)->obj), @@ -2475,11 +2467,6 @@ get_property (GObject *object, guint prop_id, { NMIP6Config *self = NM_IP6_CONFIG (object); NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter ipconf_iter; - const NMPlatformIP6Route *route; - GVariantBuilder builder_data, builder_legacy; - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; switch (prop_id) { case PROP_IFINDEX: @@ -2489,131 +2476,37 @@ get_property (GObject *object, guint prop_id, case PROP_ADDRESSES: nm_assert (!!priv->address_data_variant == !!priv->addresses_variant); - if (priv->address_data_variant) - goto out_addresses_cached; - - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); - g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuay)")); - - head_entry = nm_ip6_config_lookup_addresses (self); - if (head_entry) { - gs_free const NMPObject **addresses = NULL; - guint naddr, i; - - addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr); - nm_assert (addresses && naddr); - - g_qsort_with_data (addresses, - naddr, - sizeof (addresses[0]), - _addresses_sort_cmp_prop, - GINT_TO_POINTER (priv->privacy)); - - for (i = 0; i < naddr; i++) { - GVariantBuilder addr_builder; - const NMPlatformIP6Address *address = NMP_OBJECT_CAST_IP6_ADDRESS (addresses[i]); - - g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&addr_builder, "{sv}", - "address", - g_variant_new_string (_nm_utils_inet6_ntop (&address->address, sbuf))); - g_variant_builder_add (&addr_builder, "{sv}", - "prefix", - g_variant_new_uint32 (address->plen)); - if ( !IN6_IS_ADDR_UNSPECIFIED (&address->peer_address) - && !IN6_ARE_ADDR_EQUAL (&address->peer_address, &address->address)) { - g_variant_builder_add (&addr_builder, "{sv}", - "peer", - g_variant_new_string (_nm_utils_inet6_ntop (&address->peer_address, sbuf))); - } - - g_variant_builder_add (&builder_data, "a{sv}", &addr_builder); - - g_variant_builder_add (&builder_legacy, "(@ayu@ay)", - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - &address->address, 16, 1), - address->plen, - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - ( i == 0 - && priv->best_default_route) - ? &NMP_OBJECT_CAST_IP6_ROUTE (priv->best_default_route)->gateway - : &in6addr_any, - 16, 1)); - } + if (!priv->address_data_variant) { + nm_utils_ip6_addresses_to_dbus (nm_ip6_config_lookup_addresses (self), + priv->privacy, + priv->best_default_route, + &priv->address_data_variant, + &priv->addresses_variant); + g_variant_ref_sink (priv->address_data_variant); + g_variant_ref_sink (priv->addresses_variant); } - - priv->address_data_variant = g_variant_ref_sink (g_variant_builder_end (&builder_data)); - priv->addresses_variant = g_variant_ref_sink (g_variant_builder_end (&builder_legacy)); -out_addresses_cached: g_value_set_variant (value, - prop_id == PROP_ADDRESS_DATA ? - priv->address_data_variant : - priv->addresses_variant); + prop_id == PROP_ADDRESS_DATA + ? priv->address_data_variant + : priv->addresses_variant); break; case PROP_ROUTE_DATA: case PROP_ROUTES: nm_assert (!!priv->route_data_variant == !!priv->routes_variant); - if (priv->route_data_variant) - goto out_routes_cached; - - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); - g_variant_builder_init (&builder_legacy, G_VARIANT_TYPE ("a(ayuayu)")); - - nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, self, &route) { - GVariantBuilder route_builder; - - nm_assert (_route_valid (route)); - - if (route->type_coerced != nm_platform_route_type_coerce (RTN_UNICAST)) - continue; - - g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&route_builder, "{sv}", - "dest", - g_variant_new_string (_nm_utils_inet6_ntop (&route->network, sbuf))); - g_variant_builder_add (&route_builder, "{sv}", - "prefix", - g_variant_new_uint32 (route->plen)); - if (!IN6_IS_ADDR_UNSPECIFIED (&route->gateway)) { - g_variant_builder_add (&route_builder, "{sv}", - "next-hop", - g_variant_new_string (_nm_utils_inet6_ntop (&route->gateway, sbuf))); - } - - g_variant_builder_add (&route_builder, "{sv}", - "metric", - g_variant_new_uint32 (route->metric)); - - if (!nm_platform_route_table_is_main (route->table_coerced)) { - g_variant_builder_add (&route_builder, "{sv}", - "table", - g_variant_new_uint32 (nm_platform_route_table_uncoerce (route->table_coerced, TRUE))); - } - - g_variant_builder_add (&builder_data, "a{sv}", &route_builder); - - /* legacy versions of nm_ip6_route_set_prefix() in libnm-util assert that the - * plen is positive. Skip the default routes not to break older clients. */ - if ( nm_platform_route_table_is_main (route->table_coerced) - && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { - g_variant_builder_add (&builder_legacy, "(@ayu@ayu)", - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - &route->network, 16, 1), - (guint32) route->plen, - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - &route->gateway, 16, 1), - (guint32) route->metric); - } + if (!priv->route_data_variant) { + nm_utils_ip6_routes_to_dbus (nm_ip6_config_lookup_routes (self), + &priv->route_data_variant, + &priv->routes_variant); + g_variant_ref_sink (priv->route_data_variant); + g_variant_ref_sink (priv->routes_variant); } - priv->route_data_variant = g_variant_ref_sink (g_variant_builder_end (&builder_data)); - priv->routes_variant = g_variant_ref_sink (g_variant_builder_end (&builder_legacy)); -out_routes_cached: + g_value_set_variant (value, - prop_id == PROP_ROUTE_DATA ? - priv->route_data_variant : - priv->routes_variant); + prop_id == PROP_ROUTE_DATA + ? priv->route_data_variant + : priv->routes_variant); break; case PROP_GATEWAY: if (priv->best_default_route) { |