Summary
I have otbr-agent running as a full border router on macOS (Apple Silicon
Mac mini, bare metal, RCP mode with a SONOFF EFR32MG24 dongle). Real
Matter-over-Thread devices (two Nuki smart locks) are commissioned through
it into Home Assistant and work reliably, including across host reboots.
The surprising part: the tree is nearly there already. A stock checkout
gets 96% through compilation with -DOTBR_MDNS=mDNSResponder. It took two
small changes in this repo plus one in openthread to reach a fully working
border router:
src/rest/json.cpp: a C++ VLA fails Apple clang with -Werror
(-Wvla-cxx-extension); fixed with a fixed-size buffer.
src/mdns/CMakeLists.txt: don't link a standalone dns_sd library on
Apple platforms (the API is in libSystem).
- openthread
src/posix/platform/infra_if.cpp: IPV6_BOUND_IF takes an
interface index on macOS, not a name; the shared BSD branch passed the
name and died with EINVAL at startup. (Separate PR to
openthread/openthread.)
What works (verified with real hardware)
- RCP over HDLC/UART (460800 baud, EFR32MG24)
- utun-based Thread netif; network forms, state=leader, dataset persistence
- mDNS via native mDNSResponder:
_meshcop._udp advertised; discovered by
Home Assistant on the LAN
- SRP server + advertising proxy: Thread devices'
_matter._tcp records
published to the LAN with AAAA resolution
- Border routing: RA emission with PIO + RIO on the infra interface works
out of the box (tcpdump-verified); LAN hosts learn routes and reach mesh
devices; Matter CASE sessions established host->mesh
- Full Matter commissioning of Thread devices via HA + phone flow
Platform requirements found
sysctl net.inet6.ip6.forwarding=1 is required (macOS defaults to 0).
Without it the host neither forwards infra<->utun traffic nor delivers
packets arriving on the infra interface for utun-owned addresses.
Question for maintainers: should otbr-agent set this at startup on macOS
(matching what the Linux setup scripts do), or should it be a documented
deployment requirement?
Not attempted / out of scope for a first PR
- Backbone router: Darwin has no usable IPv6 multicast routing (MRT6
equivalent); would need a userspace forwarder. Single-BR Matter homes
don't need it.
- Firewall: macOS
pf could host the equivalent of the ip6tables rules;
proposed as a follow-up PR.
- NCP mode (the existing
netif_unix.cpp stub already documents this).
Questions before I open PRs
- Is macOS host support something the project wants to carry? (I'm happy
to also contribute a macOS build job for GitHub Actions to keep it
green.)
- PR structure preference: one PR with the two build fixes + CI job +
docs, or split?
- The forwarding sysctl question above.
- For the openthread
infra_if.cpp fix I'll open a separate PR there —
anything else platform-related you'd want bundled with it?
Code
Branches with the changes described above:
Happy to share logs, packet captures, or run experiments — the setup is my
daily-driver home automation so it gets continuous real-world testing.
Summary
I have otbr-agent running as a full border router on macOS (Apple Silicon
Mac mini, bare metal, RCP mode with a SONOFF EFR32MG24 dongle). Real
Matter-over-Thread devices (two Nuki smart locks) are commissioned through
it into Home Assistant and work reliably, including across host reboots.
The surprising part: the tree is nearly there already. A stock checkout
gets 96% through compilation with
-DOTBR_MDNS=mDNSResponder. It took twosmall changes in this repo plus one in openthread to reach a fully working
border router:
src/rest/json.cpp: a C++ VLA fails Apple clang with-Werror(
-Wvla-cxx-extension); fixed with a fixed-size buffer.src/mdns/CMakeLists.txt: don't link a standalonedns_sdlibrary onApple platforms (the API is in libSystem).
src/posix/platform/infra_if.cpp:IPV6_BOUND_IFtakes aninterface index on macOS, not a name; the shared BSD branch passed the
name and died with EINVAL at startup. (Separate PR to
openthread/openthread.)
What works (verified with real hardware)
_meshcop._udpadvertised; discovered byHome Assistant on the LAN
_matter._tcprecordspublished to the LAN with AAAA resolution
out of the box (tcpdump-verified); LAN hosts learn routes and reach mesh
devices; Matter CASE sessions established host->mesh
Platform requirements found
sysctl net.inet6.ip6.forwarding=1is required (macOS defaults to 0).Without it the host neither forwards infra<->utun traffic nor delivers
packets arriving on the infra interface for utun-owned addresses.
Question for maintainers: should otbr-agent set this at startup on macOS
(matching what the Linux setup scripts do), or should it be a documented
deployment requirement?
Not attempted / out of scope for a first PR
equivalent); would need a userspace forwarder. Single-BR Matter homes
don't need it.
pfcould host the equivalent of the ip6tables rules;proposed as a follow-up PR.
netif_unix.cppstub already documents this).Questions before I open PRs
to also contribute a macOS build job for GitHub Actions to keep it
green.)
docs, or split?
infra_if.cppfix I'll open a separate PR there —anything else platform-related you'd want bundled with it?
Code
Branches with the changes described above:
Happy to share logs, packet captures, or run experiments — the setup is my
daily-driver home automation so it gets continuous real-world testing.