I have a Huawei HG659 Home Gateway supplied as part of my Vodafone FibreX installation. Out of the box, since early 2017, the Vodafone FibreX / Huawei HG659 combination has natively provided IPv6 support. This automagically works on modern mac OS:

ewen@osx:~$ ping6 google.com
PING6(56=40+8+8 bytes) 2407:7000:9b0e:4856:b971:8973:3fe3:1a51 --> 2404:6800:4006:804::200e
16 bytes from 2404:6800:4006:804::200e, icmp_seq=0 hlim=57 time=46.574 ms
16 bytes from 2404:6800:4006:804::200e, icmp_seq=1 hlim=57 time=43.953 ms

and Linux:

ewen@linux:~$ ping6 google.com
PING google.com(syd15s03-in-x0e.1e100.net (2404:6800:4006:804::200e)) 56 data bytes
64 bytes from syd15s03-in-x0e.1e100.net (2404:6800:4006:804::200e): icmp_seq=1 ttl=57 time=44.8 ms
64 bytes from syd15s03-in-x0e.1e100.net (2404:6800:4006:804::200e): icmp_seq=2 ttl=57 time=43.8 ms

to provide global IPv6 connectivity, for a single internal VLAN, without having to do anything else.

Vodafone delegates a /56 prefix to each customer, which in theory means that it should be possible to further sub-delegate that within our own network for multiple subnets -- most IPv6 features will work down to /64 subnets. I think the /56 is being provided via DHCPv6 Prefix Delegation (see RFC3633 and RFC3769; see also OpenStack Prefix Delegation discussion).

Recently I started looking at whether I could configure an internal Mikrotik router to route dynamically-obtained IPv6 prefixes from the Huawei HG659's /56 pool, to create a separate -- more isolated -- internal subnet. A very useful Mikrotik IPv6 Home Example provided the Mikrotik configuration required, although I did have to update it slightly for later Mikrotik versions (tested with RouterOS 6.40.1).

Enable IPv6 features on the Mikrotik if they are not already enabled:

/system package enable ipv6
/system package print

If the "print" shows you an "X" with a note that it will be enabled after reboot, then also reboot the Mikrotik at this point:

/system reboot

After that, you should have a IPv6 Link Local Address on the active interface, which you can see with:

[admin@naos-rb951-2n] > /ipv6 addr print
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local
 #    ADDRESS                                     FROM-... INTERFACE        ADV
 0 DL fe80::d6ca:6dff:fe50:6c44/64                         ether1           no
[admin@naos-rb951-2n] >

(The IPv6 Link Local addresses are recognisable as being in fe80::/64, and on the Mikrotik will show as "DL" -- dynamically assigned, link local.)

Once that is working configure the Mikrotik IPv6 DHCPv6 client to request a Prefix Delegation with:

/ipv6 dhcp-client add interface=ether1 pool-name=ipv6-local \
      add-default-route=yes use-peer-dns=yes request=prefix

Unfortunately when I tried that, it never succeeded in getting an answer from the Huawei HG659. Instead the status was stuck in "searching":

[admin@naos-rb951-2n] > /ipv6 dhcp-client print detail
Flags: D - dynamic, X - disabled, I - invalid
 0    interface=ether1 status=searching... duid="0x00030001d4ca6d506c44"
      dhcp-server-v6=:: request=prefix add-default-route=yes use-peer-dns=yes
      pool-name="ipv6-local" pool-prefix-length=64 prefix-hint=::/0
[admin@naos-rb951-2n] >

