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'.
This commit is contained in:
Dan Winship 2014-10-21 08:33:18 -04:00
parent f17699f4e3
commit d16905df63
15 changed files with 923 additions and 86 deletions

View file

@ -37,4 +37,9 @@
#define DBUS_TYPE_G_IP6_ROUTE (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
#define DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ROUTE))
#define DBUS_TYPE_NM_IP_ADDRESS (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_MAP_OF_STRING, G_TYPE_INVALID))
#define DBUS_TYPE_NM_IP_ADDRESSES (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_NM_IP_ADDRESS))
#define DBUS_TYPE_NM_IP_ROUTE (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT, DBUS_TYPE_G_MAP_OF_STRING, G_TYPE_INVALID))
#define DBUS_TYPE_NM_IP_ROUTES (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_NM_IP_ROUTE))
#endif /* __NM_DBUS_GLIB_TYPES_H__ */

View file

@ -2,20 +2,42 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP4Config">
<property name="Addresses" type="aau" access="read">
<tp:docstring>
Array of arrays of IPv4 address/prefix/gateway. All 3
elements of each array are in network byte order. Essentially:
[(addr, prefix, gateway), (addr, prefix, gateway), ...]
Deprecated: use AddressData and Gateway
</tp:docstring>
</property>
<property name="AddressData" type="aa{sv}" access="read">
<tp:docstring>
Array of IP address data objects. All addresses will include
"address" (an IP address string), and "prefix" (a uint). Some
addresses may include additional attributes.
</tp:docstring>
</property>
<property name="Gateway" type="s" access="read">
<tp:docstring>The gateway in use.</tp:docstring>
</property>
<property name="Addresses" type="aau" access="read">
<tp:docstring>Array of tuples of IPv4 address/prefix/gateway. All 3
elements of each tuple are in network byte order. Essentially:
[(addr, prefix, gateway), (addr, prefix, gateway), ...]
<property name="Routes" type="aau" access="read">
<tp:docstring>
Arrays of IPv4 route/prefix/next-hop/metric. All 4 elements of
each tuple are in network byte order. 'route' and 'next hop'
are IPv4 addresses, while prefix and metric are simple
unsigned integers. Essentially: [(route, prefix, next-hop,
metric), (route, prefix, next-hop, metric), ...]
Deprecated: use RouteData
</tp:docstring>
</property>
<property name="Routes" type="aau" access="read">
<tp:docstring>Tuples of IPv4 route/prefix/next-hop/metric. All 4 elements
of each tuple are in network byte order. 'route' and 'next hop' are IPv4
addresses, while prefix and metric are simple unsigned integers. Essentially:
[(route, prefix, next-hop, metric), (route, prefix, next-hop, metric), ...]
<property name="RouteData" type="aa{sv}" access="read">
<tp:docstring>
Array of IP route data objects. All routes will include "dest"
(an IP address string) and "prefix" (a uint). Some routes may
include "next-hop" (an IP address string), "metric" (a uint),
and additional attributes.
</tp:docstring>
</property>
<property name="Nameservers" type="au" access="read">

View file

@ -2,14 +2,37 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP6Config">
<property name="Addresses" type="a(ayuay)" access="read">
<tp:docstring>
Array of tuples of IPv6 address/prefix/gateway.
Deprecated: use AddressData and Gateway.
</tp:docstring>
</property>
<property name="AddressData" type="aa{sv}" access="read">
<tp:docstring>
Array of IP address data objects. All addresses will include
"address" (an IP address string), and "prefix" (a uint). Some
addresses may include additional attributes.
</tp:docstring>
</property>
<property name="Gateway" type="s" access="read">
<tp:docstring>The gateway in use.</tp:docstring>
</property>
<property name="Addresses" type="a(ayuay)" access="read">
<tp:docstring>Tuples of IPv6 address/prefix/gateway.</tp:docstring>
</property>
<property name="Routes" type="a(ayuayu)" access="read">
<tp:docstring>Tuples of IPv6 route/prefix/next-hop/metric.</tp:docstring>
<tp:docstring>
Tuples of IPv6 route/prefix/next-hop/metric.
Deprecated: use RouteData
</tp:docstring>
</property>
<property name="RouteData" type="aa{sv}" access="read">
<tp:docstring>
Array of IP route data objects. All routes will include "dest"
(an IP address string) and "prefix" (a uint). Some routes may
include "next-hop" (an IP address string), "metric" (a uint),
and additional attributes.
</tp:docstring>
</property>
<property name="Nameservers" type="aay" access="read">
<tp:docstring>The nameservers in use.</tp:docstring>

View file

@ -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,

View file

