GNOME Bugzilla – Bug 656610
RA prefixes and DHCPv6 interaction
Last modified: 2014-10-31 09:49:08 UTC
dhclient apparently hardcodes all address prefixes to /64 which may or may not be correct; we probably want to investigate using the prefix we get from RA (if any) and applying that to the addresses that dhclient returns as long as the network part matches, so that the addresses from DHCP get the same prefix as the RA prefix. Not sure if people depend on always getting a /64 from dhclient though.
DHCP prefix should always be honored, AFAIK.
When DHCPv6 assigns an address, the packets exchanged with the server does not even contain any prefix information, because this information is already available via RA. ISC dhclient 4.2.2 contains the following code snippet (dhc6.c:3902): /* Current practice is that all subnets are /64's, but * some suspect this may not be permanent. */ client_envadd(client, prefix, "ip6_prefixlen", "%d", 64); client_envadd(client, prefix, "ip6_address", "%s", piaddr(addr->address)); The point is that it's common practice to use /64, but certainly not a certainty. The following Debian bug report points out the unreachability problem that occurs when the prefix is set incorrectly. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=661885 I'm seeing the same problem in Ubuntu using 0.9.1. This message also has some notes concerning the difference between address assignment and prefix information: http://www.ietf.org/mail-archive/web/dhcwg/current/msg07420.html One can of course debate if NM should work around this, or if dhclient should emit 128 instead of 64, and let NM continue to use that.
Some notes on Windows 7 behaviour: Neither the "Status" dialog for a network connection or the console output from ipconfig mentions anything like "netmask" or "prefix length" for IPv6, which they do for IPv4. Looking at the routing table it list routes similar to this: 1234:1234::/124 on local link 1234:1234::56/128 on local link with higher metric. The first route matches the prefix received in the RA. The second route matches the assigned IP address. So it seems to me that ignoring the IPv6 prefix length from dhclient and always using 128 instead is a reasonable way to handle this. And should be easy to implement.
The assumed /64 prefix length in dhclient is a bug in ISC DHCP. DHCPv6 IA_NA assignments do not contain any prefix length information, so such assignments are always individual addresses (/128s). If a prefix is to be configured on the link on which the IA_NA address is configured, this must be advertised by the network using the ICMPv6 Router Advertisement mechanism instead. In the absense of a Prefix Information Option in the ICMPv6 RA, no prefix should be configured on the link. So we need either to fix dhclient to send a prefix length of 128, and/or we need to ignore the bogus prefix length information in NM. I'll send a patch to ISC to fix it there, but it might still be a good idea to work around the bug in NM too, in order to get the fix rolled out more quickly. Tore
I just sent a patch to the mailing list: http://mail.gnome.org/archives/networkmanager-list/2012-May/msg00101.html I think it is worth while adding this to NM, as waiting for ISC to fix their end will probably take longer, and in any case the prefix length is hard coded there too - for DHCPv6 IA_NA, the prefix length should always be /128. Tore
(In reply to comment #4) > The assumed /64 prefix length in dhclient is a bug in ISC DHCP. DHCPv6 IA_NA > assignments do not contain any prefix length information, so such assignments > are always individual addresses (/128s). I don't think that's exactly right. The IA_NA doesn't *explicitly* indicate a prefix, but the address has to be "consistent with the DHCP server's knowledge of the network topology, prefix assignment and address assignment policies", meaning it may be implicitly associated with a prefix. So I think a better fix would be to check if the assigned address matches one of the interface's prefixes, and assign a length based on that (and fall back to 128 if there's no match). But also, really, we should not be modifying the routing tables at all based on DHCPv6 responses.
(In reply to comment #6) > I don't think that's exactly right. The IA_NA doesn't *explicitly* indicate a > prefix, but the address has to be "consistent with the DHCP server's knowledge > of the network topology, prefix assignment and address assignment policies", > meaning it may be implicitly associated with a prefix. That's the «appropriate for the link» definition, which, as I understand it, basically states the DHCPv6 server should not hand out any addresses which doesn't belong on the link. For example, it would be inappropriate to for a DHCPv6 server to respond positively to a Confirm message the client might have brought from some other network. The definition is still about the address, singular. > So I think a better fix would be to check if the assigned address matches one > of the interface's prefixes, and assign a length based on that (and fall back > to 128 if there's no match). I suppose you could do that. However, the implementation would be far more complex than simply going with /128s always. For example, what do we do if the on-link prefix expires, but the address is still valid? You'd have to cover this and all other corner cases and adapt the configuration accordingly. Why bother? I don't the benefit. > But also, really, we should not be modifying the routing tables at all based on > DHCPv6 responses. Yep. Implicitly assuming an on-link /64 (any on-link prefix at all really) from a IA_NA as is currently done is without question the wrong thing to do. Treating it like a single address /128 is one way to do it right, and by far the simplest one. Tore
Tore's patch for this pushed as: eb460b70dad82d366d35fa5703c0e79a1389e4d1 dhcp: use /128 as prefix length for IPv6 IA_NA assignments (bgo #656610) (debian #661885) DHCPv6 IA_NA assignments do not contain a prefix length, they are for a single address (/128) only. However, the ISC DHCPv6 client incorrectly assumes IA_NA assignments come with a implicit prefix length of /64, and passes this incorrect information on to NetworkManager, which adds this prefix as a on-link route. This will cause communication failures in certain networks, for example NBMA networks, and in organisations using longer prefix lengths than /64 for their LANs. For more discussion regarding this problem, see RFC 5942 section 5. This patch makes NM ignore the false prefix length attribute provided by the ISC DHCPv6 client, instead setting it to a /128 (single address) in all cases. Note that this does not preclude an on-link prefix from being added by NM if it is being advertised in the correct way, i.e., by including a Prefix Information Option with the L flag set in an ICMPv6 Router Advertisement. For what it's worth I've also sent a patch to ISC to change the hard- coded implicit prefix length value from /64 to /128 in [ISC-Bugs #29468].
I would like to clarify the situation with regard to DHCPv6-leased IPv6 addresses: DHCPv6 does not transfer any associated prefix with a leased IPv6 address, that is within IA_NA and IA_TA identity associations. Please do not mix this up with prefix delegation through IA_PDs which are for completely different tasks. There is clear writing in section 4 of RFC 5942, item 1: The assignment of an IPv6 address -- whether through IPv6 stateless address autoconfiguration [RFC4862], DHCPv6 [RFC3315], or manual configuration -- MUST NOT implicitly cause a prefix derived from that address to be treated as on-link and added to the Prefix List. In principle, NetworkManager even should not create the /128 prefix after all; however, this is probably not of real concern to do still it: it just covers itself.
(In reply to comment #9) > In principle, NetworkManager even should not create the /128 prefix after all; NetworkManager has to set the prefix length for each address it conveys to the kernel. Address prefixes are typically positive integer numbers smaller than the address size in bits (128 for IPv6), leaving two special values 0 and 128 for the prefix. Zero causes a default device route to be installed, which is typically not what you want. Currently our only chance is to install the address with prefix length equal to 128. That results in a kernel-initialized device route for ip-address/128. Testing shows that this route is useless (it's already covered by the 'local' table) but harmless. A /128 prefix cannot be in practice considered an on-link prefix as it doesn't make any other addresses accessible via neighbor discovery protocol. To be honest, in my opinion the concept of address prefix length is only useful for statically assigned addresses. And even then it's (in my opinion) only useful for userspace tools which in turn could install a prefix-less address and a device route in the kernel. IPv6 autoconf in NetworkManager git master works exactly like that. Both RA and DHCP addresses are always /128. Routing table records are added based on RA on-link prefixes. Static IPv4/IPv6 and dynamic IPv4 addresses are sent to the kernel with prefix lengths provided by configuration or DHCPv4.
(In reply to comment #8) > For what it's worth I've also sent a patch to ISC to change the hard- > coded implicit prefix length value from /64 to /128 in [ISC-Bugs #29468]. Upstream commit https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commitdiff;h=9279a3d722b3849b59a4bab17a2cec3b86e73fdc