diff options
Diffstat (limited to 'src/nm-ip6-config.c')
| -rw-r--r-- | src/nm-ip6-config.c | 394 |
1 files changed, 283 insertions, 111 deletions
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index aaf5e701..db64e726 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -19,14 +19,16 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include <string.h> +#include <arpa/inet.h> #include "nm-ip6-config.h" #include "nm-glib-compat.h" -#include "libgsystem.h" -#include "nm-platform.h" #include "nm-utils.h" +#include "nm-platform.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" #include "nm-ip6-config-glue.h" @@ -52,9 +54,11 @@ typedef struct { enum { PROP_0, - PROP_GATEWAY, + PROP_ADDRESS_DATA, PROP_ADDRESSES, + PROP_ROUTE_DATA, PROP_ROUTES, + PROP_GATEWAY, PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, @@ -169,7 +173,9 @@ static gboolean routes_are_duplicate (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gboolean consider_gateway_and_metric) { return IN6_ARE_ADDR_EQUAL (&a->network, &b->network) && a->plen == b->plen && - (!consider_gateway_and_metric || (IN6_ARE_ADDR_EQUAL (&a->gateway, &b->gateway) && a->metric == b->metric)); + ( !consider_gateway_and_metric + || ( IN6_ARE_ADDR_EQUAL (&a->gateway, &b->gateway) + && nm_utils_ip6_route_metric_normalize (a->metric) == nm_utils_ip6_route_metric_normalize (b->metric))); } static gint @@ -272,6 +278,7 @@ nm_ip6_config_addresses_sort (NMIP6Config *self, NMSettingIP6ConfigPrivacy use_t g_free (data_pre); if (changed) { + _NOTIFY (self, PROP_ADDRESS_DATA); _NOTIFY (self, PROP_ADDRESSES); return TRUE; } @@ -285,7 +292,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co NMIP6Config *config; NMIP6ConfigPrivate *priv; guint i; - guint lowest_metric = G_MAXUINT; + guint32 lowest_metric = G_MAXUINT32; struct in6_addr old_gateway = IN6ADDR_ANY_INIT; gboolean has_gateway = FALSE; gboolean notify_nameservers = FALSE; @@ -301,14 +308,14 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co g_array_unref (priv->routes); priv->addresses = nm_platform_ip6_address_get_all (ifindex); - priv->routes = nm_platform_ip6_route_get_all (ifindex, TRUE); + priv->routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); /* Extract gateway from default route */ old_gateway = priv->gateway; for (i = 0; i < priv->routes->len; i++) { const NMPlatformIP6Route *route = &g_array_index (priv->routes, NMPlatformIP6Route, i); - if (IN6_IS_ADDR_UNSPECIFIED (&route->network)) { + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { if (route->metric < lowest_metric) { priv->gateway = route->gateway; lowest_metric = route->metric; @@ -347,7 +354,9 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co /* actually, nobody should be connected to the signal, just to be sure, notify */ if (notify_nameservers) _NOTIFY (config, PROP_NAMESERVERS); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); if (!IN6_ARE_ADDR_EQUAL (&priv->gateway, &old_gateway)) _NOTIFY (config, PROP_GATEWAY); @@ -372,25 +381,19 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex) { int count = nm_ip6_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count); - NMPlatformIP6Route route; + const NMPlatformIP6Route *route; for (i = 0; i < count; i++) { - memcpy (&route, nm_ip6_config_get_route (config, i), sizeof (route)); + route = nm_ip6_config_get_route (config, i); /* Don't add the route if it's more specific than one of the subnets * the device already has an IP address on. */ - if ( IN6_IS_ADDR_UNSPECIFIED (&route.gateway) - && nm_ip6_config_destination_is_direct (config, &route.network, route.plen)) + if ( IN6_IS_ADDR_UNSPECIFIED (&route->gateway) + && nm_ip6_config_destination_is_direct (config, &route->network, route->plen)) continue; - /* Don't add the default route if the connection - * is never supposed to be the default connection. - */ - if (nm_ip6_config_get_never_default (config) && IN6_IS_ADDR_UNSPECIFIED (&route.network)) - continue; - - g_array_append_val (routes, route); + g_array_append_vals (routes, route, 1); } success = nm_platform_ip6_route_sync (ifindex, routes); @@ -401,79 +404,88 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex) } void -nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting, int default_route_metric) +nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric) { guint naddresses, nroutes, nnameservers, nsearches; + const char *gateway_str; int i; if (!setting) return; - naddresses = nm_setting_ip6_config_get_num_addresses (setting); - nroutes = nm_setting_ip6_config_get_num_routes (setting); - nnameservers = nm_setting_ip6_config_get_num_dns (setting); - nsearches = nm_setting_ip6_config_get_num_dns_searches (setting); + g_return_if_fail (NM_IS_SETTING_IP6_CONFIG (setting)); + + naddresses = nm_setting_ip_config_get_num_addresses (setting); + nroutes = nm_setting_ip_config_get_num_routes (setting); + nnameservers = nm_setting_ip_config_get_num_dns (setting); + nsearches = nm_setting_ip_config_get_num_dns_searches (setting); g_object_freeze_notify (G_OBJECT (config)); /* Gateway */ - if (nm_setting_ip6_config_get_never_default (setting)) + if (nm_setting_ip_config_get_never_default (setting)) nm_ip6_config_set_never_default (config, TRUE); - else if (nm_setting_ip6_config_get_ignore_auto_routes (setting)) + else if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip6_config_set_never_default (config, FALSE); - for (i = 0; i < naddresses; i++) { - const struct in6_addr *gateway = nm_ip6_address_get_gateway (nm_setting_ip6_config_get_address (setting, i)); + gateway_str = nm_setting_ip_config_get_gateway (setting); + if (gateway_str) { + struct in6_addr gateway; - if (gateway && !IN6_IS_ADDR_UNSPECIFIED (gateway)) { - nm_ip6_config_set_gateway (config, gateway); - break; - } + inet_pton (AF_INET6, gateway_str, &gateway); + nm_ip6_config_set_gateway (config, &gateway); } /* Addresses */ for (i = 0; i < naddresses; i++) { - NMIP6Address *s_addr = nm_setting_ip6_config_get_address (setting, i); + NMIPAddress *s_addr = nm_setting_ip_config_get_address (setting, i); NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); - address.address = *nm_ip6_address_get_address (s_addr); - address.plen = nm_ip6_address_get_prefix (s_addr); + nm_ip_address_get_address_binary (s_addr, &address.address); + address.plen = nm_ip_address_get_prefix (s_addr); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; - address.source = NM_PLATFORM_SOURCE_USER; + address.source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (config, &address); } /* Routes */ - if (nm_setting_ip6_config_get_ignore_auto_routes (setting)) + if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip6_config_reset_routes (config); for (i = 0; i < nroutes; i++) { - NMIP6Route *s_route = nm_setting_ip6_config_get_route (setting, i); + NMIPRoute *s_route = nm_setting_ip_config_get_route (setting, i); NMPlatformIP6Route route; memset (&route, 0, sizeof (route)); - route.network = *nm_ip6_route_get_dest (s_route); - route.plen = nm_ip6_route_get_prefix (s_route); - route.gateway = *nm_ip6_route_get_next_hop (s_route); - route.metric = nm_ip6_route_get_metric (s_route); - if (!route.metric) + nm_ip_route_get_dest_binary (s_route, &route.network); + route.plen = nm_ip_route_get_prefix (s_route); + nm_ip_route_get_next_hop_binary (s_route, &route.gateway); + if (nm_ip_route_get_metric (s_route) == -1) route.metric = default_route_metric; - route.source = NM_PLATFORM_SOURCE_USER; + else + route.metric = nm_ip_route_get_metric (s_route); + route.source = NM_IP_CONFIG_SOURCE_USER; + + g_assert (route.plen > 0); nm_ip6_config_add_route (config, &route); } /* DNS */ - if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) { + if (nm_setting_ip_config_get_ignore_auto_dns (setting)) { nm_ip6_config_reset_nameservers (config); nm_ip6_config_reset_domains (config); nm_ip6_config_reset_searches (config); } - for (i = 0; i < nnameservers; i++) - nm_ip6_config_add_nameserver (config, nm_setting_ip6_config_get_dns (setting, i)); + for (i = 0; i < nnameservers; i++) { + struct in6_addr ip; + + if (inet_pton (AF_INET6, nm_setting_ip_config_get_dns (setting, i), &ip) == 1) + nm_ip6_config_add_nameserver (config, &ip); + } for (i = 0; i < nsearches; i++) - nm_ip6_config_add_search (config, nm_setting_ip6_config_get_dns_search (setting, i)); + nm_ip6_config_add_search (config, nm_setting_ip_config_get_dns_search (setting, i)); g_object_thaw_notify (G_OBJECT (config)); } @@ -481,17 +493,17 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting, i NMSetting * nm_ip6_config_create_setting (const NMIP6Config *config) { - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; const struct in6_addr *gateway; guint naddresses, nroutes, nnameservers, nsearches; const char *method = NULL; int i; - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); if (!config) { g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); return NM_SETTING (s_ip6); } @@ -505,7 +517,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) /* Addresses */ for (i = 0; i < naddresses; i++) { const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); - NMIP6Address *s_addr; + NMIPAddress *s_addr; /* Ignore link-local address. */ if (IN6_IS_ADDR_LINKLOCAL (&address->address)) { @@ -524,26 +536,28 @@ nm_ip6_config_create_setting (const NMIP6Config *config) if (!method || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - s_addr = nm_ip6_address_new (); - - nm_ip6_address_set_address (s_addr, &address->address); - nm_ip6_address_set_prefix (s_addr, address->plen); - if (gateway) - nm_ip6_address_set_gateway (s_addr, gateway); + s_addr = nm_ip_address_new_binary (AF_INET6, &address->address, address->plen, NULL); + nm_setting_ip_config_add_address (s_ip6, s_addr); + nm_ip_address_unref (s_addr); + } - nm_setting_ip6_config_add_address (s_ip6, s_addr); - nm_ip6_address_unref (s_addr); + /* Gateway */ + if ( gateway + && nm_setting_ip_config_get_num_addresses (s_ip6) > 0) { + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet6_ntop (gateway, NULL), + NULL); } /* Use 'ignore' if the method wasn't previously set */ if (!method) method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, method, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, method, NULL); /* Routes */ for (i = 0; i < nroutes; i++) { const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); - NMIP6Route *s_route; + NMIPRoute *s_route; /* Ignore link-local route. */ if (IN6_IS_ADDR_LINKLOCAL (&route->network)) @@ -554,30 +568,27 @@ nm_ip6_config_create_setting (const NMIP6Config *config) continue; /* Ignore routes provided by external sources */ - if (route->source != NM_PLATFORM_SOURCE_USER) + if (route->source != NM_IP_CONFIG_SOURCE_USER) continue; - s_route = nm_ip6_route_new (); - nm_ip6_route_set_dest (s_route, &route->network); - nm_ip6_route_set_prefix (s_route, route->plen); - if (!IN6_IS_ADDR_UNSPECIFIED (&route->network)) - nm_ip6_route_set_next_hop (s_route, &route->gateway); - nm_ip6_route_set_metric (s_route, route->metric); - - nm_setting_ip6_config_add_route (s_ip6, s_route); - nm_ip6_route_unref (s_route); + s_route = nm_ip_route_new_binary (AF_INET6, + &route->network, route->plen, + &route->gateway, route->metric, + NULL); + nm_setting_ip_config_add_route (s_ip6, s_route); + nm_ip_route_unref (s_route); } /* DNS */ for (i = 0; i < nnameservers; i++) { const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (config, i); - nm_setting_ip6_config_add_dns (s_ip6, nameserver); + nm_setting_ip_config_add_dns (s_ip6, nm_utils_inet6_ntop (nameserver, NULL)); } for (i = 0; i < nsearches; i++) { const char *search = nm_ip6_config_get_search (config, i); - nm_setting_ip6_config_add_dns_search (s_ip6, search); + nm_setting_ip_config_add_dns_search (s_ip6, search); } return NM_SETTING (s_ip6); @@ -694,6 +705,9 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) if (src_tmp && dst_tmp && IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp)) nm_ip6_config_set_gateway (dst, NULL); + if (!nm_ip6_config_get_num_addresses (dst)) + nm_ip6_config_set_gateway (dst, NULL); + /* routes */ for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) { const NMPlatformIP6Route *src_route = nm_ip6_config_get_route (src, i); @@ -956,7 +970,7 @@ nm_ip6_config_dump (const NMIP6Config *config, const char *detail) for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) g_message (" search: %s", nm_ip6_config_get_search (config, i)); - g_message (" mss: %u", nm_ip6_config_get_mss (config)); + g_message (" mss: %"G_GUINT32_FORMAT, nm_ip6_config_get_mss (config)); g_message (" n-dflt: %d", nm_ip6_config_get_never_default (config)); } @@ -1012,6 +1026,7 @@ nm_ip6_config_reset_addresses (NMIP6Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } } @@ -1055,7 +1070,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) * with "what should be" and the kernel values are "what turned out after configuring it". * * For other sources, the longer lifetime wins. */ - if ( (new->source == NM_PLATFORM_SOURCE_KERNEL && new->source != item_old.source) + if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.source) || nm_platform_ip_address_cmp_expiry ((const NMPlatformIPAddress *) &item_old, (const NMPlatformIPAddress *) new) > 0) { item->timestamp = item_old.timestamp; item->lifetime = item_old.lifetime; @@ -1069,6 +1084,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } @@ -1080,6 +1096,7 @@ nm_ip6_config_del_address (NMIP6Config *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); } @@ -1125,6 +1142,7 @@ nm_ip6_config_reset_routes (NMIP6Config *config) if (priv->routes->len != 0) { g_array_set_size (priv->routes, 0); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } } @@ -1143,10 +1161,11 @@ void nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); - NMPlatformSource old_source; + NMIPConfigSource old_source; int i; g_return_if_fail (new != NULL); + g_return_if_fail (new->plen > 0); for (i = 0; i < priv->routes->len; i++ ) { NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i); @@ -1164,6 +1183,7 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) g_array_append_val (priv->routes, *new); NOTIFY: + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1175,6 +1195,7 @@ nm_ip6_config_del_route (NMIP6Config *config, guint i) g_return_if_fail (i < priv->routes->len); g_array_remove_index (priv->routes, i); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1194,6 +1215,68 @@ nm_ip6_config_get_route (const NMIP6Config *config, guint i) return &g_array_index (priv->routes, NMPlatformIP6Route, i); } +const NMPlatformIP6Route * +nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + guint i; + struct in6_addr network2, host2; + NMPlatformIP6Route *best_route = NULL; + + g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL); + + for (i = 0; i < priv->routes->len; i++) { + NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i); + + if (!IN6_IS_ADDR_UNSPECIFIED (&item->gateway)) + continue; + + if (best_route && best_route->plen > item->plen) + continue; + + nm_utils_ip6_address_clear_host_address (&host2, host, item->plen); + nm_utils_ip6_address_clear_host_address (&network2, &item->network, item->plen); + + if (!IN6_ARE_ADDR_EQUAL (&network2, &host2)) + continue; + + if (best_route && + nm_utils_ip6_route_metric_normalize (best_route->metric) <= nm_utils_ip6_route_metric_normalize (item->metric)) + continue; + + best_route = item; + } + + return best_route; +} + +const NMPlatformIP6Address * +nm_ip6_config_get_subnet_for_host (const NMIP6Config *config, const struct in6_addr *host) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + guint i; + NMPlatformIP6Address *subnet = NULL; + struct in6_addr subnet2, host2; + + g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL); + + for (i = 0; i < priv->addresses->len; i++) { + NMPlatformIP6Address *item = &g_array_index (priv->addresses, NMPlatformIP6Address, i); + + if (subnet && subnet->plen >= item->plen) + continue; + + nm_utils_ip6_address_clear_host_address (&host2, host, item->plen); + nm_utils_ip6_address_clear_host_address (&subnet2, &item->address, item->plen); + + if (IN6_ARE_ADDR_EQUAL (&subnet2, &host2)) + subnet = item; + } + + return subnet; +} + + /******************************************************************/ void @@ -1532,6 +1615,15 @@ nameservers_to_gvalue (GArray *array, GValue *value) } static void +gvalue_destroy (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { @@ -1539,11 +1631,34 @@ get_property (GObject *object, guint prop_id, NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); switch (prop_id) { - case PROP_GATEWAY: - if (!IN6_IS_ADDR_UNSPECIFIED (&priv->gateway)) - g_value_set_string (value, nm_utils_inet6_ntop (&priv->gateway, NULL)); - else - g_value_set_string (value, NULL); + case PROP_ADDRESS_DATA: + { + GPtrArray *addresses = g_ptr_array_new (); + int naddr = nm_ip6_config_get_num_addresses (config); + int i; + + for (i = 0; i < naddr; i++) { + const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); + GHashTable *addr_hash; + GValue *val; + + addr_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&address->address, NULL)); + g_hash_table_insert (addr_hash, "address", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, address->plen); + g_hash_table_insert (addr_hash, "prefix", val); + + g_ptr_array_add (addresses, addr_hash); + } + + g_value_take_boxed (value, addresses); + } break; case PROP_ADDRESSES: { @@ -1576,7 +1691,7 @@ get_property (GObject *object, guint prop_id, /* Gateway */ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) (gateway ? gateway : &in6addr_any), sizeof (*gateway)); + g_byte_array_append (ba, (guint8 *) (i == 0 && gateway ? gateway : &in6addr_any), sizeof (*gateway)); g_value_take_boxed (&element, ba); g_value_array_append (array, &element); g_value_unset (&element); @@ -1587,6 +1702,47 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, addresses); } break; + case PROP_ROUTE_DATA: + { + GPtrArray *routes = g_ptr_array_new (); + guint nroutes = nm_ip6_config_get_num_routes (config); + int i; + + for (i = 0; i < nroutes; i++) { + const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); + GHashTable *route_hash; + GValue *val; + + route_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&route->network, NULL)); + g_hash_table_insert (route_hash, "dest", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->plen); + g_hash_table_insert (route_hash, "prefix", val); + + if (!IN6_IS_ADDR_UNSPECIFIED (&route->gateway)) { + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&route->gateway, NULL)); + g_hash_table_insert (route_hash, "next-hop", val); + } + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->metric); + g_hash_table_insert (route_hash, "metric", val); + + g_ptr_array_add (routes, route_hash); + } + + g_value_take_boxed (value, routes); + } + break; case PROP_ROUTES: { GPtrArray *routes = g_ptr_array_new (); @@ -1594,12 +1750,18 @@ get_property (GObject *object, guint prop_id, int i; for (i = 0; i < nroutes; i++) { + GValueArray *array; const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); - - GValueArray *array = g_value_array_new (4); GByteArray *ba; GValue element = G_VALUE_INIT; + /* 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_IP_ROUTE_IS_DEFAULT (route)) + continue; + + array = g_value_array_new (4); + g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); ba = g_byte_array_new (); g_byte_array_append (ba, (guint8 *) &route->network, sizeof (route->network)); @@ -1630,6 +1792,12 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, routes); } break; + case PROP_GATEWAY: + if (!IN6_IS_ADDR_UNSPECIFIED (&priv->gateway)) + g_value_set_string (value, nm_utils_inet6_ntop (&priv->gateway, NULL)); + else + g_value_set_string (value, NULL); + break; case PROP_NAMESERVERS: nameservers_to_gvalue (priv->nameservers, value); break; @@ -1657,42 +1825,46 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) object_class->finalize = finalize; /* properties */ - obj_properties[PROP_GATEWAY] = - g_param_spec_string (NM_IP6_CONFIG_GATEWAY, - "Gateway", - "IP6 Gateway", - NULL, - G_PARAM_READABLE); + obj_properties[PROP_ADDRESS_DATA] = + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESS_DATA, "", "", + DBUS_TYPE_NM_IP_ADDRESSES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESSES] = - g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, - "Addresses", - "IP6 addresses", - DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - G_PARAM_READABLE); + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, "", "", + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_DATA] = + g_param_spec_boxed (NM_IP6_CONFIG_ROUTE_DATA, "", "", + DBUS_TYPE_NM_IP_ROUTES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTES] = - g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, - "Routes", - "Routes", + g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, "", "", DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_GATEWAY] = + g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = - g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, - "Nameservers", - "DNS list", + g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, "", "", DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DOMAINS] = - g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, - "Domains", - "Domains", + g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_SEARCHES] = - g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, - "Searches", - "Searches", + g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, obj_properties); |