Commit db9b7e10 authored by Thomas Haller's avatar Thomas Haller

core: update existing IP[46]Config of device instead of replacing it (bgo #707617)

When the IP[46]Config changes, a new configuration gets assembled.
Before, whenever the new configuration was different than the current
one, the IP[46]Config of the device was completely replaced. This also
meant, that the old dbus IP[46]Config object was removed and the new one
was exported.

Now instead of recreating a new configuration, it updates the existing
(already exported) configuration in-place.

Also, add new gobject properties 'gateway' and 'searches' to the config class,
they will be exported over dbus.

Also, whenever any of the exported properties changes, make sure that a
notify signal gets emitted.

https://bugzilla.gnome.org/show_bug.cgi?id=707617Signed-off-by: Thomas Haller's avatarThomas Haller <thaller@redhat.com>
parent f0fccd99
......@@ -2,21 +2,15 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP4Config">
<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), ...]
</tp:docstring>
</property>
<property name="Nameservers" type="au" access="read">
<tp:docstring>The nameservers in use.</tp:docstring>
</property>
<property name="WinsServers" type="au" access="read">
<tp:docstring>The Windows Internet Name Service servers associated with the connection. Each address is in network byte order.</tp:docstring>
</property>
<property name="Domains" type="as" access="read">
<tp:docstring>A list of domains this address belongs to.</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
......@@ -24,6 +18,18 @@
[(route, prefix, next-hop, metric), (route, prefix, next-hop, metric), ...]
</tp:docstring>
</property>
<property name="Nameservers" type="au" access="read">
<tp:docstring>The nameservers in use.</tp:docstring>
</property>
<property name="Domains" type="as" access="read">
<tp:docstring>A list of domains this address belongs to.</tp:docstring>
</property>
<property name="Searches" type="as" access="read">
<tp:docstring>A list of dns searches.</tp:docstring>
</property>
<property name="WinsServers" type="au" access="read">
<tp:docstring>The Windows Internet Name Service servers associated with the connection. Each address is in network byte order.</tp:docstring>
</property>
</interface>
</node>
......@@ -2,17 +2,23 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP6Config">
<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>
</property>
<property name="Nameservers" type="aay" access="read">
<tp:docstring>The nameservers in use.</tp:docstring>
</property>
<property name="Domains" type="as" access="read">
<tp:docstring>A list of domains this address belongs to.</tp:docstring>
</property>
<property name="Routes" type="a(ayuayu)" access="read">
<tp:docstring>Tuples of IPv6 route/prefix/next-hop/metric.</tp:docstring>
<property name="Searches" type="as" access="read">
<tp:docstring>A list of dns searches.</tp:docstring>
</property>
</interface>
</node>
......
......@@ -37,19 +37,23 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT)
typedef struct {
DBusGProxy *proxy;
char *gateway;
GSList *addresses;
GSList *routes;
GArray *nameservers;
GPtrArray *domains;
GSList *routes;
GPtrArray *searches;
GArray *wins;
} NMIP4ConfigPrivate;
enum {
PROP_0,
PROP_GATEWAY,
PROP_ADDRESSES,
PROP_ROUTES,
PROP_NAMESERVERS,
PROP_DOMAINS,
PROP_ROUTES,
PROP_SEARCHES,
PROP_WINS_SERVERS,
LAST_PROP
......@@ -90,12 +94,12 @@ demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointe
}
static gboolean
demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
demarshal_string_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
if (!_nm_string_array_demarshal (value, (GPtrArray **) field))
return FALSE;
_nm_object_queue_notify (object, NM_IP4_CONFIG_DOMAINS);
_nm_object_queue_notify (object, pspec->name);
return TRUE;
}
......@@ -119,10 +123,12 @@ register_properties (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
const NMPropertiesInfo property_info[] = {
{ NM_IP4_CONFIG_GATEWAY, &priv->gateway, },
{ NM_IP4_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip4_address_array },
{ NM_IP4_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip4_array },
{ NM_IP4_CONFIG_DOMAINS, &priv->domains, demarshal_domains },
{ NM_IP4_CONFIG_ROUTES, &priv->routes, demarshal_ip4_routes_array },
{ NM_IP4_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip4_array },
{ NM_IP4_CONFIG_DOMAINS, &priv->domains, demarshal_string_array },
{ NM_IP4_CONFIG_SEARCHES, &priv->searches, demarshal_string_array },
{ NM_IP4_CONFIG_WINS_SERVERS, &priv->wins, demarshal_ip4_array },
{ NULL },
};
......@@ -148,6 +154,8 @@ finalize (GObject *object)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
g_free (priv->gateway);
g_slist_foreach (priv->addresses, (GFunc) g_free, NULL);
g_slist_free (priv->addresses);
......@@ -165,6 +173,11 @@ finalize (GObject *object)
g_ptr_array_free (priv->domains, TRUE);
}
if (priv->searches) {
g_ptr_array_foreach (priv->searches, (GFunc) g_free, NULL);
g_ptr_array_free (priv->searches, TRUE);
}
g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object);
......@@ -182,17 +195,23 @@ get_property (GObject *object,
_nm_object_ensure_inited (NM_OBJECT (object));
switch (prop_id) {
case PROP_GATEWAY:
g_value_set_string (value, nm_ip4_config_get_gateway (self));
break;
case PROP_ADDRESSES:
nm_utils_ip4_addresses_to_gvalue (priv->addresses, value);
break;
case PROP_ROUTES:
nm_utils_ip4_routes_to_gvalue (priv->routes, value);
break;
case PROP_NAMESERVERS:
g_value_set_boxed (value, nm_ip4_config_get_nameservers (self));
break;
case PROP_DOMAINS:
g_value_set_boxed (value, nm_ip4_config_get_domains (self));
break;
case PROP_ROUTES:
nm_utils_ip4_routes_to_gvalue (priv->routes, value);
case PROP_SEARCHES:
g_value_set_boxed (value, nm_ip4_config_get_searches (self));
break;
case PROP_WINS_SERVERS:
g_value_set_boxed (value, nm_ip4_config_get_wins_servers (self));
......@@ -217,6 +236,21 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
/* properties */
/**
* NMIP4Config:gateway:
*
* The IP4 gateway address of the configuration as string.
*
* Since: 0.9.10
**/
g_object_class_install_property
(object_class, PROP_GATEWAY,
g_param_spec_string (NM_IP4_CONFIG_GATEWAY,
"Gateway",
"Gateway",
NULL,
G_PARAM_READABLE));
/**
* NMIP4Config:addresses:
*
......@@ -229,6 +263,18 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
"Addresses",
G_PARAM_READABLE));
/**
* NMIP4Config:routes:
*
* The #GPtrArray containing #NMSettingIP4Route<!-- -->s of the configuration.
**/
g_object_class_install_property
(object_class, PROP_ROUTES,
g_param_spec_pointer (NM_IP4_CONFIG_ROUTES,
"Routes",
"Routes",
G_PARAM_READABLE));
/**
* NMIP4Config:nameservers:
*
......@@ -256,15 +302,18 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
G_PARAM_READABLE));
/**
* NMIP4Config:routes:
* NMIP4Config:searches:
*
* The #GPtrArray containing #NMSettingIP4Route<!-- -->s of the configuration.
* The #GPtrArray containing dns search strings of the configuration.
*
* Since: 0.9.10
**/
g_object_class_install_property
(object_class, PROP_ROUTES,
g_param_spec_pointer (NM_IP4_CONFIG_ROUTES,
"Routes",
"Routes",
(object_class, PROP_SEARCHES,
g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES,
"Searches",
"DNS searches",
NM_TYPE_STRING_ARRAY,
G_PARAM_READABLE));
/**
......@@ -299,6 +348,25 @@ nm_ip4_config_new (DBusGConnection *connection, const char *object_path)
NULL);
}
/**
* nm_ip4_config_get_gateway:
* @config: a #NMIP4Config
*
* Gets the IP4 gateway address.
*
* Returns: the IP4 address of the gateway.
*
* Since: 0.9.10
**/
const char *
nm_ip4_config_get_gateway (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
_nm_object_ensure_inited (NM_OBJECT (config));
return NM_IP4_CONFIG_GET_PRIVATE (config)->gateway;
}
/**
* nm_ip4_config_get_addresses:
* @config: a #NMIP4Config
......@@ -353,6 +421,26 @@ nm_ip4_config_get_domains (NMIP4Config *config)
return handle_ptr_array_return (NM_IP4_CONFIG_GET_PRIVATE (config)->domains);
}
/**
* nm_ip4_config_get_searches:
* @config: a #NMIP4Config
*
* Gets the dns searches.
*
* Returns: (element-type utf8): the #GPtrArray containing dns searches as strings. This is the
* internal copy used by the configuration, and must not be modified.
*
* Since: 0.9.10
**/
const GPtrArray *
nm_ip4_config_get_searches (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
_nm_object_ensure_inited (NM_OBJECT (config));
return handle_ptr_array_return (NM_IP4_CONFIG_GET_PRIVATE (config)->searches);
}
/**
* nm_ip4_config_get_wins_servers:
* @config: a #NMIP4Config
......
......@@ -54,20 +54,24 @@ typedef struct {
void (*_reserved6) (void);
} NMIP4ConfigClass;
#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_ROUTES "routes"
#define NM_IP4_CONFIG_SEARCHES "searches"
#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers"
GType nm_ip4_config_get_type (void);
GObject *nm_ip4_config_new (DBusGConnection *connection, const char *object_path);
const char * nm_ip4_config_get_gateway (NMIP4Config *config);
const GSList * nm_ip4_config_get_addresses (NMIP4Config *config);
const GSList * nm_ip4_config_get_routes (NMIP4Config *config);
const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config);
const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config);
const GSList * nm_ip4_config_get_routes (NMIP4Config *config);
const GPtrArray *nm_ip4_config_get_searches (NMIP4Config *config);
const GArray * nm_ip4_config_get_wins_servers (NMIP4Config *config);
G_END_DECLS
......
......@@ -37,18 +37,22 @@ G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_OBJECT)
typedef struct {
DBusGProxy *proxy;
char *gateway;
GSList *addresses;
GSList *routes;
GSList *nameservers;
GPtrArray *domains;
GSList *routes;
GPtrArray *searches;
} NMIP6ConfigPrivate;
enum {
PROP_0,
PROP_GATEWAY,
PROP_ADDRESSES,
PROP_ROUTES,
PROP_NAMESERVERS,
PROP_DOMAINS,
PROP_ROUTES,
PROP_SEARCHES,
LAST_PROP
};
......@@ -108,6 +112,16 @@ demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer
return TRUE;
}
static gboolean
demarshal_searches (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
if (!_nm_string_array_demarshal (value, (GPtrArray **) field))
return FALSE;
_nm_object_queue_notify (object, NM_IP6_CONFIG_SEARCHES);
return TRUE;
}
static gboolean
demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
......@@ -128,10 +142,12 @@ register_properties (NMIP6Config *config)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
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_NAMESERVERS, &priv->nameservers, demarshal_ip6_nameserver_array },
{ NM_IP6_CONFIG_DOMAINS, &priv->domains, demarshal_domains },
{ NM_IP6_CONFIG_ROUTES, &priv->routes, demarshal_ip6_routes_array },
{ NM_IP6_CONFIG_SEARCHES, &priv->searches, demarshal_searches },
{ NULL },
};
......@@ -140,6 +156,25 @@ register_properties (NMIP6Config *config)
property_info);
}
/**
* nm_ip6_config_get_gateway:
* @config: a #NMIP6Config
*
* Gets the IP6 gateway.
*
* Returns: the IPv6 gateway of the configuration.
*
* Since: 0.9.10
**/
const char *
nm_ip6_config_get_gateway (NMIP6Config *config)
{
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
_nm_object_ensure_inited (NM_OBJECT (config));
return NM_IP6_CONFIG_GET_PRIVATE (config)->gateway;
}
/**
* nm_ip6_config_get_addresses:
* @config: a #NMIP6Config
......@@ -197,6 +232,26 @@ nm_ip6_config_get_domains (NMIP6Config *config)
return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->domains);
}
/**
* nm_ip6_config_get_searches:
* @config: a #NMIP6Config
*
* Gets the dns searches.
*
* Returns: (element-type utf8): the #GPtrArray containing dns searches as strings.
* This is the internal copy used by the configuration, and must not be modified.
*
* Since: 0.9.10
**/
const GPtrArray *
nm_ip6_config_get_searches (NMIP6Config *config)
{
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
_nm_object_ensure_inited (NM_OBJECT (config));
return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->searches);
}
/**
* nm_ip6_config_get_routes:
* @config: a #NMIP6Config
......@@ -232,6 +287,8 @@ finalize (GObject *object)
{
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
g_free (priv->gateway);
g_slist_foreach (priv->addresses, (GFunc) nm_ip6_address_unref, NULL);
g_slist_free (priv->addresses);
......@@ -246,6 +303,11 @@ finalize (GObject *object)
g_ptr_array_free (priv->domains, TRUE);
}
if (priv->searches) {
g_ptr_array_foreach (priv->searches, (GFunc) g_free, NULL);
g_ptr_array_free (priv->searches, TRUE);
}
g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object);
......@@ -263,17 +325,23 @@ get_property (GObject *object,
_nm_object_ensure_inited (NM_OBJECT (object));
switch (prop_id) {
case PROP_GATEWAY:
g_value_set_string (value, nm_ip6_config_get_gateway (self));
break;
case PROP_ADDRESSES:
nm_utils_ip6_addresses_to_gvalue (priv->addresses, value);
break;
case PROP_ROUTES:
nm_utils_ip6_routes_to_gvalue (priv->routes, value);
break;
case PROP_NAMESERVERS:
g_value_set_boxed (value, nm_ip6_config_get_nameservers (self));
break;
case PROP_DOMAINS:
g_value_set_boxed (value, nm_ip6_config_get_domains (self));
break;
case PROP_ROUTES:
nm_utils_ip6_routes_to_gvalue (priv->routes, value);
case PROP_SEARCHES:
g_value_set_boxed (value, nm_ip6_config_get_searches (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -300,6 +368,21 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
/* properties */
/**
* NMIP6Config:gateway:
*
* The IPv6 gateway as string
*
* Since: 0.9.10
**/
g_object_class_install_property
(object_class, PROP_ROUTES,
g_param_spec_string (NM_IP6_CONFIG_ROUTES,
"Gateway",
"Gateway",
NULL,
G_PARAM_READABLE));
/**
* NMIP6Config:addresses:
*
......@@ -315,6 +398,21 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
NM_TYPE_IP6_ADDRESS_OBJECT_ARRAY,
G_PARAM_READABLE));
/**
* NMIP6Config:routes:
*
* The #GPtrArray containing the IPv6 routes; use
* nm_utils_ip6_routes_from_gvalue() to return a #GSList of
* #NMSettingIP6Address objects that is more usable than the raw data.
**/
g_object_class_install_property
(object_class, PROP_ROUTES,
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
"Routes",
"Routes",
NM_TYPE_IP6_ROUTE_OBJECT_ARRAY,
G_PARAM_READABLE));
/**
* NMIP6Config:nameservers:
*
......@@ -343,18 +441,19 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
G_PARAM_READABLE));
/**
* NMIP6Config:routes:
* NMIP6Config:searches:
*
* The #GPtrArray containing the IPv6 routes; use
* nm_utils_ip6_routes_from_gvalue() to return a #GSList of
* #NMSettingIP6Address objects that is more usable than the raw data.
* The #GPtrArray containing dns search strings of the configuration.
*
* Since: 0.9.10
**/
g_object_class_install_property
(object_class, PROP_ROUTES,
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
"Routes",
"Routes",
NM_TYPE_IP6_ROUTE_OBJECT_ARRAY,
(object_class, PROP_SEARCHES,
g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES,
"Searches",
"DNS Searches",
NM_TYPE_STRING_ARRAY,
G_PARAM_READABLE));
}
......@@ -54,19 +54,23 @@ typedef struct {
void (*_reserved6) (void);
} NMIP6ConfigClass;
#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_ROUTES "routes"
#define NM_IP6_CONFIG_SEARCHES "searches"
GType nm_ip6_config_get_type (void);
GObject *nm_ip6_config_new (DBusGConnection *connection, const char *object_path);
const char * nm_ip6_config_get_gateway (NMIP6Config *config);
const GSList * nm_ip6_config_get_addresses (NMIP6Config *config);
const GSList * nm_ip6_config_get_routes (NMIP6Config *config);
const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config);
const GPtrArray *nm_ip6_config_get_domains (NMIP6Config *config);
const GSList * nm_ip6_config_get_routes (NMIP6Config *config);
const GPtrArray *nm_ip6_config_get_searches (NMIP6Config *config);
G_END_DECLS
......
......@@ -4558,7 +4558,9 @@ nm_device_set_ip4_config (NMDevice *self,
NMDevicePrivate *priv;
const char *ip_iface;
NMIP4Config *old_config = NULL;
gboolean has_changes = FALSE;
gboolean success = TRUE;
NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
int ip_ifindex;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
......@@ -4570,36 +4572,52 @@ nm_device_set_ip4_config (NMDevice *self,
old_config = priv->ip4_config;
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config)
if (commit && new_config) {
success = nm_ip4_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
if (nm_ip4_config_equal (new_config, old_config))
return success;
priv->ip4_config = NULL;
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
if (new_config) {
if (old_config) {
/* has_changes is set only on relevant changes, because when the configuration changes,
* this causes a re-read and reset. This should only happen for relevant changes */
nm_ip4_config_replace (old_config, new_config, &has_changes);
if (has_changes) {
nm_log_dbg (LOGD_IP4, "(%s): update IP4Config instance (%s)",
ip_iface, nm_ip4_config_get_dbus_path (old_config));
}
} else {
has_changes = TRUE;
priv->ip4_config = g_object_ref (new_config);
if (success || !commit) {
if (success && !nm_ip4_config_get_dbus_path (new_config)) {
/* Export over D-Bus */
if (!nm_ip4_config_get_dbus_path (new_config))
nm_ip4_config_export (new_config);
_update_ip4_address (self);
}
if (!success && reason)
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
} else {
}
} else if (old_config) {
has_changes = TRUE;
priv->ip4_config = NULL;
nm_log_dbg (LOGD_IP4, "(%s): clear IP4Config instance (%s)",
ip_iface, nm_ip4_config_get_dbus_path (old_config));
/* Device config is invalid if combined config is invalid */
g_clear_object (&priv->dev_ip4_config);
}
if (has_changes) {
_update_ip4_address (self);
if (old_config != priv->ip4_config)
g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG);
g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config);
if (old_config)
if (old_config != priv->ip4_config && old_config)
g_object_unref (old_config);
}
if (reason)
*reason = reason_local;
return success;
}
......@@ -4632,7 +4650,9 @@ nm_device_set_ip6_config (NMDevice *self,
NMDevicePrivate *priv;
const char *ip_iface;
NMIP6Config *old_config = NULL;
gboolean has_changes = FALSE;
gboolean success = TRUE;
NMDeviceStateReason reason_local = NM_DEVICE_STATE_REASON_NONE;
int ip_ifindex;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
......@@ -4644,32 +4664,48 @@ nm_device_set_ip6_config (NMDevice *self,
old_config = priv->ip6_config;
/* Always commit to nm-platform to update lifetimes */
if (commit && new_config)
if (commit && new_config) {
success = nm_ip6_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
if (nm_ip6_config_equal (new_config, old_config))
return success;
priv->ip6_config = NULL;
if (!success)
reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
if (new_config) {
if (old_config) {
/* has_changes is set only on relevant changes, because when the configuration changes,
* this causes a re-read and reset. This should only happen for relevant changes */
nm_ip6_config_replace (old_config, new_config, &has_changes);
if (has_changes) {
nm_log_dbg (LOGD_IP6, "(%s): update IP6Config instance (%s)",
ip_iface, nm_ip6_config_get_dbus_path (old_config));
}
} else {
has_changes = TRUE;
priv->ip6_config = g_object_ref (new_config);
if (success || !commit) {
if (success && !nm_ip6_config_get_dbus_path (new_config)) {
/* Export over D-Bus */
if (!nm_ip6_config_get_dbus_path (new_config))
nm_ip6_config_export (new_config);
}
if (!success && reason)
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
} else if (old_config) {
has_changes = TRUE;
priv->ip6_config = NULL;