From b22a20880e697febc3000de60321106a227a64bf Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 14 Feb 2020 17:46:31 +0100 Subject: [PATCH] ovs: discard link updates when deactivating When the ovs interface gets deactivated, it is released from the master port and we call nm_device_update_from_platform_link (dev, NULL) to ignore any later event for the interface. This is important especially because it sets a zero ifindex on the interface and so, later when the link disappears, we don't unmanage the device but directly remove it. However, since ovs commands are queued, the link could appear during the deactivation and we need to ignore such events. Add a new device method can_update_from_platform_link() for such purpose. (cherry picked from commit e9fc1dea437a3f78212143e8d2b14bcea8926f90) (cherry picked from commit c4eb0c6852d96b82081babe2c16a54df75717aba) (cherry picked from commit 34a9247a640504b15daeab578f569a4a151bfa7d) --- src/devices/nm-device.c | 10 ++++++++++ src/devices/nm-device.h | 2 ++ src/devices/ovs/nm-device-ovs-interface.c | 13 +++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index cf3f0c4987..f966ae6f4c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -4142,6 +4142,12 @@ nm_device_create_and_realize (NMDevice *self, return TRUE; } +static gboolean +can_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) +{ + return TRUE; +} + void nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink) { @@ -4150,6 +4156,9 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink int ifindex; guint32 mtu; + if (!NM_DEVICE_GET_CLASS (self)->can_update_from_platform_link (self, plink)) + return; + g_return_if_fail (plink == NULL || link_type_compatible (self, plink->type, NULL, NULL)); str = plink ? nm_platform_link_get_udi (nm_device_get_platform (self), plink->ifindex) : NULL; @@ -16973,6 +16982,7 @@ nm_device_class_init (NMDeviceClass *klass) klass->get_type_description = get_type_description; klass->can_auto_connect = can_auto_connect; + klass->can_update_from_platform_link = can_update_from_platform_link; klass->check_connection_compatible = check_connection_compatible; klass->check_connection_available = check_connection_available; klass->can_unmanaged_external_down = can_unmanaged_external_down; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index bcbc00bbed..0eab3aca19 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -460,6 +460,8 @@ typedef struct _NMDeviceClass { guint32 (* get_dhcp_timeout) (NMDevice *self, int addr_family); + gboolean (* can_update_from_platform_link) (NMDevice *self, const NMPlatformLink *plink); + /* Controls, whether to call act_stage2_config() callback also for assuming * a device or for external activations. In this case, act_stage2_config() must * take care not to touch the device's configuration. */ diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c index 726637864e..9c74ffd1c2 100644 --- a/src/devices/ovs/nm-device-ovs-interface.c +++ b/src/devices/ovs/nm-device-ovs-interface.c @@ -312,6 +312,18 @@ deactivate_async (NMDevice *device, data); } +static gboolean +can_update_from_platform_link (NMDevice *device, const NMPlatformLink *plink) +{ + /* If the device is deactivating, we already sent the + * deletion command to ovsdb and we don't want to deal + * with any new link appearing from the previous + * activation. + */ + return !plink + || nm_device_get_state (device) != NM_DEVICE_STATE_DEACTIVATING; +} + /*****************************************************************************/ static void @@ -341,6 +353,7 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH); + device_class->can_update_from_platform_link = can_update_from_platform_link; device_class->deactivate = deactivate; device_class->deactivate_async = deactivate_async; device_class->get_type_description = get_type_description;