summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-09-24 15:13:19 -0500
committerThomas Haller <thaller@redhat.com>2015-12-04 12:15:12 +0100
commit0be66bb1ebb0f0ff197c38131bba42dda346df52 (patch)
tree06b3dceadc05ee9316af318b27ed2c4fb66b419b
parentdeb6c5f7143f9f257b79a8c9db724310ef4c9a31 (diff)
downloadNetworkManager-0be66bb1ebb0f0ff197c38131bba42dda346df52.tar.gz
core: add class function for device unrealization
When a device is unrealized, its class-specific properties must also be cleared since the device is no longer valid.
-rw-r--r--src/devices/nm-device-ip-tunnel.c29
-rw-r--r--src/devices/nm-device-tun.c21
-rw-r--r--src/devices/nm-device-vlan.c11
-rw-r--r--src/devices/nm-device-vxlan.c20
-rw-r--r--src/devices/nm-device.c119
-rw-r--r--src/devices/nm-device.h14
-rw-r--r--src/nm-manager.c12
7 files changed, 217 insertions, 9 deletions
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index 746fb170d0..922a3489c1 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -728,6 +728,34 @@ setup (NMDevice *device, NMPlatformLink *plink)
}
static void
+unrealize (NMDevice *device, gboolean remove_resources)
+{
+ NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
+ NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
+ GParamSpec **properties;
+ guint n_properties, i;
+
+ NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->unrealize (device, remove_resources);
+
+ g_clear_object (&priv->parent);
+ priv->parent_ifindex = 0;
+ g_clear_pointer (&priv->local, g_free);
+ g_clear_pointer (&priv->remote, g_free);
+ priv->ttl = 0;
+ priv->tos = 0;
+ priv->path_mtu_discovery = FALSE;
+ g_clear_pointer (&priv->input_key, g_free);
+ g_clear_pointer (&priv->output_key, g_free);
+ priv->encap_limit = 0;
+ priv->flow_label = 0;
+
+ properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties);
+ for (i = 0; i < n_properties; i++)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
+ g_free (properties);
+}
+
+static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
@@ -809,6 +837,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
device_class->create_and_realize = create_and_realize;
device_class->realize = realize;
device_class->setup = setup;
+ device_class->unrealize = unrealize;
device_class->connection_type = NM_SETTING_IP_TUNNEL_SETTING_NAME;
diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c
index 978c1bace3..214b227030 100644
--- a/src/devices/nm-device-tun.c
+++ b/src/devices/nm-device-tun.c
@@ -24,9 +24,9 @@
#include <string.h>
#include <sys/types.h>
+#include "nm-default.h"
#include "nm-device-tun.h"
#include "nm-device-private.h"
-#include "nm-default.h"
#include "nm-platform.h"
#include "nm-device-factory.h"
#include "nm-setting-tun.h"
@@ -265,6 +265,24 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
return TRUE;
}
+static void
+unrealize (NMDevice *device, gboolean remove_resources)
+{
+ NMDeviceTun *self = NM_DEVICE_TUN (device);
+ NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
+ GParamSpec **properties;
+ guint n_properties, i;
+
+ NM_DEVICE_CLASS (nm_device_tun_parent_class)->unrealize (device, remove_resources);
+
+ memset (&priv->props, 0, sizeof (NMPlatformTunProperties));
+
+ properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties);
+ for (i = 0; i < n_properties; i++)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
+ g_free (properties);
+}
+
/**************************************************************/
static void
@@ -349,6 +367,7 @@ nm_device_tun_class_init (NMDeviceTunClass *klass)
device_class->check_connection_compatible = check_connection_compatible;
device_class->create_and_realize = create_and_realize;
device_class->realize = realize;
+ device_class->unrealize = unrealize;
device_class->update_connection = update_connection;
/* properties */
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index 1712a81385..0f7b0d9f80 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -256,6 +256,16 @@ create_and_realize (NMDevice *device,
return TRUE;
}
+static void
+unrealize (NMDevice *device, gboolean remove_resources)
+{
+ NM_DEVICE_CLASS (nm_device_vlan_parent_class)->unrealize (device, remove_resources);
+
+ NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id = 0;
+ g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID);
+ nm_device_vlan_set_parent (NM_DEVICE_VLAN (device), NULL);
+}
+
/******************************************************************/
static NMDeviceCapabilities
@@ -663,6 +673,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
parent_class->create_and_realize = create_and_realize;
parent_class->realize = realize;
parent_class->setup = setup;
+ parent_class->unrealize = unrealize;
parent_class->get_generic_capabilities = get_generic_capabilities;
parent_class->bring_up = bring_up;
parent_class->act_stage1_prepare = act_stage1_prepare;
diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c
index 7fb55f2086..f52d81e0a7 100644
--- a/src/devices/nm-device-vxlan.c
+++ b/src/devices/nm-device-vxlan.c
@@ -22,9 +22,9 @@
#include <string.h>
+#include "nm-default.h"
#include "nm-device-vxlan.h"
#include "nm-device-private.h"
-#include "nm-default.h"
#include "nm-manager.h"
#include "nm-platform.h"
#include "nm-utils.h"
@@ -142,6 +142,23 @@ setup (NMDevice *device, NMPlatformLink *plink)
update_properties (device);
}
+static void
+unrealize (NMDevice *device, gboolean remove_resources)
+{
+ NMDeviceVxlan *self = NM_DEVICE_VXLAN (device);
+ NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self);
+ GParamSpec **properties;
+ guint n_properties, i;
+
+ NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->unrealize (device, remove_resources);
+
+ memset (&priv->props, 0, sizeof (NMPlatformLnkVxlan));
+
+ properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties);
+ for (i = 0; i < n_properties; i++)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
+ g_free (properties);
+}
/**************************************************************/
@@ -231,6 +248,7 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
device_class->link_changed = link_changed;
device_class->setup = setup;
+ device_class->unrealize = unrealize;
/* properties */
g_object_class_install_property
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index d55493fff6..f9607685fd 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1858,6 +1858,103 @@ setup (NMDevice *self, NMPlatformLink *plink)
g_object_thaw_notify (G_OBJECT (self));
}
+static void
+unrealize (NMDevice *self, gboolean remove_resources)
+{
+ int ifindex;
+
+ if (remove_resources) {
+ ifindex = nm_device_get_ifindex (self);
+ if ( ifindex > 0
+ && nm_device_is_software (self))
+ nm_platform_link_delete (NM_PLATFORM_GET, ifindex);
+ }
+}
+
+/**
+ * nm_device_unrealize():
+ * @self: the #NMDevice
+ * @remove_resources: if %TRUE, remove backing resources
+ * @error: location to store error, or %NULL
+ *
+ * Clears any properties that depend on backing resources (kernel devices,
+ * etc) and removes those resources if @remove_resources is %TRUE.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
+{
+ NMDevicePrivate *priv;
+
+ g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+
+ if (!nm_device_is_software (self) || !nm_device_is_real (self)) {
+ g_set_error_literal (error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_NOT_SOFTWARE,
+ "This device is not a software device or is not realized");
+ return FALSE;
+ }
+
+ priv = NM_DEVICE_GET_PRIVATE (self);
+
+ g_return_val_if_fail (priv->iface != NULL, FALSE);
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ if (NM_DEVICE_GET_CLASS (self)->unrealize)
+ NM_DEVICE_GET_CLASS (self)->unrealize (self, remove_resources);
+
+ if (priv->ifindex > 0) {
+ priv->ifindex = 0;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IFINDEX);
+ }
+ priv->ip_ifindex = 0;
+ if (priv->ip_iface) {
+ g_clear_pointer (&priv->ip_iface, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE);
+ }
+ if (priv->driver_version) {
+ g_clear_pointer (&priv->driver_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_DRIVER_VERSION);
+ }
+ if (priv->firmware_version) {
+ g_clear_pointer (&priv->firmware_version, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_FIRMWARE_VERSION);
+ }
+ if (priv->udi) {
+ g_clear_pointer (&priv->udi, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_UDI);
+ }
+ if (priv->hw_addr) {
+ g_clear_pointer (&priv->hw_addr, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS);
+ }
+ if (priv->physical_port_id) {
+ g_clear_pointer (&priv->physical_port_id, g_free);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_PHYSICAL_PORT_ID);
+ }
+
+ g_clear_pointer (&priv->perm_hw_addr, g_free);
+ g_clear_pointer (&priv->initial_hw_addr, g_free);
+
+ priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_CAPABILITIES);
+
+ priv->real = FALSE;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_REAL);
+
+ g_object_thaw_notify (G_OBJECT (self));
+
+ nm_device_state_changed (self,
+ NM_DEVICE_STATE_UNMANAGED,
+ remove_resources ?
+ NM_DEVICE_STATE_REASON_USER_REQUESTED : NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
+
+ return TRUE;
+}
+
/**
* nm_device_notify_new_device_added():
* @self: the #NMDevice
@@ -6471,16 +6568,21 @@ delete_on_deactivate_link_delete (gpointer user_data)
DeleteOnDeactivateData *data = user_data;
NMDevice *self = data->device;
+ _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
+ data->ifindex, data->idle_add_id);
+
if (data->device) {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device);
+ gs_free_error GError *error = NULL;
g_object_remove_weak_pointer (G_OBJECT (data->device), (void **) &data->device);
priv->delete_on_deactivate_data = NULL;
- }
- _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)",
- data->ifindex, data->idle_add_id);
- nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
+ if (!nm_device_unrealize (data->device, TRUE, &error))
+ _LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message);
+ } else
+ nm_platform_link_delete (NM_PLATFORM_GET, data->ifindex);
+
g_free (data);
return FALSE;
}
@@ -6611,6 +6713,8 @@ delete_cb (NMDevice *self,
GError *error,
gpointer user_data)
{
+ GError *local = NULL;
+
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, FALSE, subject, error->message);
@@ -6618,9 +6722,11 @@ delete_cb (NMDevice *self,
}
/* Authorized */
- nm_platform_link_delete (NM_PLATFORM_GET, nm_device_get_ifindex (self));
- g_dbus_method_invocation_return_value (context, NULL);
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DELETE, self, TRUE, subject, NULL);
+ if (nm_device_unrealize (self, TRUE, &local))
+ g_dbus_method_invocation_return_value (context, NULL);
+ else
+ g_dbus_method_invocation_take_error (context, local);
}
static void
@@ -10219,6 +10325,7 @@ nm_device_class_init (NMDeviceClass *klass)
klass->check_connection_available = check_connection_available;
klass->can_unmanaged_external_down = can_unmanaged_external_down;
klass->setup = setup;
+ klass->unrealize = unrealize;
klass->is_up = is_up;
klass->bring_up = bring_up;
klass->take_down = take_down;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 8931b85609..c185184a79 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -183,6 +183,17 @@ typedef struct {
*/
void (*setup) (NMDevice *self, NMPlatformLink *plink);
+ /**
+ * unrealize():
+ * @self: the #NMDevice
+ * @remove_resources: if %TRUE remove backing resources
+ * @error: location to store error, or %NULL
+ *
+ * Clears any properties that depend on backing resources (kernel devices,
+ * etc) and removes those resources if @remove_resources is %TRUE.
+ */
+ void (*unrealize) (NMDevice *self, gboolean remove_resources);
+
/* Hardware state (IFF_UP) */
gboolean (*can_unmanaged_external_down) (NMDevice *self);
gboolean (*is_up) (NMDevice *self);
@@ -466,6 +477,9 @@ gboolean nm_device_create_and_realize (NMDevice *self,
NMConnection *connection,
NMDevice *parent,
GError **error);
+gboolean nm_device_unrealize (NMDevice *device,
+ gboolean remove_resources,
+ GError **error);
gboolean nm_device_get_autoconnect (NMDevice *device);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 4bc0dc3413..5c6bdb2a14 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1949,10 +1949,20 @@ _platform_link_cb_idle (PlatformLinkCbData *data)
platform_link_added (self, data->ifindex, &pllink);
} else {
NMDevice *device;
+ GError *error = NULL;
device = nm_manager_get_device_by_ifindex (self, data->ifindex);
- if (device)
+ if (device) {
+ if (nm_device_is_software (device)) {
+ if (!nm_device_unrealize (device, FALSE, &error)) {
+ nm_log_warn (LOGD_DEVICE, "(%s): failed to unrealize: %s",
+ nm_device_get_iface (device),
+ error->message);
+ g_clear_error (&error);
+ }
+ }
remove_device (self, device, FALSE, TRUE);
+ }
}
g_object_remove_weak_pointer (G_OBJECT (self), (gpointer *) &data->self);
}