diff options
Diffstat (limited to 'src/core/nm-policy.c')
| -rw-r--r-- | src/core/nm-policy.c | 143 |
1 files changed, 129 insertions, 14 deletions
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 16b0211f..518fc596 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -797,6 +797,20 @@ device_dns_lookup_done(NMDevice *device, gpointer user_data) } static void +device_carrier_changed(NMDevice *device, GParamSpec *pspec, gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy *self = _PRIV_TO_SELF(priv); + gs_free char *msg = NULL; + + if (nm_device_has_carrier(device)) { + g_signal_handlers_disconnect_by_func(device, device_carrier_changed, priv); + msg = g_strdup_printf("device '%s' got carrier", nm_device_get_iface(device)); + update_system_hostname(self, msg); + } +} + +static void update_system_hostname(NMPolicy *self, const char *msg) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); @@ -880,6 +894,7 @@ update_system_hostname(NMPolicy *self, const char *msg) info = &g_array_index(infos, DeviceHostnameInfo, i); addr_family = info->IS_IPv4 ? AF_INET : AF_INET6; g_signal_handlers_disconnect_by_func(info->device, device_dns_lookup_done, self); + g_signal_handlers_disconnect_by_func(info->device, device_carrier_changed, priv); if (info->from_dhcp) { dhcp_config = nm_device_get_dhcp_config(info->device, addr_family); @@ -905,10 +920,18 @@ update_system_hostname(NMPolicy *self, const char *msg) if (priv->hostname_mode != NM_POLICY_HOSTNAME_MODE_DHCP) { if (info->from_dns) { - const char *result; - gboolean wait = FALSE; + const char *result = NULL; + gboolean wait = FALSE; - result = nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait); + if (nm_device_has_carrier(info->device)) { + result = + nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait); + } else { + g_signal_connect(info->device, + "notify::" NM_DEVICE_CARRIER, + G_CALLBACK(device_carrier_changed), + priv); + } if (result) { _set_hostname(self, result, "from address lookup"); return; @@ -1556,6 +1579,7 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); NMSettingsConnection *const *connections = NULL; guint i; + gboolean multiconnect = FALSE; _LOGT(LOGD_DEVICE, "unblocking failed OVS interfaces"); @@ -1563,6 +1587,13 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) for (i = 0; connections[i]; i++) { NMSettingsConnection *sett_conn = connections[i]; NMConnection *connection = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection *s_con = nm_connection_get_setting_connection(connection); + + /* Check if any connection is connect multiple */ + if (s_con + && nm_setting_connection_get_multi_connect(s_con) + == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) + multiconnect = TRUE; if (nm_connection_get_setting_ovs_interface(connection)) { nm_settings_connection_autoconnect_retries_reset(sett_conn); @@ -1572,6 +1603,18 @@ nm_policy_unblock_failed_ovs_interfaces(NMPolicy *self) FALSE); } } + + /* There is, at least, one multiconnect connection with an OVS setting. + * Let's check the OVS devices retries */ + if (multiconnect) { + NMDevice *device; + GHashTableIter h_iter; + g_hash_table_iter_init(&h_iter, priv->devices); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { + if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_OVS_INTERFACE) + nm_device_autoconnect_retries_reset(device); + } + } } static gboolean @@ -1583,7 +1626,8 @@ reset_autoconnect_all( NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); NMSettingsConnection *const *connections = NULL; guint i; - gboolean changed = FALSE; + gboolean changed = FALSE; + gboolean multiconnect = FALSE; _LOGD(LOGD_DEVICE, "re-enabling autoconnect for all connections%s%s%s", @@ -1594,6 +1638,8 @@ reset_autoconnect_all( connections = nm_settings_get_connections(priv->settings, NULL); for (i = 0; connections[i]; i++) { NMSettingsConnection *sett_conn = connections[i]; + NMSettingConnection *s_con = + nm_connection_get_setting_connection(nm_settings_connection_get_connection(sett_conn)); if (device && !nm_device_check_connection_compatible( @@ -1602,6 +1648,11 @@ reset_autoconnect_all( NULL)) continue; + if (s_con + && nm_setting_connection_get_multi_connect(s_con) + == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) + multiconnect = TRUE; + if (only_no_secrets) { /* we only reset the no-secrets blocked flag. */ if (nm_settings_connection_autoconnect_blocked_reason_set( @@ -1630,6 +1681,20 @@ reset_autoconnect_all( } } } + + /* There is, at least, one multiconnect connection. Let's check the devices retries */ + if (multiconnect) { + NMDevice *device_iter; + GHashTableIter h_iter; + g_hash_table_iter_init(&h_iter, priv->devices); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &device_iter, NULL)) { + if (nm_device_get_autoconnect_retries(device_iter) != -2) { + nm_device_autoconnect_retries_reset(device_iter); + changed = TRUE; + } + } + } + return changed; } @@ -1687,7 +1752,8 @@ reset_connections_retries(gpointer user_data) NMSettingsConnection *const *connections = NULL; guint i; gint32 con_stamp, min_stamp, now; - gboolean changed = FALSE; + gboolean changed = FALSE; + gboolean multiconnect = FALSE; priv->reset_retries_id = 0; @@ -1696,6 +1762,14 @@ reset_connections_retries(gpointer user_data) connections = nm_settings_get_connections(priv->settings, NULL); for (i = 0; connections[i]; i++) { NMSettingsConnection *connection = connections[i]; + NMSettingConnection *s_con = + nm_connection_get_setting_connection(nm_settings_connection_get_connection(connection)); + + /* Check if any connection is connect multiple */ + if (s_con + && nm_setting_connection_get_multi_connect(s_con) + == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) + multiconnect = TRUE; con_stamp = nm_settings_connection_autoconnect_retries_blocked_until(connection); if (con_stamp == 0) @@ -1708,6 +1782,25 @@ reset_connections_retries(gpointer user_data) min_stamp = con_stamp; } + /* There is, at least, one multiconnect connection. Let's check the devices retries */ + if (multiconnect) { + NMDevice *device; + GHashTableIter h_iter; + g_hash_table_iter_init(&h_iter, priv->devices); + while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { + con_stamp = nm_device_autoconnect_retries_blocked_until(device); + + /* default value in device is -2, which means, we do not care */ + if (con_stamp <= 0) + continue; + if (con_stamp <= now) { + nm_device_autoconnect_retries_reset(device); + changed = TRUE; + } else if (min_stamp == 0 || min_stamp > con_stamp) + min_stamp = con_stamp; + } + } + /* Schedule the handler again if there are some stamps left */ if (min_stamp != 0) priv->reset_retries_id = @@ -1721,21 +1814,31 @@ reset_connections_retries(gpointer user_data) } static void -_connection_autoconnect_retries_set(NMPolicy *self, NMSettingsConnection *connection, int tries) +_connection_autoconnect_retries_set(NMPolicy *self, + NMSettingsConnection *connection, + NMDevice *device, + int tries) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); + NMSettingConnection *s_con; + gint32 retry_time; nm_assert(NM_IS_SETTINGS_CONNECTION(connection)); nm_assert(tries >= 0); - nm_settings_connection_autoconnect_retries_set(connection, tries); + s_con = nm_connection_get_setting_connection(nm_settings_connection_get_connection(connection)); + if (s_con + && nm_setting_connection_get_multi_connect(s_con) == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) { + nm_device_set_autoconnect_retries(device, tries); + retry_time = nm_device_autoconnect_retries_blocked_until(device); + } else { + nm_settings_connection_autoconnect_retries_set(connection, tries); + retry_time = nm_settings_connection_autoconnect_retries_blocked_until(connection); + } if (tries == 0) { /* Schedule a handler to reset retries count */ if (!priv->reset_retries_id) { - gint32 retry_time = - nm_settings_connection_autoconnect_retries_blocked_until(connection); - g_warn_if_fail(retry_time != 0); priv->reset_retries_id = g_timeout_add_seconds(MAX(0, retry_time - nm_utils_get_monotonic_timestamp_sec()), @@ -1997,13 +2100,25 @@ device_state_changed(NMDevice *device, } if (!blocked) { - tries = nm_settings_connection_autoconnect_retries_get(sett_conn); + s_con = nm_connection_get_setting_connection( + nm_settings_connection_get_connection(sett_conn)); + if (s_con + && nm_setting_connection_get_multi_connect(s_con) + == NM_CONNECTION_MULTI_CONNECT_MULTIPLE) { + if (nm_device_get_autoconnect_retries(device) == -2) + nm_device_set_autoconnect_retries( + device, + nm_settings_connection_autoconnect_retries_get(sett_conn)); + + tries = nm_device_get_autoconnect_retries(device); + } else + tries = nm_settings_connection_autoconnect_retries_get(sett_conn); if (tries > 0) { _LOGD(LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left", nm_settings_connection_get_id(sett_conn), tries - 1); - _connection_autoconnect_retries_set(self, sett_conn, tries - 1); + _connection_autoconnect_retries_set(self, sett_conn, device, tries - 1); } else if (tries != 0) { _LOGD(LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left", @@ -2893,7 +3008,7 @@ dispose(GObject *object) } g_hash_table_iter_init(&h_iter, priv->devices); - if (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { + while (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) { g_hash_table_iter_remove(&h_iter); devices_list_unregister(self, device); } |