From adc756c9bde28dee9e8e2425945afc0ffef339aa Mon Sep 17 00:00:00 2001 From: Nikolay Martynov Date: Thu, 1 Jun 2017 23:57:03 +0200 Subject: device: handle carrier changes for master device differently For master devices, instead of ignoring loss of carrier entirely, handle it. First of all, master devices are now by default ignore-carrier=yes. That means, without explict user configuration in NetworkManager.conf, the previous behavior in carrier_changed() does not change. If the user decides to configure the master device like [device-with-carrier] match-device=type:bond,type:bridge,type:team ignore-carrier=no then, master device will disconnect on carrier loss like regular devices. https://github.com/NetworkManager/NetworkManager/pull/18 Co-authored-by: Thomas Haller --- man/NetworkManager.conf.xml | 9 ++++++++- src/devices/nm-device.c | 47 ++++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 0dc1b700d9..d8fa1b3b95 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -233,7 +233,10 @@ no-auto-default=* if specified (See ). Otherwise, it is a list of matches to specify for which device carrier should be ignored. See for the - syntax how to specify a device. + syntax how to specify a device. Note that master types like + bond, bridge, and team ignore carrier by default. You can however + revert that default using the "except:" specifier (or better, + use the per-device setting instead of the deprecated setting). @@ -839,6 +842,10 @@ unmanaged=1 interfaces will still reflect the actual device state; it's just that NetworkManager will not make use of that information. + + Master types like bond, bridge and team ignore carrier by default, + while other device types react on carrier changes by default. + This setting overwrites the deprecated main.ignore-carrier setting above. diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 866879c2fe..c8b0114afe 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -2246,24 +2246,32 @@ carrier_changed (NMDevice *self, gboolean carrier) return; if (nm_device_is_master (self)) { - /* Bridge/bond/team carrier does not affect its own activation, - * but when carrier comes on, if there are slaves waiting, - * it will restart them. - */ - if (!carrier) - return; - - /* Force master to retry getting ip addresses when carrier - * is restored. */ - if (priv->state == NM_DEVICE_STATE_ACTIVATED) - nm_device_update_dynamic_ip_setup (self); - else { - if (nm_device_activate_ip4_state_in_wait (self)) - nm_device_activate_stage3_ip4_start (self); - if (nm_device_activate_ip6_state_in_wait (self)) - nm_device_activate_stage3_ip6_start (self); + if (carrier) { + /* Force master to retry getting ip addresses when carrier + * is restored. */ + if (priv->state == NM_DEVICE_STATE_ACTIVATED) + nm_device_update_dynamic_ip_setup (self); + else { + if (nm_device_activate_ip4_state_in_wait (self)) + nm_device_activate_stage3_ip4_start (self); + if (nm_device_activate_ip6_state_in_wait (self)) + nm_device_activate_stage3_ip6_start (self); + } + } else { + /* Put master device into DISCONNECTED state if there is + * no carrier. This would mean that all slaves are still + * enslaved. This is nessesary to be able to reconnect + * when carrier appears. + */ + if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { + if ( priv->queued_state.id + && priv->queued_state.state >= NM_DEVICE_STATE_PREPARE) + queued_state_clear (self); + } else { + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_CARRIER); + } } - return; } else if (priv->is_enslaved && !carrier) { /* Slaves don't deactivate when they lose carrier; for @@ -3843,9 +3851,8 @@ nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags) gboolean nm_device_ignore_carrier_by_default (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - return FALSE; + /* master types ignore-carrier by default. */ + return nm_device_is_master (self); } gboolean -- cgit v1.2.1