I've got the following setup:

  • My Windows 7 development box (or a freshly installed Windows 7 VM)
  • A Windows Embedded CE 6.0 based device with IPv6 enabled and a web server running
  • A USB RNDIS connection between the two

On both sides of the connection, there is a link-local IPv6 address configured automatically as expected and I can ping in both directions using the scope ID. I can enter the device's IPv6 address URI with the scope ID into Internet Explorer and can connect to the web server immediately.

However, having to input the scope ID is not the way IPv6 is expected to work for a user and consequently, Firefox does not support IPv6 address URIs with a scope ID. But: Connecting to the web server without the scope ID is very unreliable and I get a lot of connection timeouts in IE / Firefox and several retries with cygwin's wget.

Here is what I have found out so far

  • There is no other adapter configured to have the Windows CE's link-local IPv6 address on any of the other networks attached to my computer (Ethernet, VMware adapters…)
  • When the neighbor cache (netsh interface ipv6 show neighbors) shows the IPv6 address on the RNDIS interface as "Reachable", the web server connection succeeds immediately. I can trigger this by doing a ping prior to the browser request.
  • When the neighbor cache shows the IPv6 address on the RNDIS interface as "Stale", the connection times out. The other interfaces show the IPv6 address in various states: Usually "Unreachable" and "Incomplete".
  • I can watch the RNDIS interface with Wireshark while wget goes through several retries. There is no traffic on the interface besides ICPMv6 "Multicast Listener Report Message v2", LLMNR "Standard query" and DHCPv6 "Solicit", all originating from my PC. Then by the third or fourth retry of wget, there is an ICMPv6 "Neighbor solicitation" which the Windows CE device immediately responds to with a "Neighbor advertisement". This is when wget finally TCP-connects to the web server and downloads the requested page.
  • By that time, the neighbor cache shows the IPv6 address as Reachable and immediate subsequent requests succeed as well
  • While wget tries to connect to the web server, there are various Neighbor solicitation requests on my other interfaces

MSDN documents going through the interfaces one at a time when trying to find a neighbor, so I can understand the Neighbor solicitation requests on the other interfaces in principle, but I cannot believe that this is the way IPv6 Neighbor discovery is expected to work.

Is there a good way to make this scenario work reliably?

  • 1
    Don't use link-local addresses for this purpose. That's not what they're for. – David Schwartz Apr 24 '12 at 8:37

With link-local addresses, you must use the scope ID. The addresses are meaningless without it. It should not have been possible for you to get it to work at all without the scope ID.

In response to the comment from David Schwartz, there's no problem with using link-local addresses for this purpose, and it should work fine. It's especially useful for a web server running on an embedded appliance. I've used this for example to access a web server running on an embedded appliance for maintenance with a back-to-back ethernet connection to the appliance from a laptop. There were no other IP addresses on the wire but link-local.

But you're right: browsers have trouble with it. I believe that some older versions of Firefox work and newer ones don't. This is a bug in Firefox. Incidentally, it is a bug in Google Chrome too.

There's nothing you can do to make this reliable until the browser makers fix the bug. When I've needed to, I've managed to work around it with a port forward (e.g. ssh or socat).

  • Thanks, especially for the links. How are users supposed to learn about the scope ID of their interface, for example in Windows – Kai Ruhnau Apr 25 '12 at 12:14
  • I don't know about Windows specifically, but normally you can use the name of the interface for the scope ID, for example "eth0". Internally this gets translated to a small integer, and you can use that integer directly too, but the name is probably more user friendly. – Celada Apr 25 '12 at 13:47
  • To overcome the problems with link-local addresses, I now have generated a uniqe local prefix which gets advertised by the device. For added convenience (unique local + EUI-64 = lots of bits set), there is also an AAAA record in the device's DNS. – Kai Ruhnau Apr 26 '12 at 14:08
  • You might also expect to learn the link-local address (with scope) from a service discovery system of some kind. So the user would just see a link. – mcr Aug 29 '15 at 16:57
  • That's true, @mcr, resolving a mDNS/DNS-SD/zeroconf/Bonjour name to a link-local IP address works perfectly well. – Celada Aug 30 '15 at 7:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.