@ -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)
{
return nm_utils_ip4_routes_to_variant (g_value_get_boxed (prop_value));
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_routes_from_dbus (GVariant *dbus_value,
GValue *prop_value)
ip4_address_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 *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)
{
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_route_data_set (NMSetting *setting,
GVariant *connection_dict,
const char *property,
GVariant *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);
}

View file

@ -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)
{
return nm_utils_ip6_routes_to_variant (g_value_get_boxed (prop_value));
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_routes_from_dbus (GVariant *dbus_value,
GValue *prop_value)
ip6_address_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 *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)
{
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_route_data_set (NMSetting *setting,
GVariant *connection_dict,
const char *property,
GVariant *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);
}

View file

@ -1711,6 +1711,245 @@ nm_utils_ip6_routes_from_variant (GVariant *value)
return routes;
}
/**
* 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:
*

View file

@ -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);

View file

@ -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);

View file

@ -40,6 +40,8 @@ typedef struct {
char **domains;
char **searches;
char **wins;
gboolean new_style_data;
} NMIP4ConfigPrivate;
enum {
@ -69,10 +71,13 @@ nm_ip4_config_init (NMIP4Config *config)
}
static gboolean
demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
demarshal_ip4_addresses (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
if (priv->new_style_data)
return TRUE;
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip4_addresses_from_variant (value, NULL);
_nm_object_queue_notify (object, NM_IP4_CONFIG_ADDRESSES);
@ -80,6 +85,20 @@ demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GVariant *valu
return TRUE;
}
static gboolean
demarshal_ip4_address_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
priv->new_style_data = TRUE;
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET);
_nm_object_queue_notify (object, NM_IP4_CONFIG_ADDRESSES);
return TRUE;
}
static gboolean
demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
@ -96,10 +115,13 @@ demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpoin
}
static gboolean
demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
demarshal_ip4_routes (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
if (priv->new_style_data)
return TRUE;
g_ptr_array_unref (priv->routes);
priv->routes = nm_utils_ip4_routes_from_variant (value);
_nm_object_queue_notify (object, NM_IP4_CONFIG_ROUTES);
@ -107,14 +129,30 @@ demarshal_ip4_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value
return TRUE;
}
static gboolean
demarshal_ip4_route_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
priv->new_style_data = TRUE;
g_ptr_array_unref (priv->routes);
priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET);
_nm_object_queue_notify (object, NM_IP4_CONFIG_ROUTES);
return TRUE;
}
static void
init_dbus (NMObject *object)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
const NMPropertiesInfo property_info[] = {
{ NM_IP4_CONFIG_GATEWAY, &priv->gateway, },
{ NM_IP4_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip4_address_array },
{ NM_IP4_CONFIG_ROUTES, &priv->routes, demarshal_ip4_routes_array },
{ NM_IP4_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip4_addresses },
{ "address-data", &priv->addresses, demarshal_ip4_address_data },
{ NM_IP4_CONFIG_ROUTES, &priv->routes, demarshal_ip4_routes },
{ "route-data", &priv->routes, demarshal_ip4_route_data },
{ NM_IP4_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip4_array },
{ NM_IP4_CONFIG_DOMAINS, &priv->domains, },
{ NM_IP4_CONFIG_SEARCHES, &priv->searches, },

View file

@ -39,6 +39,8 @@ typedef struct {
char **nameservers;
char **domains;
char **searches;
gboolean new_style_data;
} NMIP6ConfigPrivate;
enum {
@ -54,10 +56,13 @@ enum {
};
static gboolean
demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
demarshal_ip6_addresses (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
if (priv->new_style_data)
return TRUE;
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip6_addresses_from_variant (value, NULL);
_nm_object_queue_notify (object, NM_IP6_CONFIG_ADDRESSES);
@ -65,6 +70,20 @@ demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GVariant *valu
return TRUE;
}
static gboolean
demarshal_ip6_address_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
priv->new_style_data = TRUE;
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET6);
_nm_object_queue_notify (object, NM_IP6_CONFIG_ADDRESSES);
return TRUE;
}
static gboolean
demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
@ -81,10 +100,13 @@ demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GVariant *v
}
static gboolean
demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
demarshal_ip6_routes (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
if (priv->new_style_data)
return TRUE;
g_ptr_array_unref (priv->routes);
priv->routes = nm_utils_ip6_routes_from_variant (value);
_nm_object_queue_notify (object, NM_IP6_CONFIG_ROUTES);
@ -92,14 +114,30 @@ demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GVariant *value
return TRUE;
}
static gboolean
demarshal_ip6_route_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
priv->new_style_data = TRUE;
g_ptr_array_unref (priv->routes);
priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET6);
_nm_object_queue_notify (object, NM_IP6_CONFIG_ROUTES);
return TRUE;
}
static void
init_dbus (NMObject *object)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
const NMPropertiesInfo property_info[] = {
{ NM_IP6_CONFIG_GATEWAY, &priv->gateway, },
{ NM_IP6_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip6_address_array },
{ NM_IP6_CONFIG_ROUTES, &priv->routes, demarshal_ip6_routes_array },
{ NM_IP6_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip6_addresses },
{ "address-data", &priv->addresses, demarshal_ip6_address_data },
{ NM_IP6_CONFIG_ROUTES, &priv->routes, demarshal_ip6_routes },
{ "route-data", &priv->routes, demarshal_ip6_route_data },
{ NM_IP6_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip6_nameserver_array },
{ NM_IP6_CONFIG_DOMAINS, &priv->domains, },
{ NM_IP6_CONFIG_SEARCHES, &priv->searches, },

View file

@ -59,9 +59,11 @@ G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF);
enum {
PROP_0,
PROP_GATEWAY,
PROP_ADDRESS_DATA,
PROP_ADDRESSES,
PROP_ROUTE_DATA,
PROP_ROUTES,
PROP_GATEWAY,
PROP_NAMESERVERS,
PROP_DOMAINS,
PROP_SEARCHES,
@ -235,6 +237,8 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf)
}
/* actually, nobody should be connected to the signal, just to be sure, notify */
_NOTIFY (config, PROP_ADDRESS_DATA);
_NOTIFY (config, PROP_ROUTE_DATA);
_NOTIFY (config, PROP_ADDRESSES);
_NOTIFY (config, PROP_ROUTES);
if (priv->gateway != old_gateway)
@ -1013,6 +1017,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);
}
}
@ -1070,6 +1075,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);
}
@ -1081,6 +1087,7 @@ 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);
}
@ -1125,6 +1132,7 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
if (priv->routes->len != 0) {
g_array_set_size (priv->routes, 0);
_NOTIFY (config, PROP_ROUTE_DATA);
_NOTIFY (config, PROP_ROUTES);
}
}
@ -1164,6 +1172,7 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
g_array_append_val (priv->routes, *new);
NOTIFY:
_NOTIFY (config, PROP_ROUTE_DATA);
_NOTIFY (config, PROP_ROUTES);
}
@ -1175,6 +1184,7 @@ nm_ip4_config_del_route (NMIP4Config *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);
}
@ -1705,11 +1715,41 @@ get_property (GObject *object, guint prop_id,
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
switch (prop_id) {
case PROP_GATEWAY:
if (priv->gateway)
g_value_set_string (value, nm_utils_inet4_ntop (priv->gateway, NULL));
else
g_value_set_string (value, NULL);
case PROP_ADDRESS_DATA:
{
GPtrArray *addresses = g_ptr_array_new ();
int naddr = nm_ip4_config_get_num_addresses (config);
int i;
for (i = 0; i < naddr; i++) {
const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i);
GValueArray *array = g_value_array_new (3);
GHashTable *attrs;
GValue val = { 0, };
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, nm_utils_inet4_ntop (address->address, NULL));
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, address->plen);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
attrs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
if (*address->label)
g_hash_table_insert (attrs, "label", g_strdup (address->label));
g_value_take_boxed (&val, attrs);
g_value_array_append (array, &val);
g_value_unset (&val);
g_ptr_array_add (addresses, array);
}
g_value_take_boxed (value, addresses);
}
break;
case PROP_ADDRESSES:
{
@ -1732,6 +1772,53 @@ 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_ip4_config_get_num_routes (config);
int i;
for (i = 0; i < nroutes; i++) {
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
GValueArray *array = g_value_array_new (5);
GHashTable *attrs;
GValue val = { 0, };
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, nm_utils_inet4_ntop (route->network, NULL));
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, route->plen);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_STRING);
if (route->gateway)
g_value_set_string (&val, nm_utils_inet4_ntop (route->gateway, NULL));
else
g_value_set_string (&val, "");
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, route->metric);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
attrs = g_hash_table_new (g_str_hash, g_str_equal);
g_value_take_boxed (&val, attrs);
g_value_array_append (array, &val);
g_value_unset (&val);
g_ptr_array_add (routes, array);
}
g_value_take_boxed (value, routes);
}
break;
case PROP_ROUTES:
{
GPtrArray *routes = g_ptr_array_new ();
@ -1753,6 +1840,12 @@ get_property (GObject *object, guint prop_id,
g_value_take_boxed (value, routes);
}
break;
case PROP_GATEWAY:
if (priv->gateway)
g_value_set_string (value, nm_utils_inet4_ntop (priv->gateway, NULL));
else
g_value_set_string (value, NULL);
break;
case PROP_NAMESERVERS:
g_value_set_boxed (value, priv->nameservers);
break;
@ -1781,19 +1874,29 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
obj_properties[PROP_GATEWAY] =
g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_ADDRESS_DATA] =
g_param_spec_boxed (NM_IP4_CONFIG_ADDRESS_DATA, "", "",
DBUS_TYPE_NM_IP_ADDRESSES,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_ADDRESSES] =
g_param_spec_boxed (NM_IP4_CONFIG_ADDRESSES, "", "",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
g_param_spec_boxed (NM_IP4_CONFIG_ADDRESSES, "", "",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_ROUTE_DATA] =
g_param_spec_boxed (NM_IP4_CONFIG_ROUTE_DATA, "", "",
DBUS_TYPE_NM_IP_ROUTES,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_ROUTES] =
g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, "", "",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, "", "",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_GATEWAY] =
g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_NAMESERVERS] =

