diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 014c3adde6..8518fd624b 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -10473,152 +10473,58 @@ nm_device_get_ip4_config (NMDevice *self) static gboolean nm_device_set_ip_config (NMDevice *self, int addr_family, - NMIPConfig *_new_config, + NMIPConfig *new_config, gboolean commit, GPtrArray *ip4_dev_route_blacklist) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const gboolean IS_IPv4 = (addr_family == AF_INET); + NMIPConfig *old_config; + gboolean has_changes = FALSE; + gboolean success = TRUE; + NMSettingsConnection *settings_connection; nm_assert_addr_family (addr_family); - nm_assert (!_new_config || nm_ip_config_get_addr_family (_new_config) == addr_family); + nm_assert (!new_config || nm_ip_config_get_addr_family (new_config) == addr_family); + nm_assert ( !new_config + || ( new_config + && ({ + int ip_ifindex = nm_device_get_ip_ifindex (self); - if (IS_IPv4) { - NMIP4Config *new_config = NM_IP4_CONFIG (_new_config); - NMDevicePrivate *priv; - NMIP4Config *old_config = NULL; - gboolean has_changes = FALSE; - gboolean success = TRUE; + ( ip_ifindex > 0 + && ip_ifindex == nm_ip_config_get_ifindex (new_config)); + }))); + nm_assert (IS_IPv4 || !ip4_dev_route_blacklist); - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: update (commit=%d, new-config=%p)", + nm_utils_addr_family_to_char (addr_family), + commit, + new_config); - _LOGD (LOGD_IP4, "ip4-config: update (commit=%d, new-config=%p)", - commit, new_config); + /* Always commit to nm-platform to update lifetimes */ + if (commit && new_config) { - nm_assert ( !new_config - || ( new_config - && ({ - int ip_ifindex = nm_device_get_ip_ifindex (self); + _commit_mtu (self, + IS_IPv4 + ? NM_IP4_CONFIG (new_config) + : priv->ip_config_4); - ( ip_ifindex > 0 - && ip_ifindex == nm_ip4_config_get_ifindex (new_config)); - }))); - - priv = NM_DEVICE_GET_PRIVATE (self); - - old_config = priv->ip_config_4; - - /* Always commit to nm-platform to update lifetimes */ - if (commit && new_config) { - _commit_mtu (self, new_config); - success = nm_ip4_config_commit (new_config, + if (IS_IPv4) { + success = nm_ip4_config_commit (NM_IP4_CONFIG (new_config), nm_device_get_platform (self), - nm_device_get_route_table (self, AF_INET, FALSE) + nm_device_get_route_table (self, addr_family, FALSE) ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN); nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), - nm_ip4_config_get_ifindex (new_config), + nm_ip_config_get_ifindex (new_config), ip4_dev_route_blacklist); - } - - if (new_config) { - if (old_config) { - /* has_changes is set only on relevant changes, because when the configuration changes, - * this causes a re-read and reset. This should only happen for relevant changes */ - nm_ip4_config_replace (old_config, new_config, &has_changes); - if (has_changes) { - _LOGD (LOGD_IP4, "ip4-config: update IP4Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } - } else { - has_changes = TRUE; - priv->ip_config_4 = g_object_ref (new_config); - - if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) - nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); - - _LOGD (LOGD_IP4, "ip4-config: set IP4Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); - } - } else if (old_config) { - has_changes = TRUE; - priv->ip_config_4 = NULL; - _LOGD (LOGD_IP4, "ip4-config: clear IP4Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - /* Device config is invalid if combined config is invalid */ - applied_config_clear (&priv->dev_ip4_config); - } - - concheck_periodic_update (self); - - if (!nm_device_sys_iface_state_is_external_or_assume (self)) - ip4_rp_filter_update (self); - - if (has_changes) { - NMSettingsConnection *settings_connection; - - _update_ip4_address (self); - - if (old_config != priv->ip_config_4) - _notify (self, PROP_IP4_CONFIG); - g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip_config_4, old_config); - - if (old_config != priv->ip_config_4) - nm_dbus_object_clear_and_unexport (&old_config); - - if ( nm_device_sys_iface_state_is_external (self) - && (settings_connection = nm_device_get_settings_connection (self)) - && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED) - && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) { - NMSetting *s_ip4; - - g_object_freeze_notify (G_OBJECT (settings_connection)); - - nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP4_CONFIG); - s_ip4 = nm_ip4_config_create_setting (priv->ip_config_4); - nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip4); - - g_object_thaw_notify (G_OBJECT (settings_connection)); - } - - nm_device_queue_recheck_assume (self); - } - - return success; - } else { - NMIP6Config *new_config = NM_IP6_CONFIG (_new_config); - NMDevicePrivate *priv; - NMIP6Config *old_config = NULL; - gboolean has_changes = FALSE; - gboolean success = TRUE; - - g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - - _LOGD (LOGD_IP6, "ip6-config: update (commit=%d, new-config=%p)", - commit, new_config); - - nm_assert ( !new_config - || ( new_config - && ({ - int ip_ifindex = nm_device_get_ip_ifindex (self); - - ( ip_ifindex > 0 - && ip_ifindex == nm_ip6_config_get_ifindex (new_config)); - }))); - - priv = NM_DEVICE_GET_PRIVATE (self); - - old_config = priv->ip_config_6; - - /* Always commit to nm-platform to update lifetimes */ - if (commit && new_config) { + } else { gs_unref_ptrarray GPtrArray *temporary_not_available = NULL; - _commit_mtu (self, priv->ip_config_4); - - success = nm_ip6_config_commit (new_config, + success = nm_ip6_config_commit (NM_IP6_CONFIG (new_config), nm_device_get_platform (self), - nm_device_get_route_table (self, AF_INET6, FALSE) + nm_device_get_route_table (self, addr_family, FALSE) ? NM_IP_ROUTE_TABLE_SYNC_MODE_FULL : NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, &temporary_not_available); @@ -10626,68 +10532,92 @@ nm_device_set_ip_config (NMDevice *self, if (!_rt6_temporary_not_available_set (self, temporary_not_available)) success = FALSE; } + } - if (new_config) { - if (old_config) { - /* has_changes is set only on relevant changes, because when the configuration changes, - * this causes a re-read and reset. This should only happen for relevant changes */ - nm_ip6_config_replace (old_config, new_config, &has_changes); - if (has_changes) { - _LOGD (LOGD_IP6, "ip6-config: update IP6Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); - } - } else { - has_changes = TRUE; - priv->ip_config_6 = g_object_ref (new_config); + old_config = priv->ip_config_x[IS_IPv4]; - if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) - nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); - - _LOGD (LOGD_IP6, "ip6-config: set IP6Config instance (%s)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); - } - } else if (old_config) { - has_changes = TRUE; - priv->ip_config_6 = NULL; - priv->needs_ip6_subnet = FALSE; - _LOGD (LOGD_IP6, "ip6-config: clear IP6Config instance (%s)", + if (new_config && old_config) { + /* has_changes is set only on relevant changes, because when the configuration changes, + * this causes a re-read and reset. This should only happen for relevant changes */ + nm_ip_config_replace (old_config, new_config, &has_changes); + if (has_changes) { + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: update IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); } + } else if (new_config /*&& !old_config*/) { + has_changes = TRUE; + priv->ip_config_x[IS_IPv4] = g_object_ref (new_config); + if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) + nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); - if (has_changes) { - NMSettingsConnection *settings_connection; + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: set IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), + nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); + } else if (old_config /*&& !new_config*/) { + has_changes = TRUE; + priv->ip_config_x[IS_IPv4] = NULL; + _LOGD (LOGD_IP_from_af (addr_family), + "ip%c-config: clear IP Config instance (%s)", + nm_utils_addr_family_to_char (addr_family), + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); + if (IS_IPv4) { + /* Device config is invalid if combined config is invalid */ + applied_config_clear (&priv->dev_ip4_config); + } else + priv->needs_ip6_subnet = FALSE; + } - if (old_config != priv->ip_config_6) - _notify (self, PROP_IP6_CONFIG); - g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip_config_6, old_config); + if (IS_IPv4) { + concheck_periodic_update (self); - if (old_config != priv->ip_config_6) - nm_dbus_object_clear_and_unexport (&old_config); + if (!nm_device_sys_iface_state_is_external_or_assume (self)) + ip4_rp_filter_update (self); + } - if ( nm_device_sys_iface_state_is_external (self) - && (settings_connection = nm_device_get_settings_connection (self)) - && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), - NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED) - && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) { - NMSetting *s_ip6; + if (has_changes) { - g_object_freeze_notify (G_OBJECT (settings_connection)); + if (IS_IPv4) + _update_ip4_address (self); - nm_connection_remove_setting (NM_CONNECTION (settings_connection), NM_TYPE_SETTING_IP6_CONFIG); - s_ip6 = nm_ip6_config_create_setting (priv->ip_config_6); - nm_connection_add_setting (NM_CONNECTION (settings_connection), s_ip6); + if (old_config != priv->ip_config_x[IS_IPv4]) + _notify (self, IS_IPv4 ? PROP_IP4_CONFIG : PROP_IP6_CONFIG); - g_object_thaw_notify (G_OBJECT (settings_connection)); - } + g_signal_emit (self, + signals[IS_IPv4 ? IP4_CONFIG_CHANGED : IP6_CONFIG_CHANGED], + 0, + priv->ip_config_x[IS_IPv4], + old_config); - nm_device_queue_recheck_assume (self); + if (old_config != priv->ip_config_x[IS_IPv4]) + nm_dbus_object_clear_and_unexport (&old_config); + if ( nm_device_sys_iface_state_is_external (self) + && (settings_connection = nm_device_get_settings_connection (self)) + && NM_FLAGS_HAS (nm_settings_connection_get_flags (settings_connection), + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED) + && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request)) == NM_ACTIVATION_TYPE_EXTERNAL) { + g_object_freeze_notify (G_OBJECT (settings_connection)); + nm_connection_add_setting (NM_CONNECTION (settings_connection), + IS_IPv4 + ? nm_ip4_config_create_setting (priv->ip_config_4) + : nm_ip6_config_create_setting (priv->ip_config_6)); + g_object_thaw_notify (G_OBJECT (settings_connection)); + } + + nm_device_queue_recheck_assume (self); + + if (!IS_IPv4) { if (priv->ndisc) ndisc_set_router_config (priv->ndisc, self); } - - return success; } + + nm_assert (!old_config || old_config == priv->ip_config_x[IS_IPv4]); + + return success; } static gboolean