One of the projects that I began early last year is an IPv6 rollout across our entire worldwide network. During the initial heady days of the project, I managed to get the infrastructure largely configured in a dual-stack arrangement. Then something came up. I can’t remember exactly what, at this point, but something did, and so the project sat. And sat. And sat some more.
Earlier this week, I reviewed the appalling (lack of) progress so far and began moving forward. I had already completed the acquisition of Provider Independent Address Space (PI), getting our upstream providers to advertise the routes, and the setting up of 90% of the infrastructure (SVI addressing, the different IPv6 settings like IPv6 CEF and unicast-routing, etc.) Everything here worked as expected.
I decided to start with the infrastructure more related to the client side, including servers of interest (DNS, AD, mail, etc.) to the inside, and the end-user workstations. It should be noted here that we had IPv6 turned off on all workstations and servers, despite Microsoft’s best practices which state that IPv6 should be left on because several services will break with it off. Since these services (Homegroups, for one) don’t really apply in a corporate environment, I didn’t care too much what their best practices recommended. The first step was to turn IPv6 on for a few test machines in the IT VLAN, and a couple of the Active Directory servers.
The good news is that the servers came up and were happy as soon as they got their addresses. We’re going with a scheme of static assignment for servers, infrastructure management addresses, etc., so all I really had to do was click the checkbox for IPv6 (these are Windows 2008 R2 servers), assign address and gateway, and voila, we had reachability. Next, I fixed up some DNS settings, added some AAAA records (the IPv6 equivalent of IPv4 A records), and we had DNS resolution on IPv6 working as well.
Windows 7 wouldn’t prove to be quite as easy, for a few reasons. While the checkboxes and settings are ostensibly the same, some of the back-end code is obviously different and needs some non-obvious tweaking to get right. I couldn’t for the life of me figure out why I had no reachability, when the configuration should actually be easy as pie (stateless auto configuration–just “turn on” IPv6 and walk away). In fact, I ended up testing my Macbook Pro and a Linux machine, and both of them worked as expected right out of the gate, so I knew this was a Windows 7 problem.
The first thing that occurred to me after testing the other non-Windows machines was domain policies. We have a lot of them, and you never know what might be causing issues. I had one of my Server guys check that, and then check a non-domain Windows 7 machine with the same image (Windows 7 Enterprise), and he came up with no applicable policy problems and the same behavior.
Finally, after spending too much time with Google, I managed to piece together an idea of what was happening. As it turns out, the mechanism by which Windows 7 puts together its interface identifiers is to blame. I found the applicable information in a posting from February, 2010 on a site called itexpertvoice.com, linked to here. It probably won’t surprise anyone to find out that Microsoft screwed up implementing something they helped create (RFC 4941). The command you’ll want to run, from an elevated command prompt (or GPO, SCCM, etc.) is:
netsh interface ipv6 set global randomizeidentifiers=disabled
This takes you back to behavior supported by standards-compliant hardware, and allows your Windows 7 machine to actually use IPv6.
Another command you may want to use, and this is strictly a personal and policy choice, is:
netsh interface ipv6 set privacy disabled
This turns off privacy addressing, an idea also described in RFC 4941. Given the globally unique, routable nature of IPv6, I can see where some people might get squirrelly, but I just don’t see the need. Again, this is something you’ll want to review for your own environment.
Another interesting problem I found, and one more I had to solve before my Windows 7 machines were ready to be released back into the wild, revolves around voice. Specifically, voice VLANs. In a voice-enabled network using Cisco IP telephony, each access port on a switch typically belongs to two VLANs: a voice VLAN and a data VLAN. You plug a phone in, your computer plugs in to a pass-through port on the phone, and each auto-magically gets an IP address in the correct VLAN. Except with IPv6.
I should say, however, it didn’t work that way in my environment. What happened here is that my workstation would actually get an IP address in both the data and the voice VLANs. And, due to the way prefix policy works (more on that in a minute), would use the voice VLAN as the source address in traffic originating from the workstation. The way I solved the problem for now is to turn off IPv6 and take away the IPv6 addressing from all of the voice VLANs (specifically, on the SVIs), since I haven’t gotten to the voice part of the IPv6 project anyway.
I don’t know what’s causing the workstation to get assigned a voice address, but I’m going to continue to look into it. More than likely it has to do with Stateless Auto configuration and ND, but time will tell. In the mean time, what’s this prefix policy thing I mentioned above? Read about it in RFC 3484.
Put simply, IPv6 prefix policy exists because any given interface in IPv6 is going to have several addresses; everything from Unicast to link-local, multicast, and maybe more. So, if I’m a workstation and I want to source traffic outbound on a given interface, which address do I use? Prefix policy helps to solve that problem by “ranking” different addresses on an interface in a standards-specific way.
After reading the RFC, open up an elevated command prompt on your Windows 7 machine and enter the following command to see how your machine is set up:
netsh int ipv6 show prefix policies
and you’ll get something that looks like so:
You can manipulate the order of things here, and add if needed, using the following commands (note these are two commands, but word-wrap is in effect here):
netsh int ipv6 add prefixpolicy=d2a:d00c:b678:ecfb::1/128
precedence 2 label=22
netsh int ipv6 add prefixpolicy=d2a:d00c::b678::/48
precedence 2 label=22
This gives you a matching prefix pair, and says that for all traffic destined for d2a:d00c:b678::/48 network, use the d2a:d00c:b678:ecfb::1/128 address on the interface as the source. In my case, my voice VLAN (applicable hextet: 107) was showing up in the interface prefix list before my data VLAN (applicable hextet: 1ff). I could have used the example above to set the correct precedence, but this isn’t exactly scalable to thousands of phones and workstations, all of which may have a different mix of addresses.
So, we still have the voice VLAN issue to solve, but the Windows 7 machines can now talk comfortably on the network to other workstations and servers, including using SSH, DNS, RDP, and all other major services. A lot of software still isn’t IPv6 compatible, but that’s why we’re in a dual-stack world for the foreseeable future.
Next challenge, if anyone has suggestions? Working around some of the feature non-parity issues mostly in the area of security. For instance, the ASA line as of last check still doesn’t support OSPFv3 or failover via IPv6, and no tools exist that I’m aware of for mapping complex security policy from IPv4 to IPv6, which is why our IPv6 world here still remains sequestered to just our network.
Ideally we’ll have outside traffic allowed and all of our public-facing services running in time for World IPv6 day this year, which happens on June 6th. Mark your calendars!