summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-03-17 10:52:29 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2020-03-17 21:42:42 +0100
commit8fe2046f0858970531a599894683710e66fd22a7 (patch)
tree220e56bc6483905ae6733336d06a7013e4d2b8b5
parent1a387f9ef9b33fdb34bbd986ab9c984996bf6337 (diff)
downloadNetworkManager-8fe2046f0858970531a599894683710e66fd22a7.tar.gz
core: avoid unbound recursion in IPv6 connection sharing
When a device gets a prefix delegation, we call nm_device_use_ip6_subnet() for all other devices that have IPv6 sharing enabled, which changes the current IPv6 configuration and notifies NMPolicy. When updating the DNS configuration in NMPolicy, we should notify all devices except the one that triggered the change. https://bugzilla.redhat.com/show_bug.cgi?id=1488030
-rw-r--r--src/nm-policy.c55
1 files changed, 27 insertions, 28 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 914c965163..312df0abdd 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1003,21 +1003,6 @@ update_ip4_routing (NMPolicy *self, gboolean force_update)
}
static void
-update_ip6_dns_delegation (NMPolicy *self)
-{
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- NMDevice *device;
- NMActiveConnection *ac;
- const CList *tmp_list;
-
- nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
- device = nm_active_connection_get_device (ac);
- if (device && nm_device_needs_ip6_subnet (device))
- nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6));
- }
-}
-
-static void
update_ip6_prefix_delegation (NMPolicy *self)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
@@ -1085,8 +1070,9 @@ update_ip6_routing (NMPolicy *self, gboolean force_update)
}
static void
-update_ip_dns (NMPolicy *self, int addr_family)
+update_ip_dns (NMPolicy *self, int addr_family, NMDevice *changed_device)
{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
gpointer ip_config;
const char *ip_iface = NULL;
NMVpnConnection *vpn = NULL;
@@ -1108,19 +1094,32 @@ update_ip_dns (NMPolicy *self, int addr_family)
device);
}
- if (addr_family == AF_INET6)
- update_ip6_dns_delegation (self);
+ if (addr_family == AF_INET6) {
+ NMActiveConnection *ac;
+ const CList *tmp_list;
+
+ /* Tell devices needing a subnet about the new DNS configuration */
+ nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
+ device = nm_active_connection_get_device (ac);
+ if ( device
+ && device != changed_device
+ && nm_device_needs_ip6_subnet (device))
+ nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6));
+ }
+ }
}
static void
-update_routing_and_dns (NMPolicy *self, gboolean force_update)
+update_routing_and_dns (NMPolicy *self,
+ gboolean force_update,
+ NMDevice *changed_device)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
nm_dns_manager_begin_updates (priv->dns_manager, __func__);
- update_ip_dns (self, AF_INET);
- update_ip_dns (self, AF_INET6);
+ update_ip_dns (self, AF_INET, changed_device);
+ update_ip_dns (self, AF_INET6, changed_device);
update_ip4_routing (self, force_update);
update_ip6_routing (self, force_update);
@@ -1855,14 +1854,14 @@ device_state_changed (NMDevice *device,
if (ip6_config)
_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT, device);
- update_routing_and_dns (self, FALSE);
+ update_routing_and_dns (self, FALSE, device);
nm_dns_manager_end_updates (priv->dns_manager, __func__);
break;
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
- update_routing_and_dns (self, FALSE);
+ update_routing_and_dns (self, FALSE, device);
break;
case NM_DEVICE_STATE_DEACTIVATING:
if (sett_conn) {
@@ -1897,7 +1896,7 @@ device_state_changed (NMDevice *device,
reset_autoconnect_all (self, device, FALSE);
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
- update_routing_and_dns (self, FALSE);
+ update_routing_and_dns (self, FALSE, device);
/* Device is now available for auto-activation */
schedule_activate_check (self, device);
@@ -1928,7 +1927,7 @@ device_state_changed (NMDevice *device,
if ( s_con
&& nm_setting_connection_get_num_secondaries (s_con) > 0) {
/* Make routes and DNS up-to-date before activating dependent connections */
- update_routing_and_dns (self, FALSE);
+ update_routing_and_dns (self, FALSE, device);
/* Activate secondary (VPN) connections */
if (!activate_secondary_connections (self,
@@ -1984,7 +1983,7 @@ device_ip_config_changed (NMDevice *device,
if (old_config)
nm_dns_manager_set_ip_config (priv->dns_manager, old_config, NM_DNS_IP_CONFIG_TYPE_REMOVED);
}
- update_ip_dns (self, addr_family);
+ update_ip_dns (self, addr_family, device);
if (addr_family == AF_INET)
update_ip4_routing (self, TRUE);
else
@@ -2106,7 +2105,7 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *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);
- update_routing_and_dns (self, TRUE);
+ update_routing_and_dns (self, TRUE, NULL);
nm_dns_manager_end_updates (priv->dns_manager, __func__);
}
@@ -2128,7 +2127,7 @@ vpn_connection_deactivated (NMPolicy *self, NMVpnConnection *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);
- update_routing_and_dns (self, TRUE);
+ update_routing_and_dns (self, TRUE, NULL);
nm_dns_manager_end_updates (priv->dns_manager, __func__);
}