I recently ran into an odd issue with IPv6 connectivity in my home network. During a lengthy outage, I decided to redo some of my network configurations. As part of this change, I also reorganized my IPv6 setup, relying more on DHCPv6 and less on router advertisements to configure IPv6 addresses. Overall, this worked well. My Macs had no issues connecting to IPv6. However, the Linux host I use to alert me of network connectivity issues could not “ping” the test host via IPv6.
Looking at the network configuration, I noticed a unique local address was added to the interface:
(some data obfuscated with ‘X’)
[jullrich@linux ~]$ ip -6 addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2603:xxxx:xxxx:xxxx::xxxx/128 scope global noprefixroute dynamic
valid_lft 81596sec preferred_lft 2396sec
inet6 fdef:xxxx:5489:40d7:xxxx:xxff:fexx:xxxx/64 scope global noprefixroute dynamic
valid_lft 1686sec preferred_lft 1686sec
inet6 fe80::a4c8:xxxx:xxxx:xxxx/64 scope link noprefixroute
valid_lft forever preferred_lft forever
The eth0 interface has a total of three IPv6 addresses assigned:
2603… : Globally routable address assigned via DHCPv6
fdef… : Unique local address (not globally routable)
fe80… : Link-local address
I only expected two addresses: the global and the link-local address. The Linux host used the unique local address as the source IP, which was not routable.
The unique local address’ interface ID (last 64 bits) was based on the host’s MAC address using the EUI64 scheme. This suggested that the address was selected based on a router advertisement. My official router did not advertise this prefix. So it was up to tcpdump to figure out what was going on:
% tcpdump -i en1 -vvvn ‘icmp6=134’
tcpdump: listening on en1, link-type EN10MB (Ethernet), snapshot length 524288 bytes
08:43:56.498478 IP6 (flowlabel 0x40c00, hlim 255, next-header ICMPv6 (58) payload length: 80)
fe80::ef:xxxx:259c:xxxx > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 80
hop limit 0, Flags [none], pref medium, router lifetime 0s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): xx:xx:xx:xx:xx:xx
0x0000: eca9 071f 6c65
prefix info option (3), length 32 (4): fdef:463f:xxxx:xxxx::/64, Flags [onlink, auto], valid time 1800s, pref. time 1800s
0x0000: 40c0 0000 0708 0000 0708 0000 0000 fdef
0x0010: 463f xxxx xxxx 0000 0000 0000 0000
route info option (24), length 16 (2): fdb2:xxxx:xxxx::/64, pref=medium, lifetime=1800s
0x0000: 4000 0000 0708 fdb2 xxxx xxxx 0000
unknown option (26), length 8 (1):
0x0000: 8000 0000 0000
The “router” sending these advertisements used a random (“privacy enhanced”) IPv6 address, but luckily, the router advertisements included the router’s MAC address. You can also look up the MAC address of an IPv6 host on your network using the “ndp” command (“Neighbor Discovery Protocol), which replaces the “arp” command (and protocol) for IPv4.
% ndp -na | grep fe80::ef:de0c:259c:ccd5
fe80::ef:xxxx:259c:xxxx%en5 xx:xx:xx:xx:xx:xx en1 5s D R
And, of course, once the MAC address is known, we can figure out the IPv4 address via arp:
% arp -na | grep xx:xx:xx:xx:xx:xx
? (10.x.x.x) at xx:xx:xx:xx:xx:xx on en5 ifscope [ethernet]
If the IPv4 address is not already in the ARP cache, you may need to do a quick scan to ping all hosts in the subnet.
This investigation showed that the router advertisements came from my Apple TV. The next step was to prevent this from happening. There is no obvious switch in the Apple TV to turn this off. I have seen similar behavior associated with “Internet Connection Sharing” features. But I do not believe the Apple TV has that option.
The obvious solution would be to turn off IPv6 support in the Apple TV. But oddly enough, there is no switch for that. The configuration options only cover IPv4. The IPv6 DNS server address is the only evidence that AppleTV speaks IPv6.
Some switches support an “RA Guard” feature. Like “DHCP Snooping,” it can block router advertisements from unauthorized hosts. But you usually only find features like this in higher-end enterprise switches. My switch does not support this feature.
My current solution was to increase the priority of the legitimate router advertisements to “high.” The RAs sent by the Apple TV were set to “medium.” By increasing the priority to high for the legit router, that route and the IP address received from it appear to be preferred:
For now, this works. The “sane” solution would be turning off IPv6 on the network and my recursive DNS server. But that would be too easy and not “cool.” I could move the Apple TV to a different VLAN. But this would impede some of the functionality.
There are still a few open questions about this event. Most notably, why this only showed up now. I have seen reports of this behavior going back a few years, but no real solution for it. Please feel free to comment if you have additional insight. I also do not quite understand why the unique local address was used as source IP for the outbound “ping6”.
(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.