which makes me think that while the Huawei HG659 appears to be able to request an IPv6 prefix delegation (with a DHCPv6 client) it does not appear provide a DHCPv6 server that is capable of prefix delegation, which rather defeats the purpose of having a /56 delegated :-(

Specifying:

/ipv6 dhcp-client remove 0
/ipv6 dhcp-client add interface=ether1 pool-name=ipv6-local \
      add-default-route=yes use-peer-dns=yes request=address,prefix

which apepars to be the syntax to request an interface address and a prefix delegation did not work any better, still getting stuck with a status of "searching...":

[admin@naos-rb951-2n] > /ipv6 dhcp-client print  detail
Flags: D - dynamic, X - disabled, I - invalid
 0    interface=ether1 status=searching... duid="0x00030001d4ca6d506c44"
      dhcp-server-v6=:: request=address,prefix add-default-route=yes
      use-peer-dns=yes pool-name="ipv6-local" pool-prefix-length=64
      prefix-hint=::/0
[admin@naos-rb951-2n] >

If I delete that and just request an address:

/ipv6 dhcp-client remove 0
/ipv6 dhcp-client add interface=ether1 pool-name=ipv6-local \
      add-default-route=yes use-peer-dns=yes request=address

then the DHCPv6 request does succeed very quickly:

[admin@naos-rb951-2n] > /ipv6 dhcp-client print
Flags: D - dynamic, X - disabled, I - invalid
 #    INTERFACE                     STATUS        REQUEST
 0    ether1                        bound         address
[admin@naos-rb951-2n] >

and there is an additional IPv6 address visible for that interface:

[admin@naos-rb951-2n] > /ipv6 addr print
Flags: X - disabled, I - invalid, D - dynamic, G - global, L - link-local
 #    ADDRESS                                     FROM-... INTERFACE        ADV
 0 DL fe80::d6ca:6dff:fe50:6c44/64                         ether1           no
 1 IDG ;;; duplicate address detected
      2407:xxxx:xxxx:4800::2/64                            ether1           no
[admin@naos-rb951-2n] >

Unfortunately the "I" flag and the "duplicate address detected" comment are both very bad signs -- that the address supplied by DHCPv6 is unusable. When I look around other devices on my network I find that they too have that address, including my main OS X 10.11 laptop:

ewen@ashram:~$ ifconfig -a | grep -B 10 ::2 | egrep "^en|::2"
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet6 2407:xxxx:xxxx:4800::2 prefixlen 128 dynamic
ewen@ashram:~$

and another OS X 10.11 laptop:

ewen@mandir:~$ ifconfig -a | grep -B 9 ::2 | egrep "^en|::2"
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet6 2407:xxxx:xxxx:4800::2 prefixlen 128 duplicated dynamic
ewen@mandir:~$

which implies that the Huawei HG659 DHCPv6 server is handing out the same (::2) address to multiple clients (possibly all clients?!) and only the first client to make the request has a reasonable chance of working (in theory the others will discover via RFC7527 Duplicate Address Detection that the address is already in used, and invalidate it, to allow the first client to work).

From all of this I conclude that the Huawei HG659 DHCPv6 server will basically only work in a useful fashion for a single DHCPv6 client, that wants a single address -- so it is almost useless. In particular the DHCPv6 server does not appear to be a way to get use of parts of at the IPv6 /56 delegation provided by Vodafone.

Yet IPv6 global transit does work from multiple OS X and Linux devices on my home network -- so they are clearly not (solely) reliant on IPv6 DHCPv6 working properly.

The reason they have working IPv6 transit is that OS X and Linux will also do SLAAC -- Stateless Addesss Auto-Configuration (RFC4826 -- to obtain an IPv6 address and default route. SLAAC uses the IPv6 Neighbor Discovery Protocol (RFC4861) to determine the IPv6 address prefix (/64), and a Modified EUI-64 algorithm (described in RFC5342 section 2.2) to determine the IPv6 address suffix (64-bits).

Providing the Hauwei HG659 is configured to send IPv6 RA ("Route Advertisement") messages (Home Interface -> LAN Interface -> RA Settings -> Enable RA is ticked), then SLAAC should work. There are two other settings:

  • "RA mode": automatic / manual. In automatic mode it appears to pick a prefix from the /56 that the IPv6 DHCPv6 Prefix Delegation client obtained from Vodafone -- apparently the "56" prefix (at least in my case), for no really obvious reason. In manual mode you can specify a prefix, but that does not seem very useful when the larger prefix you have is dynamically allocated....

  • "ULA mode": disable / automatic / manual. This controls the delegation of IPv6 Unique Local Addresses (RFC4193), which are site-local addresses in the fc00::/7 block. By default it is set to "automatic" which appears to result in the Huawei HG659 picking a prefix block at random (as indicated by a fd00::/8 address). "manual" allows manual specification of the block to use, and "disable" I assume turns off this feature.

Together these four features (IPv6 Link Local Addresses, IPv6 DHCPv6, IPv6 SLAAC, RFC4193 Unique Local Addresses) explain most of the IPv6 addresses that I see on my OS X client machines. For instance (some of the globally unique 56 prefix replaced with xxxx:xxxx, and the last three octets of the SLAAC addresses replaced by yy:yyyy for privacy):

ewen@ashram:~$ ifconfig en6 | egrep "^en|inet6" 
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet6 fe80::6a5b:35ff:feyy:yyyy%en6 prefixlen 64 scopeid 0x4
        inet6 2407:xxxx:xxxx:4856:6a5b:35ff:feyy:yyyy prefixlen 64 autoconf
        inet6 2407:xxxx:xxxx:4856:b971:8973:3fe3:1a51 prefixlen 64 autoconf temporary
        inet6 fd50:1d9:5e3e:8300:6a5b:35ff:feyy:yyyy prefixlen 64 autoconf
        inet6 fd50:1d9:5e3e:8300:e010:afec:6457:2850 prefixlen 64 autoconf temporary
        inet6 2407:xxxx:xxxx:4800::2 prefixlen 128 dynamic
@ashram:~$

In this list:

  • The fe80::6a5b:35ff:feyy:yyyy%en6 address is the IPv6 Link Local Address, derived from the prefix fe80:://64 and an EUI-64 suffix derived from the interface MAC address (as described in RFC2373). It is approximately the first 3 octets of the MAC address, then ff:fe, then the last 3 octets of the MAC address -- but the Universal/Local bit of the MAC address is inverted in IPv6, so as to make ::1, ::2 style hand created addresses end up automatically marked as "local". (While this seems clever, with perfect hindsight it would perhaps have been better if the IEEE MAC address Universal/Local flag was a Local/Universal flag with the bit values inverted, for the same reason... and perhaps better positioned in the bit pattern.) In this case 0x68 in the MAC address becomes 0x6a:

    ewen@ashram:~$ perl -le 'printf("%08b\n", 0x68);'
    01101000
    ewen@ashram:~$ perl -le 'printf("%08b\n", 0x6a);'
    01101010
    ewen@ashram:~$
    

    by setting this additional (7th from the left) bit.

  • The 2407:xxxx:xxxx:4856:6a5b:35ff:feyy:yyyy address is the globally routable IPv6 SLAAC address, derived from the SLACC /64 prefix obtained from the IPv6 Route Advertisement packets and the EUI-64 suffix ss described above (where the SLAAC /64 prefix provided by the Hauwei HG659 itself came from an IPv6 DHCPv6 Prefix Delegation request made by the Huawei HG659). This address is recognisable by the "autoconf" flag indicating SLAAC, and the non-fd prefix.

  • The fd50:1d9:5e3e:8300:6a5b:35ff:feyy:yyyy address is the Unique Local Address (RFC4193), derived from a randomly generated prefix in fd00::/8 and the EUI-64 suffix as described above. This address is recognisable by the "autoconf" flag indicating SLAAC, and the fd prefix. (See also "3 Ways to Ruin Your Future Network with IPv6 Unique Local Addresses" Part 1 and Part 2 -- basically by re-introducing all the pain of NAT to IPv6, as well as all the pain of "everyone uses the same site-local prefixes".)

  • The 2407:xxxx:xxxx:4800::2 address is obtained from the Huawei HG659 DHCPv6 server, and consists of the first /64 in the /56 that the Huawei HG659 DHCPv6 client obtained via Prefix Delegation, and a DHCP assigned suffix, starting with ::2 (where I think the Huawei HG659 itself is ::1, but it does not respond to ICMP with that address). This address is recognisable by the "dynamic" flag indicating DHCPv6.

    Unfortunately as described above the Huawei HG659 DHCPv6 DHCP server is broken (at least in Huawei HG659 firmware version V100R001C206B020), and mistakenly hands out the same DHCP assigned suffix to multiple clients. This means that only the lucky first DHCPv6 client on the network will have a working DHCPv6 address. (It also appears, as described above, that it does not support DHCPv6 Prefix Delegation.)

That explains all but two of the IPv6 addresses listed. The remaining two have the "temporary" flag:

ewen@ashram:~$ ifconfig en6 | egrep "^en|inet6" | egrep "^en6|temporary"
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
         inet6 2407:xxxx:xxxx:4856:b971:8973:3fe3:1a51 prefixlen 64 autoconf temporary
         inet6 fd50:1d9:5e3e:8300:e010:afec:6457:2850 prefixlen 64 autoconf temporary
ewen@ashram:~$

and those are even more special. IPv6 Temporary Addresses are created to reduce the ability to track the same device across multiple locations through the SLAAC EUI-64 suffix -- which being predictably derived from the MAC address will stay the same across multiple SLAAC prefixes. Mac OS X (since OS X 10.7 -- Lion) and Microsoft Windows since (Windows Vista) will generate, and use them, by default.

The relevant RFC is RFC4941 which defines "Privacy Extensions for Stateless Address Autoconfiguration in IPv6". Basically it defines a method to create additional ("temporary") IPv6 addresses, following a method like IPv6 SLAAC, which are not derived from a permanent identifier like the ethernet MAC address -- instead a IPv6 suffix is randomly generated and used instead of the EUI-64 suffix. Amusingly the suggested algorithm appears to be old enough to use the (now widely deprecated) MD5 hash algorithm as part of the derivation steps. (These temporary/"Privacy" addresses are supported on many modern OS.)

These RFC4941 "temporary" addresses normally have a shorter lifetime, which can be seen on OS X with "ifconfig -L":

ewen@ashram:~$ ifconfig -L en6 | egrep "^en6|temporary"
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet6 2407:xxxx:xxxx:4856:b971:8973:3fe3:1a51 prefixlen 64 autoconf temporary pltime 3440 vltime 7040
        inet6 fd50:1d9:5e3e:8300:e010:afec:6457:2850 prefixlen 64 autoconf temporary pltime 3440 vltime 7040
ewen@ashram:~$

but on the system I checked both the temporary and the permanent SLAAC addresses had the same pltime/vltime values, which I assume are derived from the SLAAC validity times. The "pltime" is the "preferred" lifetime, and the "vltime" is the "valid" lifetime; I think that after the preferred lifetime an attempt will be made to generate renew the address, and after the valid lifetime the address will be expired (assuming it is not renewed/replaced before then).

It appears that in macOS 10.12 (Sierra) and later, even the non-temporary IPv6 addresses no longer use the EUI-64 approach to derive the address suffix from the MAC address -- which means the "permanent" addresses also changed between 10.11 and 10.12. I do not currently have a macOS 10.12 (Sierra) system to test this on. I found a claim these are RFC 3972 "Cryptographically Generated Addresses", but there does not seem to be much evidence for the exact algorithm used. (There are also suggestions that this is an implementation of RFC7217 "Semantically Opaque Interface Identifiers" which effectively make the IPv6 suffix also depend on the IPv6 prefix. Ie, the resulting address would be stable given the same Prefix, but different for each prefix. See also an IPv6 on OS X Hardening Guide -- from 2015, so probably somewhat out of date now.)

Returning to the problem I started with, configuring a Mikrotik for IPv6, I found that the Mikrotik could have an interfacen address configured with SLAAC, by setting:

/ipv6 settings set accept-router-advertisements=yes

or:

/ipv6 settings set accept-router-advertisements=yes-if-forwarding-disabled forward=no

(see Mikrotik IPv6 Settings), but at least on 6.40.1 this still does not result in an IPv6 SLAAC address being visible anywhere, even after a reboot. (Bouncing the interface, or rebooting -- /system reboot -- is required to initiate SLAAC.)

You can check the address did get assigned properly by pinging it from another SLAAC configured system, with the EUI-64 derived suffix:

ewen@ashram:~$ ping6 -c 2 2407:xxxx:xxxx:4856:d6ca:6dff:feyy:yyyy
PING6(56=40+8+8 bytes) 2407:xxxx:xxxx:4856:6a5b:35ff:fe88:8f6e --> 2407:7000:9b0e:4856:d6ca:6dff:feyy:yyyy
16 bytes from 2407:xxxx:xxxx:4856:d6ca:6dff:feyy:yyyy, icmp_seq=0 hlim=255 time=0.440 ms
16 bytes from 2407:xxxx:xxxx:4856:d6ca:6dff:feyy:yyyy, icmp_seq=1 hlim=255 time=0.504 ms

--- 2407:xxxx:xxxx:4856:d6ca:6dff:feyy:yyyy ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.440/0.472/0.504/0.032 ms
ewen@ashram:~$

In the default IPv6 settings:

[admin@naos-rb951-2n] > /ipv6 settings print
                       forward: yes
              accept-redirects: yes-if-forwarding-disabled
  accept-router-advertisements: yes-if-forwarding-disabled
          max-neighbor-entries: 8192
[admin@naos-rb951-2n] >

then IPv6 SLAAC will not be performed; but with either of the settings above (after a reboot: /system reboot) then SLAAC will be performed.

Other than the UI/display issue, this is consistent with the idea that the WAN interface of a router should be assignable using SLAAC, but not entirely consistent with the documentation which says SLAAC cannot be used on routers. It is just that to be useful routers typically need IP addresses for multiple interfaces, and the only way to meaningfully obtain those is either IPv6 DHCPv6 Prefix Delegation -- or static configuration.

Since the Huawei HG659 appears not to provide a usable IPv6 DHCPv6 server there is no way to get DHCPv6 Prefix Delegation working internally, which means my best option will be to replace Huawei HG659 with something else as the "Home Gateway" connected to the Technicolor TC4400VDF modem. Generally people seem to be using a Mikrotik RB750Gr3 (a "hEX") for which there is a general Mikrotik with Vodafone setup guide available. It is a small 5 * GigE router capable of up to 2 Gbps throughput in ideal conditions (by contrast the old Mikrotik RB951-2n that I had lying around to test with is only 5 * 10/100 interfaces, so slower than my FibreX connection let alone my home networking).

In theory the Mikrotik IPv6 support includes both DHCPv6 Prefix Delegation in the client and server, including on-delegating smaller prefixes. Which should mean that if a Mikrotik RB750Gr3 were directly connected to the Technicolor TC4400VDF cable modem it could handle all my requirements, including creating isolated subnets in IPv4 and IPv6. (The Huawei HG659 supports the typical home "DMZ" device by NAT'ing all IPv4 traffic to a specific internal IP, but it is not very isolated unless you NAT to another firewall like the Mikrotik and then forward from there to the isolated subnet -- and I would really prefer to avoid double NAT. That Huawei HG659 DMZ support also appears to be IPv4 only, and it does not appear to support static IPv4 routes on the LAN interface either -- the static routing functions only allow you to choose a WAN interface.)

Since I seem to have hit up against the limits of the Huawei HG659, my "interim" use of the supplied Huawei HG659 appears to be coming to an end. In the meantime I have turned off the DHCPv6 server on the Huawei HG659 (Home Network -> Lan Interface -> IPv6 DHCP Server -> IPv6 DHCP Server should be unticked).

For the record, the Mikrotik MAC Telnet reimplmentation appears to work quite well on OS X 10.11, providing you already know the MAC address you want to reach (eg, from the sticker on the outside of the Mikrotik). That helps a lot with reconfiguration of the Mikrotik for a new purpose, without relying on a Microsoft Windows system or WINE.