[PATCH] Don't allow Managed DHCPv6 to short-circuit SLAAC



NetworkManager currently operates on the assumption that Managed
(Stateful) DHCPv6 preempts SLAAC. This is not the case; Managed DHCPv6
and SLAAC are completely orthogonal. My consumer-grade xDSL CPE (a ZyXEL
P-2812HNU-F3) does both at the same time by default, which is a
necessity to trigger the following bug:

Currently NetworkManager will abandon SLAAC activation if it sees that
Managed DHCPv6 is requested by the RA. As far as I have been able to
understand, this makes NetworkManager overlook the kernel-configured
SLAAC address, which in turn makes sync_addresses() remove it again at
a later stage, as it's being considered as an "unwanted alien" of some
sort.

However, right after the device activation has finished,
nm_ip6_device_sync_from_netlink() is run, which notices that the SLAAC
address has vanished, and figures (incorrectly) that it must have been
because the Valid Lifetime has reached zero and that the kernel has
therefore removed it. In response, nm_ip6_device_sync_from_netlink()
deactivates the entire interface, and the activation process starts over
again. Given enough attempts (more than a dozen most of the time, and
sometimes more than fifty has been necessary) NM will eventually manage
to permanently activate the interface, though I don't know exactly what
conditions are necessary for the activation to be a lasting success.

This patch fixes the problem completely for me, the device is now being
successfully activated on the first attempt every single time. It simply
removes the flawed assumption that Managed DHCPv6 short-circuits SLAAC,
and makes NM complete the SLAAC process regardless of Managed DHCPv6
being requested or not.

See: https://bugzilla.redhat.com/show_bug.cgi?id=720188

diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c
index 4a5dee5..a4f8c9a 100644
--- a/src/ip6-manager/nm-ip6-manager.c
+++ b/src/ip6-manager/nm-ip6-manager.c
@@ -474,12 +474,7 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
 	}
 
 	if (!device->addrconf_complete) {
-		/* Managed mode (ie DHCP only) short-circuits automatic addrconf, so
-		 * we don't bother waiting for the device's target state to be reached
-		 * when the RA requests managed mode.
-		 */
-		if (   (device->state >= device->target_state)
-		    || (dhcp_opts == IP6_DHCP_OPT_MANAGED)) {
+		if (device->state >= device->target_state) {
 			/* device->finish_addrconf_id may currently be a timeout
 			 * rather than an idle, so we remove the existing source.
 			 */

-- 
Tore Anderson


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]