diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 0dc1b700d..d8fa1b3b9 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-bond.c b/src/devices/nm-device-bond.c
index 73ce460a2..f1db8eeac 100644
--- a/src/devices/nm-device-bond.c
+++ b/src/devices/nm-device-bond.c
@@ -57,24 +57,6 @@ get_generic_capabilities (NMDevice *dev)
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
-static gboolean
-is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
-{
- return TRUE;
-}
-
-static gboolean
-check_connection_available (NMDevice *device,
- NMConnection *connection,
- NMDeviceCheckConAvailableFlags flags,
- const char *specific_object)
-{
- /* Connections are always available because the carrier state is determined
- * by the slave carrier states, not the bonds's state.
- */
- return TRUE;
-}
-
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
@@ -631,9 +613,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass)
parent_class->is_master = TRUE;
parent_class->get_generic_capabilities = get_generic_capabilities;
- parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
- parent_class->check_connection_available = check_connection_available;
parent_class->complete_connection = complete_connection;
parent_class->update_connection = update_connection;
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index 58400211b..90950fdfc 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -59,12 +59,6 @@ get_generic_capabilities (NMDevice *dev)
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
-static gboolean
-is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags)
-{
- return TRUE;
-}
-
static gboolean
check_connection_available (NMDevice *device,
NMConnection *connection,
@@ -73,6 +67,9 @@ check_connection_available (NMDevice *device,
{
NMSettingBluetooth *s_bt;
+ if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_available (device, connection, flags, specific_object))
+ return FALSE;
+
s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection);
if (s_bt) {
return nm_bt_vtable_network_server
@@ -80,9 +77,6 @@ check_connection_available (NMDevice *device,
nm_setting_bluetooth_get_bdaddr (s_bt));
}
- /* Connections are always available because the carrier state is determined
- * by the bridge port carrier states, not the bridge's state.
- */
return TRUE;
}
@@ -490,7 +484,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
parent_class->is_master = TRUE;
parent_class->get_generic_capabilities = get_generic_capabilities;
- parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
parent_class->check_connection_available = check_connection_available;
parent_class->complete_connection = complete_connection;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index b27e1ff18..3abf46cb1 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -2246,19 +2246,20 @@ 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)
+ 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);
+ }
return;
-
- 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);
-
- return;
+ }
+ /* fall-through and change state of device */
} else if (priv->is_enslaved && !carrier) {
/* Slaves don't deactivate when they lose carrier; for
* bonds/teams in particular that would be actively
@@ -3790,12 +3791,17 @@ is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- if (priv->carrier || priv->ignore_carrier)
+ if ( priv->carrier
+ || priv->ignore_carrier)
return TRUE;
if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_DEV_AVAILABLE_IGNORE_CARRIER))
return TRUE;
+ /* master types are always available even without carrier. */
+ if (nm_device_is_master (self))
+ return TRUE;
+
return FALSE;
}
@@ -3829,6 +3835,13 @@ nm_device_is_available (NMDevice *self, NMDeviceCheckDevAvailableFlags flags)
return NM_DEVICE_GET_CLASS (self)->is_available (self, flags);
}
+gboolean
+nm_device_ignore_carrier_by_default (NMDevice *self)
+{
+ /* master types ignore-carrier by default. */
+ return nm_device_is_master (self);
+}
+
gboolean
nm_device_get_enabled (NMDevice *self)
{
@@ -11673,6 +11686,12 @@ check_connection_available (NMDevice *self,
return TRUE;
}
+ /* master types are always available even without carrier.
+ * Making connection non-available would un-enslave slaves which
+ * is not desired. */
+ if (nm_device_is_master (self))
+ return TRUE;
+
return FALSE;
}
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 0323a7829..fb87de896 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -493,6 +493,8 @@ NMSetting * nm_device_get_applied_setting (NMDevice *dev, GType setting_ty
void nm_device_removed (NMDevice *self, gboolean unconfigure_ip_config);
+gboolean nm_device_ignore_carrier_by_default (NMDevice *self);
+
gboolean nm_device_is_available (NMDevice *dev, NMDeviceCheckDevAvailableFlags flags);
gboolean nm_device_has_carrier (NMDevice *dev);
diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c
index 298666410..aeb39ebf9 100644
--- a/src/devices/team/nm-device-team.c
+++ b/src/devices/team/nm-device-team.c
@@ -83,24 +83,6 @@ get_generic_capabilities (NMDevice *device)
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
-static gboolean
-is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
-{
- return TRUE;
-}
-
-static gboolean
-check_connection_available (NMDevice *device,
- NMConnection *connection,
- NMDeviceCheckConAvailableFlags flags,
- const char *specific_object)
-{
- /* Connections are always available because the carrier state is determined
- * by the team port carrier states, not the team's state.
- */
- return TRUE;
-}
-
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
@@ -890,9 +872,7 @@ nm_device_team_class_init (NMDeviceTeamClass *klass)
parent_class->is_master = TRUE;
parent_class->create_and_realize = create_and_realize;
parent_class->get_generic_capabilities = get_generic_capabilities;
- parent_class->is_available = is_available;
parent_class->check_connection_compatible = check_connection_compatible;
- parent_class->check_connection_available = check_connection_available;
parent_class->complete_connection = complete_connection;
parent_class->update_connection = update_connection;
parent_class->master_update_slave_connection = master_update_slave_connection;
diff --git a/src/nm-config-data.c b/src/nm-config-data.c
index 8f4d11217..21ad1a734 100644
--- a/src/nm-config-data.c
+++ b/src/nm-config-data.c
@@ -304,15 +304,22 @@ nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device)
{
gs_free char *value = NULL;
gboolean has_match;
+ int m;
g_return_val_if_fail (NM_IS_CONFIG_DATA (self), FALSE);
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
value = nm_config_data_get_device_config (self, NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER, device, &has_match);
if (has_match)
- return nm_config_parse_boolean (value, FALSE);
+ m = nm_config_parse_boolean (value, -1);
+ else
+ m = nm_device_spec_match_list_full (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier, -1);
- return nm_device_spec_match_list (device, NM_CONFIG_DATA_GET_PRIVATE (self)->ignore_carrier);
+ if (NM_IN_SET (m, TRUE, FALSE))
+ return m;
+
+ /* if ignore-carrier is not explicitly configed, then it depends on the device (type). */
+ return nm_device_ignore_carrier_by_default (device);
}
gboolean