This is all on HASS OS so there’s a lot of Docker noise. This is from right on the HASS server itself, using the SSH & Web Terminal addon.
Both border routers sending advertisements:
➜ config sudo tcpdump -vvvv -ttt -i enp0s18 icmp6 and 'ip6[40] = 134'
tcpdump: listening on enp0s18, link-type EN10MB (Ethernet), snapshot length 262144 bytes
00:00:00.000000 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 112) fe80::20e:c4ff:fed2:8995 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 112
hop limit 64, Flags [managed, other stateful], pref high, router lifetime 1800s, reachable time 0ms, retrans timer 0ms
prefix info option (3), length 32 (4): 2600:1700:8463:d1a0::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
0x0000: 40c0 0001 5180 0000 3840 0000 0000 2600
0x0010: 1700 8463 d1a0 0000 0000 0000 0000
rdnss option (25), length 24 (3): lifetime 600s, addr: fw.tolstyak.net
0x0000: 0000 0000 0258 2600 1700 8463 d1a0 0000
0x0010: 0000 0000 0001
dnssl option (31), length 24 (3): lifetime 600s, domain(s): tolstyak.net.
0x0000: 0000 0000 0258 0874 6f6c 7374 7961 6b03
0x0010: 6e65 7400 0000
mtu option (5), length 8 (1): 1500
0x0000: 0000 0000 05dc
source link-address option (1), length 8 (1): 00:0e:c4:d2:89:95
0x0000: 000e c4d2 8995
00:00:07.210061 IP6 (flowlabel 0x40000, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::1ca9:85d:5992:1da3 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 0, Flags [none], pref medium, router lifetime 0s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): 94:ea:32:8c:6b:b6
0x0000: 94ea 328c 6bb6
prefix info option (3), length 32 (4): fd9a:793f:4de6:4fac::/64, Flags [onlink, auto], valid time 1800s, pref. time 1800s
0x0000: 40c0 0000 0708 0000 0708 0000 0000 fd9a
0x0010: 793f 4de6 4fac 0000 0000 0000 0000
route info option (24), length 16 (2): fd6a:ab22:4825::/64, pref=medium, lifetime=1800s
0x0000: 4000 0000 0708 fd6a ab22 4825 0000
00:00:11.944192 IP6 (flowlabel 0x20d00, hlim 255, next-header ICMPv6 (58) payload length: 40) fe80::45b:9bf6:27e9:bd84 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 40
hop limit 0, Flags [none], pref medium, router lifetime 0s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): a8:51:ab:91:7d:e7
0x0000: a851 ab91 7de7
route info option (24), length 16 (2): fd6a:ab22:4825::/64, pref=medium, lifetime=1800s
0x0000: 4000 0000 0708 fd6a ab22 4825 0000
00:00:02.548996 IP6 (flowlabel 0x40000, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::1ca9:85d:5992:1da3 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 0, Flags [none], pref medium, router lifetime 0s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): 94:ea:32:8c:6b:b6
0x0000: 94ea 328c 6bb6
prefix info option (3), length 32 (4): fd9a:793f:4de6:4fac::/64, Flags [onlink, auto], valid time 1800s, pref. time 1800s
0x0000: 40c0 0000 0708 0000 0708 0000 0000 fd9a
0x0010: 793f 4de6 4fac 0000 0000 0000 0000
route info option (24), length 16 (2): fd6a:ab22:4825::/64, pref=medium, lifetime=1800s
0x0000: 4000 0000 0708 fd6a ab22 4825 0000
00:00:09.317836 IP6 (flowlabel 0x40000, hlim 255, next-header ICMPv6 (58) payload length: 72) fe80::1ca9:85d:5992:1da3 > ip6-allnodes: [icmp6 sum ok] ICMP6, router advertisement, length 72
hop limit 0, Flags [none], pref medium, router lifetime 0s, reachable time 0ms, retrans timer 0ms
source link-address option (1), length 8 (1): 94:ea:32:8c:6b:b6
0x0000: 94ea 328c 6bb6
prefix info option (3), length 32 (4): fd9a:793f:4de6:4fac::/64, Flags [onlink, auto], valid time 1800s, pref. time 1800s
0x0000: 40c0 0000 0708 0000 0708 0000 0000 fd9a
0x0010: 793f 4de6 4fac 0000 0000 0000 0000
route info option (24), length 16 (2): fd6a:ab22:4825::/64, pref=medium, lifetime=1800s
0x0000: 4000 0000 0708 fd6a ab22 4825 0000
Both do make it into the routing table:
➜ config route -A inet6 | grep fd6a
fd6a:ab22:4825::/64 fe80::1ca9:85d:5992:1da3 UG 100 7 0 enp0s18
fd6a:ab22:4825::/64 fe80::45b:9bf6:27e9:bd84 UG 100 5 0 enp0s18
ip -6 route doesn’t show both routes for some reason, or even the next hop
➜ config ip -6 route
::1 dev lo metric 256
2600:1700:8463:d1a0::1:14b4 dev enp0s18 metric 100
2600:1700:8463:d1a0::/64 dev enp0s18 metric 100
fd6a:ab22:4825::/64 metric 100
fd9a:793f:4de6:4fac::/64 dev enp0s18 metric 100
anycast fe80:: dev veth5576156 metric 0
anycast fe80:: dev hassio metric 0
anycast fe80:: dev veth0df6492 metric 0
anycast fe80:: dev veth40518c8 metric 0
anycast fe80:: dev docker0 metric 0
anycast fe80:: dev veth197b5e7 metric 0
anycast fe80:: dev vethfd70de0 metric 0
anycast fe80:: dev vethf470e81 metric 0
anycast fe80:: dev veth7cbaa02 metric 0
anycast fe80:: dev veth0d06e77 metric 0
anycast fe80:: dev veth48c645b metric 0
anycast fe80:: dev veth14281bd metric 0
anycast fe80:: dev veth027d525 metric 0
anycast fe80:: dev veth754f881 metric 0
fe80::/64 dev enp0s18 metric 100
fe80::/64 dev veth5576156 metric 256
fe80::/64 dev hassio metric 256
fe80::/64 dev veth0df6492 metric 256
fe80::/64 dev docker0 metric 256
fe80::/64 dev veth40518c8 metric 256
fe80::/64 dev veth197b5e7 metric 256
fe80::/64 dev vethfd70de0 metric 256
fe80::/64 dev vethf470e81 metric 256
fe80::/64 dev veth7cbaa02 metric 256
fe80::/64 dev veth0d06e77 metric 256
fe80::/64 dev veth48c645b metric 256
fe80::/64 dev veth14281bd metric 256
fe80::/64 dev veth027d525 metric 256
fe80::/64 dev veth754f881 metric 256
multicast ff00::/8 dev veth5576156 metric 256
multicast ff00::/8 dev hassio metric 256
multicast ff00::/8 dev veth0df6492 metric 256
multicast ff00::/8 dev docker0 metric 256
multicast ff00::/8 dev veth40518c8 metric 256
multicast ff00::/8 dev enp0s18 metric 256
multicast ff00::/8 dev veth197b5e7 metric 256
multicast ff00::/8 dev vethfd70de0 metric 256
multicast ff00::/8 dev vethf470e81 metric 256
multicast ff00::/8 dev veth7cbaa02 metric 256
multicast ff00::/8 dev veth0d06e77 metric 256
multicast ff00::/8 dev veth48c645b metric 256
multicast ff00::/8 dev veth14281bd metric 256
multicast ff00::/8 dev veth027d525 metric 256
multicast ff00::/8 dev veth754f881 metric 256
default via fe80::20e:c4ff:fed2:8995 dev enp0s18 metric 100
IPv6 addresses:
➜ config ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2600:1700:8463:d1a0::1:14b4/128 scope global dynamic noprefixroute
valid_lft 5663sec preferred_lft 2963sec
inet6 fd9a:793f:4de6:4fac:37e9:7b9d:f4f7:a275/64 scope global deprecated dynamic noprefixroute
valid_lft 1167sec preferred_lft 0sec
inet6 2600:1700:8463:d1a0:27c:5eb0:7abd:628a/64 scope global dynamic noprefixroute
valid_lft 86202sec preferred_lft 14202sec
inet6 fe80::1ad:26ee:2537:df0f/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: hassio: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP
inet6 fe80::42:beff:fe4f:34a5/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP
inet6 fe80::42:41ff:fe91:eb2d/64 scope link
valid_lft forever preferred_lft forever
6: veth5576156@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::c029:fdff:fee5:bda2/64 scope link
valid_lft forever preferred_lft forever
8: veth0df6492@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::3c00:84ff:feb3:74e0/64 scope link
valid_lft forever preferred_lft forever
10: veth40518c8@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::e48c:35ff:fe1a:8069/64 scope link
valid_lft forever preferred_lft forever
12: veth197b5e7@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::30ad:8cff:fe41:1e49/64 scope link
valid_lft forever preferred_lft forever
14: vethfd70de0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::e4f2:13ff:fe89:4020/64 scope link
valid_lft forever preferred_lft forever
16: vethf470e81@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::4844:35ff:fe5f:18e8/64 scope link
valid_lft forever preferred_lft forever
18: veth7cbaa02@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::8d6:e0ff:fec4:b84/64 scope link
valid_lft forever preferred_lft forever
20: veth0d06e77@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::58e0:91ff:fe60:d581/64 scope link
valid_lft forever preferred_lft forever
22: veth48c645b@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::74ce:41ff:febd:92bf/64 scope link
valid_lft forever preferred_lft forever
24: veth14281bd@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::1092:54ff:fe9d:93db/64 scope link
valid_lft forever preferred_lft forever
26: veth027d525@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::9cb7:38ff:feca:653f/64 scope link
valid_lft forever preferred_lft forever
28: veth754f881@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 fe80::489f:41ff:fe25:e120/64 scope link
valid_lft forever preferred_lft forever
When I say I can reach the bulb that was non-working via both border routers, I mean that I have this script that inserts temporary low-metric routes to force pings through each border router. (It removes them after.) And I was getting ping replies no matter what.
#!/bin/bash
bulbs="0t1c"
#bulbs="0t1c 2rjd 3rxf"
TBRs=$(route -A inet6 | grep fd6a | sed 's/ \+/ /g' | cut -d ' ' -f 2)
echo "Bulbs: $bulbs"
echo "TBRs:
$TBRs"
echo
for x in $bulbs; do
echo "$x"
ip=$(ping -c1 -W1 "nanoleaf-a19-$x.local" | grep PING | cut -d '(' -f 2 | cut -d ')' -f 1)
[ $? -ne 0 ] && echo "No ping" || echo "Pings"
ip -6 route get "$ip"
echo
while IFS= read -r line; do
echo "Via $line..."
ip -6 route add "$ip" via "$line" metric 1 dev enp0s18
ip -6 route get "$ip"
ping -c4 "$ip"
ip -6 route del "$ip" via "$line" metric 1 dev enp0s18
done <<< "$TBRs"
done
Its output. I did also confirm via tcpdump that the ping packets go through the expected border router when the temporary routes are in place.
➜ share ./thread.sh
Bulbs: 0t1c
TBRs:
fe80::1ca9:85d:5992:1da3
fe80::45b:9bf6:27e9:bd84
0t1c
Pings
fd6a:ab22:4825:0:2e8:a408:94b7:7fd via fe80::1ca9:85d:5992:1da3 dev enp0s18 src 2600:1700:8463:d1a0::1:14b4 metric 100
Via fe80::1ca9:85d:5992:1da3...
fd6a:ab22:4825:0:2e8:a408:94b7:7fd via fe80::1ca9:85d:5992:1da3 dev enp0s18 src 2600:1700:8463:d1a0::1:14b4 metric 1
PING fd6a:ab22:4825:0:2e8:a408:94b7:7fd (fd6a:ab22:4825:0:2e8:a408:94b7:7fd): 56 data bytes
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=0 ttl=63 time=32.223 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=1 ttl=63 time=26.495 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=2 ttl=63 time=28.608 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=3 ttl=63 time=28.686 ms
--- fd6a:ab22:4825:0:2e8:a408:94b7:7fd ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 26.495/29.003/32.223 ms
Via fe80::45b:9bf6:27e9:bd84...
fd6a:ab22:4825:0:2e8:a408:94b7:7fd via fe80::45b:9bf6:27e9:bd84 dev enp0s18 src 2600:1700:8463:d1a0::1:14b4 metric 1
PING fd6a:ab22:4825:0:2e8:a408:94b7:7fd (fd6a:ab22:4825:0:2e8:a408:94b7:7fd): 56 data bytes
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=0 ttl=63 time=39.257 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=1 ttl=63 time=34.213 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=2 ttl=63 time=24.812 ms
64 bytes from fd6a:ab22:4825:0:2e8:a408:94b7:7fd: seq=3 ttl=63 time=24.840 ms
--- fd6a:ab22:4825:0:2e8:a408:94b7:7fd ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 24.812/30.780/39.257 ms
2600:1700:8463:d1a0::/64 is my LAN
2600:1700:8463:d1a0::1:xxxx is DHCPv6
fd6a:ab22:4825::/64 is apparently my thread network
Not sure where the fd9a ULAs are coming from.
The underlying IPv6 connectivity seems to be perfectly fine, and the bulb advertises only its current IPv6 address. This is also evidenced in the logs of my previous post, where the description object shows the proper address in both the ‘address’ field and shows only that one, correct address in the ‘addresses’ list.
(_hap._udp.)
From above:
2022-11-29 10:26:34.726 DEBUG (MainThread) [aiohomekit.controller.abstract] [[fdc5:366d:c048:0:abeb:84d3:ee31:320d]:5683] (id=17:A1:DE:6E:DA:9F): Description updated: old=None new=HomeKitService(name='Nanoleaf A19 0T1C', id='17:a1:de:6e:da:9f', model='NL45', feature_flags=<FeatureFlags.SUPPORTS_SOFTWARE_AUTHENTICATION: 2>, status_flags=<StatusFlags.0: 0>, config_num=1, state_num=8, category=<Categories.LIGHTBULB: 5>, protocol_version='1.2', type='_hap._udp.local.', address='fd6a:ab22:4825:0:2e8:a408:94b7:7fd', addresses=['fd6a:ab22:4825:0:2e8:a408:94b7:7fd'], port=5683)
To demonstrate that those router advertisements are indeed my Apple border routers (_meshcop._udp.):
ATV:
HomePod Mini:
Everything is on the same VLAN. IPv6 connectivity is working fine and aiohomekit sees the zeroconf advertisements. Seems like it’s just not making use of the new IPv6 address that it receives. Once I manually updated the core.config_entries file in .storage that aiohomekit pulls pair info from it started working, and if I change the AccessoryIP of the bulb back to what it was in that file, it goes back to not working and not making use of the proper IP from zeroconf.