View file

@ -41,14 +41,18 @@ typedef struct {
GObjectClass parent;
} NMIP4ConfigClass;
#define NM_IP4_CONFIG_ADDRESS_DATA "address-data"
#define NM_IP4_CONFIG_ROUTE_DATA "route-data"
#define NM_IP4_CONFIG_GATEWAY "gateway"
#define NM_IP4_CONFIG_ADDRESSES "addresses"
#define NM_IP4_CONFIG_ROUTES "routes"
#define NM_IP4_CONFIG_NAMESERVERS "nameservers"
#define NM_IP4_CONFIG_DOMAINS "domains"
#define NM_IP4_CONFIG_SEARCHES "searches"
#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
/* deprecated */
#define NM_IP4_CONFIG_ADDRESSES "addresses"
#define NM_IP4_CONFIG_ROUTES "routes"
GType nm_ip4_config_get_type (void);

View file

@ -51,9 +51,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,
@ -271,6 +273,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;
}
@ -346,7 +349,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);
@ -1016,6 +1021,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);
}
}
@ -1073,6 +1079,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);
}
@ -1084,6 +1091,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);
}
@ -1129,6 +1137,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);
}
}
@ -1168,6 +1177,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);
}
@ -1179,6 +1189,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);
}
@ -1578,11 +1589,39 @@ 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);
GValueArray *array = g_value_array_new (3);
GHashTable *attrs;
GValue val = { 0, };
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, nm_utils_inet6_ntop (&address->address, NULL));
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, address->plen);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
attrs = g_hash_table_new (g_str_hash, g_str_equal);
g_value_take_boxed (&val, attrs);
g_value_array_append (array, &val);
g_value_unset (&val);
g_ptr_array_add (addresses, array);
}
g_value_take_boxed (value, addresses);
}
break;
case PROP_ADDRESSES:
{
@ -1626,6 +1665,53 @@ 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);
GValueArray *array = g_value_array_new (5);
GHashTable *attrs;
GValue val = { 0, };
g_value_init (&val, G_TYPE_STRING);
g_value_set_string (&val, nm_utils_inet6_ntop (&route->network, NULL));
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, route->plen);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_STRING);
if (memcmp (&route->gateway, &in6addr_any, sizeof (struct in6_addr)) != 0)
g_value_set_string (&val, nm_utils_inet6_ntop (&route->gateway, NULL));
else
g_value_set_string (&val, "");
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, G_TYPE_UINT);
g_value_set_uint (&val, route->metric);
g_value_array_append (array, &val);
g_value_unset (&val);
g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
attrs = g_hash_table_new (g_str_hash, g_str_equal);
g_value_take_boxed (&val, attrs);
g_value_array_append (array, &val);
g_value_unset (&val);
g_ptr_array_add (routes, array);
}
g_value_take_boxed (value, routes);
}
break;
case PROP_ROUTES:
{
GPtrArray *routes = g_ptr_array_new ();
@ -1669,6 +1755,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;
@ -1696,21 +1788,31 @@ 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, "", "",
NULL,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_ADDRESSES] =
g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, "", "",
DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
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, "", "",
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, "", "",
DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
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, "", "",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR,

View file

@ -42,13 +42,17 @@ typedef struct {
GObjectClass parent;
} NMIP6ConfigClass;
#define NM_IP6_CONFIG_ADDRESS_DATA "address-data"
#define NM_IP6_CONFIG_ROUTE_DATA "route-data"
#define NM_IP6_CONFIG_GATEWAY "gateway"
#define NM_IP6_CONFIG_ADDRESSES "addresses"
#define NM_IP6_CONFIG_ROUTES "routes"
#define NM_IP6_CONFIG_NAMESERVERS "nameservers"
#define NM_IP6_CONFIG_DOMAINS "domains"
#define NM_IP6_CONFIG_SEARCHES "searches"
/* deprecated */
#define NM_IP6_CONFIG_ADDRESSES "addresses"
#define NM_IP6_CONFIG_ROUTES "routes"
GType nm_ip6_config_get_type (void);