mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-06 03:50:17 +01:00
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.
This commit is contained in:
parent
deb6c5f714
commit
0be66bb1eb
7 changed files with 217 additions and 9 deletions
|
|
@ -727,6 +727,34 @@ setup (NMDevice *device, NMPlatformLink *plink)
|
|||
update_properties (device);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue