diff options
Diffstat (limited to 'src/nm-policy.c')
| -rw-r--r-- | src/nm-policy.c | 175 |
1 files changed, 105 insertions, 70 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index 55b6caf6..2bf25d50 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -337,7 +337,7 @@ device_ip6_prefix_delegated (NMDevice *device, /* Allocate a delegation delegation for new prefix. */ g_array_set_size (priv->ip6_prefix_delegations, i + 1); delegation = &g_array_index (priv->ip6_prefix_delegations, IP6PrefixDelegation, i); - delegation->subnets = g_hash_table_new (nm_direct_hash, NULL); + delegation->subnets = g_hash_table_new (NULL, NULL); delegation->next_subnet = 0; } @@ -385,8 +385,7 @@ get_best_ip_device (NMPolicy *self, gboolean fully_activated) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + const GSList *iter; NMDevice *best_device; NMDevice *prev_device; guint32 best_metric = G_MAXUINT32; @@ -401,7 +400,8 @@ get_best_ip_device (NMPolicy *self, ? (fully_activated ? priv->default_device4 : priv->activating_device4) : (fully_activated ? priv->default_device6 : priv->activating_device6); - nm_manager_for_each_device (priv->manager, device, tmp_lst) { + for (iter = nm_manager_get_devices (priv->manager); iter; iter = iter->next) { + NMDevice *device = NM_DEVICE (iter->data); NMDeviceState state; const NMPObject *r; NMConnection *connection; @@ -418,7 +418,7 @@ get_best_ip_device (NMPolicy *self, r = nm_device_get_best_default_route (device, addr_family); if (r) { - /* NOTE: the best route might have rt_source NM_IP_CONFIG_SOURCE_VPN, + /* XXX: the best route might have rt_source NM_IP_CONFIG_SOURCE_VPN, * which means it was injected by a VPN, not added by device. * * In this case, is it really the best device? Why do we even need the best @@ -461,15 +461,15 @@ static gboolean all_devices_not_active (NMPolicy *self) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + const GSList *iter = nm_manager_get_devices (priv->manager); - nm_manager_for_each_device (priv->manager, device, tmp_lst) { + while (iter != NULL) { NMDeviceState state; - state = nm_device_get_state (device); + state = nm_device_get_state (NM_DEVICE (iter->data)); if ( state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING) { + iter = g_slist_next (iter); continue; } return FALSE; @@ -1065,19 +1065,22 @@ update_ip_dns (NMPolicy *self, int addr_family) gpointer ip_config; const char *ip_iface = NULL; NMVpnConnection *vpn = NULL; + NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; nm_assert_addr_family (addr_family); ip_config = get_best_ip_config (self, addr_family, &ip_iface, NULL, NULL, &vpn); if (ip_config) { + if (vpn) + dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; + /* Tell the DNS manager this config is preferred by re-adding it with * a different IP config type. */ - nm_dns_manager_set_ip_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, + nm_dns_manager_add_ip_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, + ip_iface, ip_config, - vpn - ? NM_DNS_IP_CONFIG_TYPE_VPN - : NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE); + dns_type); } if (addr_family == AF_INET6) @@ -1192,7 +1195,7 @@ auto_activate_device (NMPolicy *self, gs_free NMSettingsConnection **connections = NULL; guint i, len; gs_free_error GError *error = NULL; - gs_unref_object NMAuthSubject *subject = NULL; + NMAuthSubject *subject; NMActiveConnection *ac; nm_assert (NM_IS_POLICY (self)); @@ -1269,11 +1272,13 @@ auto_activate_device (NMPolicy *self, * activation fails in early stages without changing device * state. */ - if (g_hash_table_add (priv->pending_active_connections, ac)) { + if (nm_g_hash_table_add (priv->pending_active_connections, ac)) { g_signal_connect (ac, NM_ACTIVE_CONNECTION_STATE_CHANGED, G_CALLBACK (pending_ac_state_changed), g_object_ref (self)); g_object_weak_ref (G_OBJECT (ac), (GWeakNotify) pending_ac_gone, self); } + + g_object_unref (subject); } static gboolean @@ -1357,7 +1362,7 @@ process_secondaries (NMPolicy *self, if (connected) { _LOGD (LOGD_DEVICE, "secondary connection '%s' succeeded; active path '%s'", nm_active_connection_get_settings_connection_id (active), - nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); + nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); /* Secondary connection activated */ secondary_data->secondaries = g_slist_remove (secondary_data->secondaries, secondary_active); @@ -1373,7 +1378,7 @@ process_secondaries (NMPolicy *self, } else { _LOGD (LOGD_DEVICE, "secondary connection '%s' failed; active path '%s'", nm_active_connection_get_settings_connection_id (active), - nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); + nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); /* Secondary connection failed -> do not watch other connections */ priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data); @@ -1669,7 +1674,7 @@ activate_secondary_connections (NMPolicy *self, ac = nm_manager_activate_connection (priv->manager, settings_con, NULL, - nm_dbus_object_get_path (NM_DBUS_OBJECT (req)), + nm_exported_object_get_path (NM_EXPORTED_OBJECT (req)), device, nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)), NM_ACTIVATION_TYPE_MANAGED, @@ -1708,6 +1713,7 @@ device_state_changed (NMDevice *device, NMPolicy *self = _PRIV_TO_SELF (priv); NMActiveConnection *ac; NMSettingsConnection *connection = nm_device_get_settings_connection (device); + const char *ip_iface = nm_device_get_ip_iface (device); NMIP4Config *ip4_config; NMIP6Config *ip6_config; NMSettingConnection *s_con = NULL; @@ -1804,10 +1810,10 @@ device_state_changed (NMDevice *device, ip4_config = nm_device_get_ip4_config (device); if (ip4_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); ip6_config = nm_device_get_ip6_config (device); if (ip6_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); update_routing_and_dns (self, FALSE); @@ -1900,24 +1906,50 @@ device_state_changed (NMDevice *device, } static void -device_ip_config_changed (NMDevice *device, - NMIPConfig *new_config, - NMIPConfig *old_config, - gpointer user_data) +device_ip4_config_changed (NMDevice *device, + NMIP4Config *new_config, + NMIP4Config *old_config, + gpointer user_data) { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); - int addr_family; + const char *ip_iface = nm_device_get_ip_iface (device); - nm_assert (new_config || old_config); - nm_assert (!new_config || NM_IS_IP_CONFIG (new_config)); - nm_assert (!old_config || NM_IS_IP_CONFIG (old_config)); + nm_dns_manager_begin_updates (priv->dns_manager, __func__); - if (new_config) { - addr_family = nm_ip_config_get_addr_family (new_config); - nm_assert (!old_config || addr_family == nm_ip_config_get_addr_family (old_config)); - } else - addr_family = nm_ip_config_get_addr_family (old_config); + /* We catch already all the IP events registering on the device state changes but + * the ones where the IP changes but the device state keep stable (i.e., activated): + * ignore IP config changes but when the device is in activated state. + * Prevents unecessary changes to DNS information. + */ + if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { + if (old_config != new_config) { + if (old_config) + nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); + if (new_config) + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + } + update_ip_dns (self, AF_INET); + update_ip4_routing (self, TRUE); + update_system_hostname (self, "ip4 conf"); + } else { + /* Old configs get removed immediately */ + if (old_config) + nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); + } + + nm_dns_manager_end_updates (priv->dns_manager, __func__); +} + +static void +device_ip6_config_changed (NMDevice *device, + NMIP6Config *new_config, + NMIP6Config *old_config, + gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy *self = _PRIV_TO_SELF (priv); + const char *ip_iface = nm_device_get_ip_iface (device); nm_dns_manager_begin_updates (priv->dns_manager, __func__); @@ -1928,24 +1960,18 @@ device_ip_config_changed (NMDevice *device, */ if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { if (old_config != new_config) { - if (new_config) - nm_dns_manager_set_ip_config (priv->dns_manager, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); if (old_config) - nm_dns_manager_set_ip_config (priv->dns_manager, old_config, NM_DNS_IP_CONFIG_TYPE_REMOVED); + nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); + if (new_config) + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); } - update_ip_dns (self, addr_family); - if (addr_family == AF_INET) - update_ip4_routing (self, TRUE); - else - update_ip6_routing (self, TRUE); - update_system_hostname (self, - addr_family == AF_INET - ? "ip4 conf" - : "ip6 conf"); + update_ip_dns (self, AF_INET6); + update_ip6_routing (self, TRUE); + update_system_hostname (self, "ip6 conf"); } else { /* Old configs get removed immediately */ if (old_config) - nm_dns_manager_set_ip_config (priv->dns_manager, old_config, NM_DNS_IP_CONFIG_TYPE_REMOVED); + nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); } nm_dns_manager_end_updates (priv->dns_manager, __func__); @@ -1988,8 +2014,8 @@ devices_list_register (NMPolicy *self, NMDevice *device) /* Connect state-changed with _after, so that the handler is invoked after other handlers. */ g_signal_connect_after (device, NM_DEVICE_STATE_CHANGED, (GCallback) device_state_changed, priv); - g_signal_connect (device, NM_DEVICE_IP4_CONFIG_CHANGED, (GCallback) device_ip_config_changed, priv); - g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip_config_changed, priv); + g_signal_connect (device, NM_DEVICE_IP4_CONFIG_CHANGED, (GCallback) device_ip4_config_changed, priv); + g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip6_config_changed, priv); g_signal_connect (device, NM_DEVICE_IP6_PREFIX_DELEGATED, (GCallback) device_ip6_prefix_delegated, priv); g_signal_connect (device, NM_DEVICE_IP6_SUBNET_NEEDED, (GCallback) device_ip6_subnet_needed, priv); g_signal_connect (device, "notify::" NM_DEVICE_AUTOCONNECT, (GCallback) device_autoconnect_changed, priv); @@ -2006,7 +2032,7 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) priv = NM_POLICY_GET_PRIVATE (self); - if (!g_hash_table_add (priv->devices, device)) + if (!nm_g_hash_table_add (priv->devices, device)) g_return_if_reached (); devices_list_register (self, device); @@ -2044,16 +2070,21 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); NMIP4Config *ip4_config; NMIP6Config *ip6_config; + const char *ip_iface; nm_dns_manager_begin_updates (priv->dns_manager, __func__); + ip_iface = nm_vpn_connection_get_ip_iface (vpn, TRUE); + + /* Add the VPN connection's IP configs from DNS */ + ip4_config = nm_vpn_connection_get_ip4_config (vpn); if (ip4_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_VPN); + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_VPN); ip6_config = nm_vpn_connection_get_ip6_config (vpn); if (ip6_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_VPN); + nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_VPN); update_routing_and_dns (self, TRUE); @@ -2070,12 +2101,16 @@ vpn_connection_deactivated (NMPolicy *self, NMVpnConnection *vpn) nm_dns_manager_begin_updates (priv->dns_manager, __func__); ip4_config = nm_vpn_connection_get_ip4_config (vpn); - if (ip4_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); + if (ip4_config) { + /* Remove the VPN connection's IP4 config from DNS */ + nm_dns_manager_remove_ip_config (priv->dns_manager, ip4_config); + } ip6_config = nm_vpn_connection_get_ip6_config (vpn); - if (ip6_config) - nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); + if (ip6_config) { + /* Remove the VPN connection's IP6 config from DNS */ + nm_dns_manager_remove_ip_config (priv->dns_manager, ip6_config); + } update_routing_and_dns (self, TRUE); @@ -2185,13 +2220,12 @@ schedule_activate_all_cb (gpointer user_data) { NMPolicy *self = user_data; NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + const GSList *iter; priv->schedule_activate_all_id = 0; - nm_manager_for_each_device (priv->manager, device, tmp_lst) - schedule_activate_check (self, device); + for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) + schedule_activate_check (self, iter->data); return G_SOURCE_REMOVE; } @@ -2225,8 +2259,7 @@ firewall_state_changed (NMFirewallManager *manager, { NMPolicy *self = (NMPolicy *) user_data; NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const CList *tmp_lst; - NMDevice *device; + const GSList *iter; if (initialized_now) { /* the firewall manager was initializing, but all requests @@ -2239,8 +2272,8 @@ firewall_state_changed (NMFirewallManager *manager, return; /* add interface of each device to correct zone */ - nm_manager_for_each_device (priv->manager, device, tmp_lst) - nm_device_update_firewall_zone (device); + for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) + nm_device_update_firewall_zone (iter->data); } static void @@ -2285,13 +2318,14 @@ connection_updated (NMSettings *settings, { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); - const CList *tmp_lst; + const GSList *iter; NMDevice *device = NULL; - NMDevice *dev; if (by_user) { /* find device with given connection */ - nm_manager_for_each_device (priv->manager, dev, tmp_lst) { + for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) { + NMDevice *dev = NM_DEVICE (iter->data); + if (nm_device_get_settings_connection (dev) == connection) { device = dev; break; @@ -2319,9 +2353,10 @@ _deactivate_if_active (NMPolicy *self, NMSettingsConnection *connection) nm_assert (NM_IS_SETTINGS_CONNECTION (connection)); nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { + NMActiveConnectionState state = nm_active_connection_get_state (ac); if ( nm_active_connection_get_settings_connection (ac) == connection - && (nm_active_connection_get_state (ac) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) { + && (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) { if (!nm_manager_deactivate_connection (priv->manager, ac, NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, @@ -2356,7 +2391,7 @@ connection_flags_changed (NMSettings *settings, NMPolicy *self = _PRIV_TO_SELF (priv); if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), - NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) { + NM_SETTINGS_CONNECTION_FLAGS_VISIBLE)) { if (!nm_settings_connection_autoconnect_is_blocked (connection)) schedule_activate_all (self); } else @@ -2488,8 +2523,8 @@ nm_policy_init (NMPolicy *self) else /* default - full mode */ priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_FULL; - priv->devices = g_hash_table_new (nm_direct_hash, NULL); - priv->pending_active_connections = g_hash_table_new (nm_direct_hash, NULL); + priv->devices = g_hash_table_new (NULL, NULL); + priv->pending_active_connections = g_hash_table_new (NULL, NULL); priv->ip6_prefix_delegations = g_array_new (FALSE, FALSE, sizeof (IP6PrefixDelegation)); g_array_set_clear_func (priv->ip6_prefix_delegations, clear_ip6_prefix_delegation); } |