diff options
author | Thomas Haller <thaller@redhat.com> | 2014-12-16 22:25:39 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-12-16 22:25:39 +0100 |
commit | 3bb6fe3b74861ff9b8ba7344a767d02465541703 (patch) | |
tree | ad6efbc243e30590f4e9d21d8c0cf2d1786e601a | |
parent | 5cca99074263d8c83cd1c6aff98776979670bb68 (diff) | |
parent | d4ae2ddbde9ad1f4d0791b07ce33ff7222c84ca9 (diff) | |
download | NetworkManager-th/nm-1-0-integration.tar.gz |
Merge branch 'backport-1-0/dcbw/external-managed-iffup-rh1030947' into nm-1-0th/nm-1-0-integration
-rw-r--r-- | src/devices/nm-device.c | 128 | ||||
-rw-r--r-- | src/devices/nm-device.h | 13 | ||||
-rw-r--r-- | src/nm-manager.c | 6 |
3 files changed, 115 insertions, 32 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 3459f4f8d5..3abeadf483 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1153,6 +1153,13 @@ update_for_ip_ifname_change (NMDevice *self) } } +static gboolean +is_software_external (NMDevice *self) +{ + return nm_device_is_software (self) + && !nm_device_get_is_nm_owned (self); +} + static void device_set_master (NMDevice *self, int ifindex) { @@ -1228,10 +1235,41 @@ device_link_changed (NMDevice *self, NMPlatformLink *info) if (klass->link_changed) klass->link_changed (self, info); - /* Update DHCP, etc, if needed */ if (ip_ifname_changed) update_for_ip_ifname_change (self); + + /* Manage externally-created software interfaces only when they are IFF_UP */ + if ( is_software_external (self) + && (nm_device_get_state (self) <= NM_DEVICE_STATE_DISCONNECTED) + && priv->ifindex > 0) { + gboolean external_down = nm_device_get_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN); + + if (external_down && info->up) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume (self); + + /* Resetting the EXTERNAL_DOWN flag may change the device's state + * to UNAVAILABLE. To ensure that the state change doesn't touch + * the device before assumption occurs, pass + * NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED as the reason. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } else if (!external_down && !info->up) { + /* If the device is already disconnected and is set !IFF_UP, + * unmanage it. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + TRUE, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } } static void @@ -5135,7 +5173,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) /* Interface must be IFF_UP before IP config can be applied */ ip_ifindex = nm_device_get_ip_ifindex (self); - if (!nm_platform_link_is_up (ip_ifindex)) { + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { nm_platform_link_set_up (ip_ifindex); if (!nm_platform_link_is_up (ip_ifindex)) _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); @@ -5246,7 +5284,7 @@ nm_device_activate_ip6_config_commit (gpointer user_data) /* Interface must be IFF_UP before IP config can be applied */ ip_ifindex = nm_device_get_ip_ifindex (self); - if (!nm_platform_link_is_up (ip_ifindex)) { + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { nm_platform_link_set_up (ip_ifindex); if (!nm_platform_link_is_up (ip_ifindex)) _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); @@ -6610,7 +6648,7 @@ nm_device_get_managed (NMDevice *self) gboolean nm_device_get_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag) { - return NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags & flag; + return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags, flag); } /** @@ -6702,6 +6740,30 @@ nm_device_set_initial_unmanaged_flag (NMDevice *self, priv->unmanaged_flags &= ~flag; } +/** + * nm_device_update_initial_unmanaged_flags(): + * @self: the #NMDevice + * + * Called before device export to allow the device to set any additional + * unmanaged flags. + */ +void +nm_device_update_initial_unmanaged_flags (NMDevice *self) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + g_return_if_fail (priv->path == NULL); + + /* Do not manage externally created software devices until they are IFF_UP */ + if ( is_software_external (self) + && !nm_platform_link_is_up (priv->ifindex) + && priv->ifindex > 0) + nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN, TRUE); +} + void nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout) { @@ -7356,6 +7418,17 @@ notify_ip_properties (NMDevice *self) } static void +ip6_managed_setup (NMDevice *self) +{ + set_nm_ipv6ll (self, TRUE); + set_disable_ipv6 (self, "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); +} + +static void _set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, @@ -7431,31 +7504,27 @@ _set_state_full (NMDevice *self, case NM_DEVICE_STATE_UNAVAILABLE: if (old_state == NM_DEVICE_STATE_UNMANAGED) { save_ip6_properties (self); - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { - set_nm_ipv6ll (self, TRUE); - set_disable_ipv6 (self, "1"); - nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); - nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); - } + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) + ip6_managed_setup (self); } - if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { - if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) - _LOGW (LOGD_HW, "firmware may be missing."); - nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); - } - /* Ensure the device gets deactivated in response to stuff like - * carrier changes or rfkill. But don't deactivate devices that are - * about to assume a connection since that defeats the purpose of - * assuming the device's existing connection. - * - * Note that we "deactivate" the device even when coming from - * UNMANAGED, to ensure that it's in a clean state. - */ - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { + if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) + _LOGW (LOGD_HW, "firmware may be missing."); + nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); + } + + /* Ensure the device gets deactivated in response to stuff like + * carrier changes or rfkill. But don't deactivate devices that are + * about to assume a connection since that defeats the purpose of + * assuming the device's existing connection. + * + * Note that we "deactivate" the device even when coming from + * UNMANAGED, to ensure that it's in a clean state. + */ nm_device_cleanup (self, reason); + } break; case NM_DEVICE_STATE_DISCONNECTED: if (old_state > NM_DEVICE_STATE_DISCONNECTED) { @@ -7465,6 +7534,13 @@ _set_state_full (NMDevice *self, set_nm_ipv6ll (self, TRUE); nm_device_cleanup (self, reason); + } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + /* Ensure IPv6 is set up as it may not have been done when + * entering the UNAVAILABLE state depending on the reason. + */ + ip6_managed_setup (self); + } } break; case NM_DEVICE_STATE_NEED_AUTH: diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 38eddaa8df..794693f28b 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -304,13 +304,15 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device); * because NM is sleeping or not managed for some other reason) * @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs) * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged + * @NM_UNMANAGED_EXTERNAL_DOWN: %TRUE when unmanaged because !IFF_UP and not created by NM */ typedef enum { - NM_UNMANAGED_NONE = 0x00, - NM_UNMANAGED_DEFAULT = 0x01, - NM_UNMANAGED_INTERNAL = 0x02, - NM_UNMANAGED_USER = 0x04, - NM_UNMANAGED_PARENT = 0x08, + NM_UNMANAGED_NONE = 0x00, + NM_UNMANAGED_DEFAULT = 0x01, + NM_UNMANAGED_INTERNAL = 0x02, + NM_UNMANAGED_USER = 0x04, + NM_UNMANAGED_PARENT = 0x08, + NM_UNMANAGED_EXTERNAL_DOWN = 0x10, /* Boundary value */ __NM_UNMANAGED_LAST, @@ -327,6 +329,7 @@ void nm_device_set_unmanaged_quitting (NMDevice *device); void nm_device_set_initial_unmanaged_flag (NMDevice *device, NMUnmanagedFlags flag, gboolean unmanaged); +void nm_device_update_initial_unmanaged_flags (NMDevice *device); gboolean nm_device_get_is_nm_owned (NMDevice *device); void nm_device_set_nm_owned (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 06f24abdb8..4c5fff5d76 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1653,7 +1653,9 @@ recheck_assume_connection (NMDevice *device, gpointer user_data) if (manager_sleeping (self)) return FALSE; - if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER)) + if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER) || + nm_device_get_unmanaged_flag (device, NM_UNMANAGED_INTERNAL) || + nm_device_get_unmanaged_flag (device, NM_UNMANAGED_PARENT)) return FALSE; state = nm_device_get_state (device); @@ -1818,6 +1820,8 @@ add_device (NMManager *self, NMDevice *device, gboolean try_assume) sleeping = manager_sleeping (self); nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_INTERNAL, sleeping); + nm_device_update_initial_unmanaged_flags (device); + nm_device_dbus_export (device); nm_device_finish_init (device); |