From 65737d9e482d87f6f87f1fe49d484580d2e89a3f Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 8 Oct 2013 13:51:00 -0400 Subject: [PATCH] devices: use disable_ipv6 as appropriate Set and clear disable_ipv6 on devices as needed to ensure that: 1) devices never get IPv6 link local addresses until they are actually activated 2) devices always lose their IPv6 link local addresses when they are deactivated 3) slaves never get IPv6 link local addresses at all https://bugzilla.gnome.org/show_bug.cgi?id=700414 https://bugzilla.redhat.com/show_bug.cgi?id=1004255 --- src/devices/nm-device.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 11c19cf0a1..c44a4d29c6 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -276,6 +276,9 @@ typedef struct { guint linklocal6_timeout_id; + char * ip6_disable_ipv6_path; + gint ip6_disable_ipv6_save; + char * ip6_accept_ra_path; gint32 ip6_accept_ra_save; @@ -413,15 +416,20 @@ update_ip6_property_paths (NMDevice *self) /* If ip_iface did change, then any values we saved before are irrelevant. */ priv->ip6_accept_ra_save = -1; priv->ip6_use_tempaddr_save = -1; + priv->ip6_disable_ipv6_save = -1; g_free (priv->ip6_accept_ra_path); g_free (priv->ip6_use_tempaddr_path); + g_free (priv->ip6_disable_ipv6_path); } priv->ip6_accept_ra_path = new_path; new_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/use_tempaddr", ip_iface); priv->ip6_use_tempaddr_path = new_path; + + new_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/disable_ipv6", ip_iface); + priv->ip6_disable_ipv6_path = new_path; } static void @@ -436,6 +444,10 @@ save_ip6_properties (NMDevice *self) priv->ip6_use_tempaddr_save = nm_platform_sysctl_get_uint (priv->ip6_use_tempaddr_path); if (priv->ip6_use_tempaddr_save > 2) priv->ip6_use_tempaddr_save = -1; + + priv->ip6_disable_ipv6_save = nm_platform_sysctl_get_uint (priv->ip6_disable_ipv6_path); + if (priv->ip6_disable_ipv6_save > 1) + priv->ip6_disable_ipv6_save = -1; } static void @@ -455,6 +467,12 @@ restore_ip6_properties (NMDevice *self) snprintf (tmp, sizeof (tmp), "%d", priv->ip6_use_tempaddr_save); nm_platform_sysctl_set (priv->ip6_use_tempaddr_path, tmp); } + + if ( priv->ip6_disable_ipv6_save != -1 + && g_file_test (priv->ip6_disable_ipv6_path, G_FILE_TEST_EXISTS)) { + nm_platform_sysctl_set (priv->ip6_disable_ipv6_path, + priv->ip6_disable_ipv6_save ? "1" : "0"); + } } /* @@ -3504,6 +3522,15 @@ act_stage3_ip6_config_start (NMDevice *self, priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE; + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { + if (!priv->master) + restore_ip6_properties (self); + return NM_ACT_STAGE_RETURN_STOP; + } + + /* Re-enable IPv6 on the interface */ + nm_platform_sysctl_set (priv->ip6_disable_ipv6_path, "0"); + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { if (!addrconf6_start (self)) { /* IPv6 might be disabled; allow IPv4 to proceed */ @@ -3520,9 +3547,6 @@ act_stage3_ip6_config_start (NMDevice *self, } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED; ret = dhcp6_start (self, connection, priv->dhcp6_mode, reason); - } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { - restore_ip6_properties (self); - ret = NM_ACT_STAGE_RETURN_STOP; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) { /* New blank config */ *out_config = nm_ip6_config_new (); @@ -4487,6 +4511,7 @@ nm_device_deactivate (NMDevice *self, NMDeviceStateReason reason) aipd_cleanup (self); /* Turn off kernel IPv6 */ + nm_platform_sysctl_set (priv->ip6_disable_ipv6_path, "1"); nm_platform_sysctl_set (priv->ip6_accept_ra_path, "0"); nm_platform_sysctl_set (priv->ip6_use_tempaddr_path, "0"); @@ -5241,6 +5266,7 @@ dispose (GObject *object) g_clear_object (&priv->vpn6_config); g_clear_object (&priv->ext_ip6_config); + g_free (priv->ip6_disable_ipv6_path); g_free (priv->ip6_accept_ra_path); g_free (priv->ip6_use_tempaddr_path); @@ -6143,6 +6169,7 @@ nm_device_state_changed (NMDevice *device, case NM_DEVICE_STATE_UNAVAILABLE: if (old_state == NM_DEVICE_STATE_UNMANAGED) { save_ip6_properties (device); + nm_platform_sysctl_set (priv->ip6_disable_ipv6_path, "1"); nm_platform_sysctl_set (priv->ip6_accept_ra_path, "0"); nm_platform_sysctl_set (priv->ip6_use_tempaddr_path, "0"); }