diff options
Diffstat (limited to 'src/nm-ip4-config.c')
| -rw-r--r-- | src/nm-ip4-config.c | 128 |
1 files changed, 64 insertions, 64 deletions
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index a4d43612..7b422359 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -55,6 +55,8 @@ typedef struct { gint64 route_metric; gboolean metered; gint dns_priority; + GVariant *address_data_variant; + GVariant *addresses_variant; } NMIP4ConfigPrivate; struct _NMIP4Config { @@ -207,8 +209,9 @@ _addresses_sort_cmp_get_prio (in_addr_t addr) static gint _addresses_sort_cmp (gconstpointer a, gconstpointer b) { - gint p1, p2, c; + gint p1, p2; const NMPlatformIP4Address *a1 = a, *a2 = b; + guint32 n1, n2; /* Sort by address type. For example link local will * be sorted *after* a global address. */ @@ -224,43 +227,30 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b) if ((a1->label[0] == '\0') != (a2->label[0] == '\0')) return (a1->label[0] == '\0') ? -1 : 1; - /* finally sort addresses lexically */ - c = memcmp (&a1->address, &a2->address, sizeof (a2->address)); - return c != 0 ? c : memcmp (a1, a2, sizeof (*a1)); -} - -gboolean -nm_ip4_config_addresses_sort (NMIP4Config *self) -{ - NMIP4ConfigPrivate *priv; - size_t data_len = 0; - char *data_pre = NULL; - gboolean changed; - - g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE); + /* Finally, sort addresses lexically. We compare only the + * network part so that the order of addresses in the same + * subnet (and thus also the primary/secondary role) is + * preserved. + */ + n1 = a1->address & nm_utils_ip4_prefix_to_netmask (a1->plen); + n2 = a2->address & nm_utils_ip4_prefix_to_netmask (a2->plen); - priv = NM_IP4_CONFIG_GET_PRIVATE (self); - if (priv->addresses->len > 1) { - data_len = priv->addresses->len * g_array_get_element_size (priv->addresses); - data_pre = g_new (char, data_len); - memcpy (data_pre, priv->addresses->data, data_len); + return memcmp (&n1, &n2, sizeof (guint32)); +} - g_array_sort (priv->addresses, _addresses_sort_cmp); +/*****************************************************************************/ - changed = memcmp (data_pre, priv->addresses->data, data_len) != 0; - g_free (data_pre); +static void +notify_addresses (NMIP4Config *self) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); - if (changed) { - _notify (self, PROP_ADDRESS_DATA); - _notify (self, PROP_ADDRESSES); - return TRUE; - } - } - return FALSE; + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); + _notify (self, PROP_ADDRESS_DATA); + _notify (self, PROP_ADDRESSES); } -/*****************************************************************************/ - NMIP4Config * nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) { @@ -347,7 +337,6 @@ gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - int i; gs_unref_ptrarray GPtrArray *added_addresses = NULL; g_return_val_if_fail (ifindex > 0, FALSE); @@ -359,7 +348,8 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu /* Routes */ { - int count = nm_ip4_config_get_num_routes (config); + guint i; + guint count = nm_ip4_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count); gboolean success; gs_unref_array GArray *device_route_purge_list = NULL; @@ -1366,7 +1356,7 @@ gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 network, guint8 plen) { guint naddresses = nm_ip4_config_get_num_addresses (config); - int i; + guint i; in_addr_t peer_network; for (i = 0; i < naddresses; i++) { @@ -1473,8 +1463,7 @@ nm_ip4_config_reset_addresses (NMIP4Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + notify_addresses (config); } } @@ -1531,8 +1520,7 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + notify_addresses (config); } void @@ -1543,8 +1531,8 @@ nm_ip4_config_del_address (NMIP4Config *config, guint i) g_return_if_fail (i < priv->addresses->len); g_array_remove_index (priv->addresses, i); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + + notify_addresses (config); } guint @@ -1725,7 +1713,7 @@ nm_ip4_config_del_nameserver (NMIP4Config *config, guint i) _notify (config, PROP_NAMESERVERS); } -guint32 +guint nm_ip4_config_get_num_nameservers (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1782,7 +1770,7 @@ nm_ip4_config_del_domain (NMIP4Config *config, guint i) _notify (config, PROP_DOMAINS); } -guint32 +guint nm_ip4_config_get_num_domains (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1854,7 +1842,7 @@ nm_ip4_config_del_search (NMIP4Config *config, guint i) _notify (config, PROP_SEARCHES); } -guint32 +guint nm_ip4_config_get_num_searches (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1911,7 +1899,7 @@ nm_ip4_config_del_dns_option(NMIP4Config *config, guint i) _notify (config, PROP_DNS_OPTIONS); } -guint32 +guint nm_ip4_config_get_num_dns_options (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1999,7 +1987,7 @@ nm_ip4_config_del_nis_server (NMIP4Config *config, guint i) g_array_remove_index (priv->nis, i); } -guint32 +guint nm_ip4_config_get_num_nis_servers (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -2072,7 +2060,7 @@ nm_ip4_config_del_wins (NMIP4Config *config, guint i) _notify (config, PROP_WINS_SERVERS); } -guint32 +guint nm_ip4_config_get_num_wins (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -2147,7 +2135,7 @@ hash_u32 (GChecksum *sum, guint32 n) void nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only) { - guint32 i; + guint i; const char *s; g_return_if_fail (config); @@ -2267,6 +2255,8 @@ finalize (GObject *object) NMIP4Config *self = NM_IP4_CONFIG (object); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); g_array_unref (priv->addresses); g_array_unref (priv->routes); g_array_unref (priv->nameservers); @@ -2292,14 +2282,26 @@ get_property (GObject *object, guint prop_id, g_value_set_int (value, priv->ifindex); break; case PROP_ADDRESS_DATA: + case PROP_ADDRESSES: { GVariantBuilder array_builder, addr_builder; - int naddr = nm_ip4_config_get_num_addresses (config); - int i; + gs_unref_array GArray *new = NULL; + guint naddr, i; + + g_return_if_fail (!!priv->address_data_variant == !!priv->addresses_variant); + + if (priv->address_data_variant) + goto return_cached; + naddr = nm_ip4_config_get_num_addresses (config); + new = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Address), naddr); + g_array_append_vals (new, priv->addresses->data, priv->addresses->len); + g_array_sort (new, _addresses_sort_cmp); + + /* Build address data variant */ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); for (i = 0; i < naddr; i++) { - const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); + const NMPlatformIP4Address *address = &g_array_index (new, NMPlatformIP4Address, i); g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&addr_builder, "{sv}", @@ -2322,19 +2324,12 @@ get_property (GObject *object, guint prop_id, g_variant_builder_add (&array_builder, "a{sv}", &addr_builder); } + priv->address_data_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); - g_value_take_variant (value, g_variant_builder_end (&array_builder)); - } - break; - case PROP_ADDRESSES: - { - GVariantBuilder array_builder; - int naddr = nm_ip4_config_get_num_addresses (config); - int i; - + /* Build addresses variant */ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau")); for (i = 0; i < naddr; i++) { - const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); + const NMPlatformIP4Address *address = &g_array_index (new, NMPlatformIP4Address, i); guint32 dbus_addr[3]; dbus_addr[0] = address->address; @@ -2345,15 +2340,20 @@ get_property (GObject *object, guint prop_id, g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, dbus_addr, 3, sizeof (guint32))); } + priv->addresses_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); - g_value_take_variant (value, g_variant_builder_end (&array_builder)); +return_cached: + g_value_set_variant (value, + prop_id == PROP_ADDRESS_DATA ? + priv->address_data_variant : + priv->addresses_variant); } break; case PROP_ROUTE_DATA: { GVariantBuilder array_builder, route_builder; guint nroutes = nm_ip4_config_get_num_routes (config); - int i; + guint i; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); for (i = 0; i < nroutes; i++) { @@ -2385,7 +2385,7 @@ get_property (GObject *object, guint prop_id, { GVariantBuilder array_builder; guint nroutes = nm_ip4_config_get_num_routes (config); - int i; + guint i; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau")); for (i = 0; i < nroutes; i++) { |