When we upgraded our datacenters to full native IPv6 we also began to enable IPv6 on our Solaris servers.
What works really well on global Solaris zones and on Solaris LDOMs can be a big pain on shared Solaris zones.
So what is the catch with Solaris zones? When you create a new Solaris zone you can add an IPv6 address easily the same way you add an IPv4 address but as you may know IPv6 needs a so called ‘link-local’ address to work properly or else IPv6 Neighbor Discovery won’t work.
We got 2 problems here. When you use an auto configured route on the global zone the shared zone will know about it (cause they share the network stack) but can’t use it since it is an link-local route and the shared zone don’t have an link-local interface. This problem can easily be avoided by setting a route to a global address in the global zone. Now the shared zone knows about the correct gateway but that is where we get to the second problem. The shared zone can neatly resolve the MAC address of the router via ND but the router can not resolve the MAC address of the zone via ND. When you snoop on the interface on the global zone you will see that the “neighbor solicitation” request arrives on the interface but somehow it is not answered.
So how do we get around the second problem? We have to add another IPv6 address to the shared zone – a link-local one. How does this usually look like? The link-local segment is fe80::/10. Usually the link-local address is generated on an per interface basis the following way: fe80::xxxx:xxxx:xxxx:xxxx/10 where xxxx:xxxx:xxxx:xxxx is the modified EUI-64 address. Since the modified EUI-64 address is already used by link-local interface in the global zone we have to come up with another address. In our case I just use the following address for our shared zones: fe80::xxxx/10. Where in this case xxxx is the last 32bit of our global IPv6 address of the zone. Lets assume our global IPv6 address for the zone is 2001:db8:0:113::133/64 this would make our link-local address for that zone fe80::133/10.
This is what a shared config zone with IPv6 global and link-local address could look like:
root@solaris10u9:~# zonecfg -z test info zonename: test zonepath: /zp01/zones/test brand: native autoboot: true bootargs: pool: limitpriv: scheduling-class: ip-type: shared hostid: inherit-pkg-dir: dir: /lib inherit-pkg-dir: dir: /platform inherit-pkg-dir: dir: /sbin inherit-pkg-dir: dir: /usr net: address: 203.0.113.133 physical: aggr1 defrouter not specified net: address: 2001:db8:0:113::133/64 physical: aggr1 defrouter not specified net: address: fe80::133/10 physical: aggr1 defrouter not specified
With this setup we now got fully working IPv6 in Solaris shared zones.