summary refs log tree commit diff
path: root/src/nm-policy.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-05-11 22:08:45 +0200
committerMichael Biebl <biebl@debian.org>2018-05-11 22:08:45 +0200
commitee9c73a923909e23a649407be77e25235d769e25 (patch)
treee21c923621fa278e737da693df9eb60ea31a6067 /src/nm-policy.c
parentf60117b41d5433be1b4a96d82cd11d0c3dce9b63 (diff)
New upstream version 1.10.8 upstream/1.10.8
Diffstat (limited to 'src/nm-policy.c')
-rw-r--r--src/nm-policy.c175
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);
 }