openthread-br: update to 2026.07.0, internal mDNS, configurable REST listen address - #30091
openthread-br: update to 2026.07.0, internal mDNS, configurable REST listen address#30091LorbusChris wants to merge 3 commits into
Conversation
522cae5 to
7aa6e5a
Compare
stintel
left a comment
There was a problem hiding this comment.
As this has not even been build-tested, I am going to request changes here. This PR has the potential to completely break people's smart homes, so without runtime testing this is a 100% no go.
👍 I'll be doing testing on actual hardware soon - this also requires openwrt/luci#8871 and coordination between the two. |
Thanks, appreciated. I'd be interested to know more about your setup and hardware. I had the idea of adding some kind of tested hardware matrix in the README.md. |
|
@stintel my first field test will be on a Turris Omnia NG (running the Turris OS flavour of OpenWrt) with a Home Assistant Connect ZBT-2. |
Great, that's completely different from my setup: 2x Olimex A64-OLinuXino with nRF52840 MDK USB Dongle in a dual-border-router setup with stateful packet filtering and conntrack state syncing with conntrackd and TREL between the 2. I have briefly been running with a 3rd border-router on a TP-Link EAP683-LR with the integrated CC2652, but the firmware of that CC2652 appeared to be unstable so it is currently disabled until I have time (and probably a 2nd device) to debug this properly. |
7aa6e5a to
bfc4369
Compare
bfc4369 to
e49c1c9
Compare
|
@stintel could you approve the "Test and Build" CI workflow? This should build now and I'm curious if anything else pops up. |
|
I'd also be happy to split the 3rd commit out into its own PR so the update can go in independently. |
Done |
If it's not too much hassle, I think I would prefer that. I'd like to thoroughly review and test this PR myself before accepting it, so having the LuCI separation in a different PR would allow that to land earlier. Also regarding mDNSResponder vs OpenThread's internal mDNS support, I'm not sure. I think I'd prefer following upstream's default. We would then have to make sure we can't run another mDNS daemon when otbr-agent is running. I see your point about keeping mDNSResponder as default, but I guess we have to check how that works when someone also install umdns and/or avahi-daemon. Lastly, otbr-agent is the only consumer of mDNSResponder and @neheb suggested to drop mDNSResponder from tree entirely after landing my 2026.06 bump. |
e49c1c9 to
d1ae6dc
Compare
d1ae6dc to
bc2d58f
Compare
|
Switched to I tested it alongside umdns on a simulated RCP and they seem to get along fine: OT names its host One thing worth knowing: OT's mDNS only serves the single Also added a Hardware testing on a Turris Omnia NG + ZBT-2 next. Mind re-approving the build workflow? |
a12c137 to
a1c33b2
Compare
The LuCI web interface for OpenThread Border Router is proposed for the openwrt/luci repository as luci-app-openthread (openwrt/luci#8871), following the standard convention for LuCI apps, as requested in openwrt#29791 and openthread/ot-br-posix#3431. Remove the luci-app-openthread subpackage (and its install recipe) so the UI is no longer shipped from two places. Split out of openwrt#30091 so it can be reviewed and land independently of the 2026.07.0 update. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
The LuCI web interface for OpenThread Border Router is proposed for the openwrt/luci repository as luci-app-openthread (openwrt/luci#8871), following the standard convention for LuCI apps, as requested in openwrt#29791 and openthread/ot-br-posix#3431. Remove the luci-app-openthread subpackage (and its install recipe) so the UI is no longer shipped from two places. Split out of openwrt#30091 so it can be reviewed and land independently of the 2026.07.0 update. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed 3 new commits (fresh review, full PR diff). All three commit messages match their diffs.
Verified against upstream ot-br-posix at v2026.07.0 (ec16e396): the tag exists; both dropped patches are indeed upstream at that tag; OTBR_DUA_ROUTING is gone from etc/cmake/options.cmake; the "Only one Advertising Proxy can be enabled." FATAL_ERROR and the OT-core proxy defaults are as described; OTBR_MDNS=openthread is the upstream default and a valid value; --rest-listen-address / --rest-listen-port exist as required_argument long options; and the ot-ctl getopt_long() missing-terminator bug behind the -h choice in test.sh is real (-h exits 0 via PrintUsage(..., stdout, OT_EXIT_SUCCESS)).
Two things I'd look at before merge — one that blocks the CI job, and one that I think blocks the package at runtime; both are inline.
Generated by Claude Code
|
I am just dropping my 2 cents here because its funny, I individually set down yesterday updating this package on my local install without knowing that this PR was up. These are my locally made changes: diff --git a/net/openthread-br/Makefile b/net/openthread-br/Makefile
index 9486685..d49e9ae 100644
--- a/net/openthread-br/Makefile
+++ b/net/openthread-br/Makefile
@@ -4,13 +4,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=openthread-br
-PKG_SOURCE_DATE:=2025-06-12
-PKG_SOURCE_VERSION:=2f3c799c7463c8f674754e65c53f78bc0bbcbd58
-PKG_RELEASE:=2
+PKG_SOURCE_DATE:=2026-06-25
+PKG_SOURCE_VERSION:=ec16e396382b4559e70a2c6fdeecb7d596a5e915
+PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/openthread/ot-br-posix.git
-PKG_MIRROR_HASH:=fae1c7c88102f88bac32f8ee25e044b9a8781eef6b9acef39388e1e11a44a195
+PKG_MIRROR_HASH:=d19a2ea6d01d66151f769e6d23450a23d5802c5a9adf3b37fe4938fb3acf63a3
PKG_MAINTAINER:=Stijn Tintel <stijn@linux-ipv6.be>
PKG_LICENSE:=BSD-3-Clause
@@ -41,9 +41,7 @@ define Package/openthread-br
+libreadline \
+libstdcpp \
+libubox \
- +libubus \
- +mdnsd \
- +mdnsresponder
+ +libubus
endef
define Package/openthread-br/description
@@ -63,13 +61,15 @@ CMAKE_OPTIONS += \
-DOT_TARGET_OPENWRT=ON \
-DOTBR_BACKBONE_ROUTER=ON \
-DOTBR_BORDER_ROUTING=ON \
- -DOTBR_DNSSD_DISCOVERY_PROXY=ON \
+ -DOTBR_DNSSD_DISCOVERY_PROXY=OFF \
+ -DOTBR_OT_DISCOVERY_PROXY=ON \
-DOTBR_DUA_ROUTING=ON \
- -DOTBR_MDNS=mDNSResponder \
+ -DOTBR_MDNS=openthread \
-DOTBR_NAT64=OFF \
-DOTBR_OPENWRT=ON \
-DOTBR_REST=ON \
- -DOTBR_SRP_ADVERTISING_PROXY=ON \
+ -DOTBR_SRP_ADVERTISING_PROXY=OFF \
+ -DOTBR_OT_SRP_ADV_PROXY=ON \
-DOTBR_SRP_SERVER_AUTO_ENABLE=ON \
-DOTBR_TREL=ON
diff --git a/net/openthread-br/patches/101-rest-Permit-to-externally-provide-cJSON-library.patch b/net/openthread-br/patches/101-rest-Permit-to-externally-provide-cJSON-library.patch
deleted file mode 100644
index 812978c..0000000
--- a/net/openthread-br/patches/101-rest-Permit-to-externally-provide-cJSON-library.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 59c389a91cfe91eebed9c36887fa2a3eca4cbd6f Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 24 Nov 2025 18:53:28 +0100
-Subject: [PATCH] [rest] Permit to externally provide cJSON library
-
-Permit to externally provide cJSON library if found with PKGConfig.
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
----
- src/rest/CMakeLists.txt | 12 +++++++++++-
- third_party/CMakeLists.txt | 5 ++++-
- 2 files changed, 15 insertions(+), 2 deletions(-)
-
---- a/src/rest/CMakeLists.txt
-+++ b/src/rest/CMakeLists.txt
-@@ -36,11 +36,22 @@ add_library(otbr-rest
- response.cpp
- )
-
-+if (CJSON_FOUND)
-+ set(CJSON_LIB_TARGETS ${CJSON_LINK_LIBRARIES})
-+else()
-+ set(CJSON_LIB_TARGETS cjson)
-+endif()
-+
-+target_include_directories(otbr-rest
-+ PRIVATE
-+ ${CJSON_INCLUDE_DIRS}
-+)
-+
- target_link_libraries(otbr-rest
- PUBLIC
- http_parser
- PRIVATE
-- cjson
-+ ${CJSON_LIB_TARGETS}
- otbr-config
- otbr-utils
- openthread-ftd
---- a/third_party/CMakeLists.txt
-+++ b/third_party/CMakeLists.txt
-@@ -28,6 +28,13 @@
-
- add_subdirectory(openthread)
- if(OTBR_REST)
-- add_subdirectory(cJSON)
-+ pkg_check_modules(CJSON libcjson)
-+ if (CJSON_FOUND)
-+ set(CJSON_FOUND ${CJSON_FOUND} PARENT_SCOPE)
-+ set(CJSON_INCLUDE_DIRS ${CJSON_INCLUDE_DIRS} PARENT_SCOPE)
-+ set(CJSON_LINK_LIBRARIES ${CJSON_LINK_LIBRARIES} PARENT_SCOPE)
-+ else()
-+ add_subdirectory(cJSON)
-+ endif()
- add_subdirectory(http-parser)
- endif()
diff --git a/net/openthread-br/patches/102-openwrt-fix-LuCI-icons.patch b/net/openthread-br/patches/102-openwrt-fix-LuCI-icons.patch
deleted file mode 100644
index 701ae0f..0000000
--- a/net/openthread-br/patches/102-openwrt-fix-LuCI-icons.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 4b09d856fd3d82bfb6707d889fb40f981945a6a2 Mon Sep 17 00:00:00 2001
-From: Stijn Tintel <stijn@linux-ipv6.be>
-Date: Wed, 7 Jan 2026 00:20:04 +0200
-Subject: [PATCH] [openwrt] fix LuCI icons (#3178)
-
-The PNG icons in LuCI have been replaced with SVG icons.
-
-Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
----
- src/openwrt/view/admin_thread/thread_overview.htm | 10 +++++-----
- src/openwrt/view/admin_thread/thread_scan.htm | 12 ++++++------
- 2 files changed, 11 insertions(+), 11 deletions(-)
-
---- a/src/openwrt/view/admin_thread/thread_overview.htm
-+++ b/src/openwrt/view/admin_thread/thread_overview.htm
-@@ -32,7 +32,7 @@
- <!-- physical device -->
- <div class="tr cbi-rowstyle-2">
- <div class="td col-1 center middle">
-- <span class="ifacebadge"><img src="<%=resource .. "/icons/wifi.png"%>" id="wpan0" /> <%=threadget("interfacename").InterfaceName%></span>
-+ <span class="ifacebadge"><img src="<%=resource .. "/icons/wifi.svg"%>" id="wpan0" /> <%=threadget("interfacename").InterfaceName%></span>
- </div>
- <div class="td col-7 left middle">
- <big><strong><%:Generic MAC 802.15.4 Thread%></strong></big><br />
-@@ -164,13 +164,13 @@
- var scale = percent_thread_signal(info);
-
- if (scale == 0)
-- icon = "<%=resource%>/icons/signal-0.png";
-+ icon = "<%=resource%>/icons/signal-000.svg";
- else if (scale == 30)
-- icon = "<%=resource%>/icons/signal-25-50.png";
-+ icon = "<%=resource%>/icons/signal-025-050.svg";
- else if (scale == 50)
-- icon = "<%=resource%>/icons/signal-50-75.png";
-+ icon = "<%=resource%>/icons/signal-050-075.svg";
- else
-- icon = "<%=resource%>/icons/signal-75-100.png";
-+ icon = "<%=resource%>/icons/signal-075-100.svg";
-
- return icon;
- }
---- a/src/openwrt/view/admin_thread/thread_scan.htm
-+++ b/src/openwrt/view/admin_thread/thread_scan.htm
-@@ -17,17 +17,17 @@
- end
-
- if info.NetworkName == nil then
-- icon = resource .. "/icons/signal-none.png"
-+ icon = resource .. "/icons/signal-none.svg"
- elseif scale < 15 then
-- icon = resource .. "/icons/signal-0.png"
-+ icon = resource .. "/icons/signal-000.svg"
- elseif scale < 35 then
-- icon = resource .. "/icons/signal-0-25.png"
-+ icon = resource .. "/icons/signal-000-025.svg"
- elseif scale < 55 then
-- icon = resource .. "/icons/signal-25-50.png"
-+ icon = resource .. "/icons/signal-025-050.svg"
- elseif scale < 75 then
-- icon = resource .. "/icons/signal-50-75.png"
-+ icon = resource .. "/icons/signal-050-075.svg"
- else
-- icon = resource .. "/icons/signal-75-100.png"
-+ icon = resource .. "/icons/signal-075-100.svg"
- end
-
- return icon
It's clear Chris is further than I am. But I have been running this on my system last night until now and besides a few mistakes I made along the way, the update itself works. So take that for a +1 for "it won't break peoples smart homes". Edit: |
|
Glad to see I'm not the only user of this package! As for "it won't break people's smart homes"... I don't think that's a claim you can make just based on the fact you tested with your local changes. I have been running the version from my PR #29784, but initially I had mDNS issues due to both mDNSResponder and OTBR's internal mDNS implementation running simultaneously - which did break my smart home. After stopping the mDNSResponder service, things started working again. So while that confirms that the version from my PR can work, at the same time it can still break smart homes in certain corner cases. I have now closed my PR as it seems this one got more attention by people who actually use OTBR. But I will kindly request anyone not to approve this PR unless they have tested exactly the build from this PR. Maybe we can make things easier by keeping mDNSResponder for now - this would solve the problem of it conflicting with the internal mDNS implementation and we don't need to modify the protocol handler. This is not a "do this now" and I know it contradicts what I wrote earlier, but more of a "let's discuss this". A broken smart home is extremely annoying and very much not WAF-friendly and avoiding that is my main goal. I will try to set up a test setup in the coming days, so I can do extensive testing. I have 6 nRF52840 dongles, spare SBCs and spare IKEA Thread/Matter stuff in a drawer, so I don't need to go out and buy new stuff to do so. |
Fair point! I wouldn't ask to disregard all testing either, just adding a "it runs for me". :)
Agreed! While it didn't break my setup, what happend to me was:
this resulted in my /tmp being full and thats when matter devices fell out my network. I disabled mdnsd and mdnsresponder and changed the logging defaults back to normal to fix this, but 100% my own fault.
It feels like it will always be a breaking switch in terms of it requires people to change their configs. Just to add my 2 cents again, now still might be the easiest time.
100% agreed :D |
34ac20c to
4d85a3c
Compare
The LuCI web interface for OpenThread Border Router is proposed for the openwrt/luci repository as luci-app-openthread (openwrt/luci#8871), following the standard convention for LuCI apps, as requested in openwrt#29791 and openthread/ot-br-posix#3431. Remove the luci-app-openthread subpackage (and its install recipe) so the UI is no longer shipped from two places. Split out of openwrt#30091 so it can be reviewed and land independently of the 2026.07.0 update. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
|
On mDNSResponder: I don't see a reason to keep it. As far as I can tell nothing else in OpenWrt uses it, and it can't share port 5353 with umdns, which is what packages normally use to announce themselves. On the other hand, the internal implementation seems to be able to run concurrently with umdns, which seems preferable to me. |
4d85a3c to
7e7405e
Compare
openwrt-ai
left a comment
There was a problem hiding this comment.
Re-reviewed after the force-push. Diffed a1c33b2 (my last review) against 7e7405e: the four points from that round are addressed — compile-time OTBR_VENDOR_NAME/OTBR_PRODUCT_NAME, the luci-app-openthread case in test.sh, the :: example replaced by the unauthenticated-API warning, and proto_config_add_int rest_listen_port. The README rewrite goes further than I asked and is a real improvement.
Nothing blocking left. Three smaller things inline, one of which is a factual claim I could check against source and think is off.
Commit checks
-
8b615ec"openthread-br: update to 2026.07.0" — the message enumerates theCMAKE_OPTIONSchanges exhaustively and by name (dropsOTBR_SRP_ADVERTISING_PROXY,OTBR_DNSSD_DISCOVERY_PROXY,OTBR_DUA_ROUTING, each with its reason), but the diff also adds-DOTBR_PRODUCT_NAME=OTBRand-DOTBR_VENDOR_NAME=OpenWrtand the message says nothing about them. Given the message's own level of detail, that reads as an oversight rather than a summarisation choice — and these are the two options without which the daemon aborts at startup on this release, plus they change the MeshCoP instance name users see. Worth a paragraph, since this is the commit a future bisect lands on.(Placing them in this commit rather than in
7e7405eis right, though — the#ifndef OTBR_VENDOR_NAMEcheck is independent of the mDNS backend, so commit 1 stays individually bootable.)
The other two commit messages match their diffs.
CI on 7e7405e: the three FormalityCheck runs are green; Test and Build still needs a maintainer approval to run, so nothing to report there.
Generated by Claude Code
d280deb to
fb7b1bf
Compare
Switch from a pinned commit to the 2026.07.0 release tag (the latest release). Drop the two local patches whose fixes are now upstream at this tag: - 101-rest-Permit-to-externally-provide-cJSON-library.patch - 102-openwrt-fix-LuCI-icons.patch Adjust CMAKE_OPTIONS for 2026.07.0's proxy rework. The release adds OT core Advertising and Discovery Proxies that default on whenever OTBR_MDNS is set and are now mutually exclusive with the legacy POSIX proxies, so forcing OTBR_SRP_ADVERTISING_PROXY=ON and OTBR_DNSSD_DISCOVERY_PROXY=ON now fails configure with "Only one Advertising Proxy can be enabled." Drop both flags to adopt the OT core proxies, matching upstream's default build. Also drop OTBR_DUA_ROUTING, which is no longer a recognized option at this tag. Set OTBR_VENDOR_NAME and OTBR_PRODUCT_NAME. This release removed the built-in defaults that border_agent.hpp used to supply, so otbr-agent now exits with "Vendor name must be set." unless they are given at compile time or on the command line. They are set to OpenThread and BorderRouter, the values those defaults had, rather than to anything OpenWrt specific. The pair also forms the MeshCoP service instance name, as "<vendor> <product>", which is the name shown when adding the border router in a Thread client and the one already-paired clients have recorded. Keeping the previous values means upgrading does not rename anyone's border router. It also leaves OTBR_NAME at OpenThread_BorderRouter, which is what it defaulted to. Add a test.sh and a test-version.sh. The generic test requires an installed executable to print PKG_VERSION, which none of this package's binaries do: otbr-agent reports the upstream CMake project version instead. That already fails the package as it stands, independently of this update. Exercise the two binaries instead, which also covers their runtime library closure. A test.sh alone does not fix the job: CI runs the generic tests forced, so they run even when a package-specific test.sh exists, and the version check still fails. test-version.sh is what the harness uses in place of that check, as alsa-lib and avahi already do for the same reason. The mDNS provider is left unchanged here; a follow-up commit switches it to OpenThread's internal implementation. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Opus 5
As of the 2026.07.0 update, otbr-agent's REST API defaults to listening on 127.0.0.1, so remote clients (e.g. Home Assistant on another host) can no longer reach it. Add rest_listen_address and rest_listen_port proto options and pass them through to otbr-agent when set; leaving them unset keeps the secure loopback-only default. Also drop the leftover unused 'foobar' proto config option. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
Switch OTBR_MDNS from mDNSResponder to openthread, drop the mdnsd and mDNSResponder dependencies, and remove the proto handler's mdnsd service check, which would otherwise refuse to start otbr-agent now that mdnsd is no longer installed. This follows upstream, which made the internal implementation the default in openthread/ot-br-posix#2996 and uses it in its own OpenWrt example package, and it lets otbr-agent share a router with umdns, which is what advertises the router's procd-registered services (ssh, samba and the like) and resolves <hostname>.local. The two can coexist because they never contend for a name: OpenThread's mDNS names its host after the Thread extended address, while umdns keeps <hostname>.local. Both bind UDP 5353 with SO_REUSEADDR and each answers only for its own records. mDNSResponder instead takes its name from gethostname(), so it and umdns race for the same name, and the loser either stops announcing without logging anywhere procd captures or, if neither notices, both keep claiming it. That is the conflict with a running mdnsd noted in openwrt#29784. Border router discovery is unaffected: in this mode OpenThread's own border agent registers the _meshcop._udp service (its OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE follows OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE), and OTBR's publisher is disabled by design, so clients such as Home Assistant still find the border router. Note that OpenThread's mDNS serves a single interface, the one given by the backbone_network option, so Thread service records are announced on that network only. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Opus 4.8
fb7b1bf to
6f49dba
Compare
|
Fixed — Also added a |
openwrt-ai
left a comment
There was a problem hiding this comment.
Re-reviewed after the force-push. Diffed 7e7405e (my last review) against 6f49dba — four files, all of it follow-up to the previous round.
The three points from that round are addressed: OTBR_VENDOR_NAME/OTBR_PRODUCT_NAME moved to OpenThread/BorderRouter, which reproduces the instance name the removed upstream defaults produced and leaves OTBR_NAME at its CMake default, so an upgrade renames nothing; the luci-app-openthread comment now says Lua controller; and the README's socket paragraph is rewritten to drop the SO_REUSEPORT claim. The rewrite reaches the right conclusion — SO_REUSEADDR on both sockets is what admits the duplicate wildcard bind, umdns's SO_REUSEPORT sits behind its error: retry and is therefore never reached, so no reuseport group forms and there is no unicast load balancing to warn about, just non-deterministic unicast delivery. Good that the PR body was corrected to match rather than left as the outlier.
On the new test-version.sh: switching on $1 is fine — lang/erlang, utils/lpac, libs/libcap-ng and others do the same, while alsa-lib/avahi use $PKG_NAME; the harness supplies both, and $1 matches this package's own test.sh. Mode is 755, and the *) catch-all mirrors test.sh rather than silently passing. openthread/openthread#13423, cited in both scripts, exists and is merged, so "fixed upstream" is accurate and the -h workaround in test.sh is correctly explained.
All three commit messages match their diffs.
CI on 6f49dba: the three FormalityCheck runs are green; Test and Build has not run on this head, so nothing to report from logs.
Nothing blocking. Two small things inline.
Generated by Claude Code
| services. Both bind the wildcard address on port 5353 with SO_REUSEADDR, which | ||
| is what admits the second bind and gets multicast delivered to both, and they | ||
| never contend for a name: OpenThread's mDNS names its host after the Thread | ||
| extended address, while umdns keeps <hostname>.local. |
There was a problem hiding this comment.
<hostname> is bare here, so GitHub's Markdown renderer treats it as an unknown HTML tag and drops it — the sentence renders as "while umdns keeps .local.", which reads as if umdns claims the bare .local label rather than the router's own name. That's the exact distinction the paragraph exists to make.
Line 36 of this same file already backticks its placeholder (`<vendor> <product>`), so this is just the one that got missed.
| extended address, while umdns keeps <hostname>.local. | |
| extended address, while umdns keeps `<hostname>.local`. |
Generated by Claude Code
| -DOTBR_SRP_SERVER_AUTO_ENABLE=ON \ | ||
| -DOTBR_TREL=ON | ||
| -DOTBR_TREL=ON \ | ||
| -DOTBR_VENDOR_NAME=OpenThread |
There was a problem hiding this comment.
nit: the PR description's summary of commit 1 still doesn't mention this pair. It enumerates the dropped patches and each dropped CMake option by name (OTBR_SRP_ADVERTISING_PROXY, OTBR_DNSSD_DISCOVERY_PROXY, OTBR_DUA_ROUTING) but says nothing about the two options added — the ones without which otbr-agent aborts at startup on this release, and which determine the MeshCoP instance name users see in a Thread client.
The commit message and the new ### Vendor and product name README section both cover it properly now; the PR body is the one place left that reads as if the update were purely a tag bump plus option removals. Since the description is what a maintainer skims before the commits, and since the value choice here was the subject of the previous round, it seems worth a line there too.
Generated by Claude Code
📦 Package Details
Maintainer: @stintel
Description
Updates
openthread-brto the 2026.07.0 release and switches to OpenThread'sinternal mDNS, addressing the mDNS / REST issues discussed on #29784.
The LuCI separation that was the third commit here has been split out to #30096
so it can land independently; this PR will be rebased on it.
Three commits:
Update to 2026.07.0 — switch from a pinned commit to the release tag and
drop
101-rest-Permit-to-externally-provide-cJSON-library.patchand102-openwrt-fix-LuCI-icons.patch(both fixes are upstream at this tag).Also adjust
CMAKE_OPTIONSfor the release's proxy rework: 2026.07.0 adds OTcore Advertising/Discovery proxies that default on with any
OTBR_MDNSbackend and are now mutually exclusive with the legacy POSIX proxies, so the
old
OTBR_SRP_ADVERTISING_PROXY=ON/OTBR_DNSSD_DISCOVERY_PROXY=ONfailconfigure with "Only one Advertising Proxy can be enabled." Drop both to
adopt the OT core proxies, matching upstream's default build; also drop
OTBR_DUA_ROUTING, no longer a recognized option. Finally, add atest.sh(see Run Testing below).
Make the REST listen address configurable — 2026.07.0 defaults
otbr-agent's REST API to
127.0.0.1, breaking remote clients such as HomeAssistant (Bump OpenThread Border Router and switch to internal mDNS implementation #29784 issue 1). Add
rest_listen_address/rest_listen_portproto options; unset keeps the secure loopback default. Also drops the unused
foobarproto option.Use OpenThread's internal mDNS —
OTBR_MDNS=openthread, drop themdnsd/
mDNSResponderdependencies, and remove the proto handler'smdnsdservicecheck, which would otherwise refuse to start otbr-agent (Bump OpenThread Border Router and switch to internal mDNS implementation #29784 issue 2).
mDNS: internal implementation, coexisting with umdns
This follows upstream's default (openthread/ot-br-posix#2996) and, importantly,
lets otbr-agent share a router with umdns — which is what advertises the
router's
procd_add_mdnsservices (dropbear ssh, ksmbd, and on Turris thefosquittoremote-management service) and resolves<hostname>.local.The two never contend for a name: OpenThread's mDNS names its host after the
Thread extended address (
ot<ExtAddress>.local), while umdns keeps<hostname>.local. mDNSResponder instead derives its name fromgethostname(),so it and umdns race for the same name — which is the conflict you flagged in
#29784.
Tested on a workstation, not on a router:
otbr-agentbuilt-DOTBR_MDNS=openthreadagainst a simulated RCP (Threadstate=leader,ba state=Active), running alongside umdns. What that run showed:SO_REUSEADDR, which is whatadmits the second bind on a wildcard UDP port
_meshcop._udpand_trel._udpunderot<ExtAddress>.localSTATE_ANNOUNCEfor<hostname>.localwith zero conflicts,and its own
_http._tcptest service stays advertisedpython-zeroconfbrowse discovers both sets of services,each resolved to its correct host
Three caveats worth recording. OT's mDNS serves a single interface — the one
from
backbone_network— so Thread records appear on that network only; aseparate guest/IoT VLAN gets nothing. Multicast visibility is one-way: umdns
disables multicast loopback, so OT never hears umdns (harmless here, since there
is no contested name).
And only multicast reaches both daemons. A unicast datagram to 5353 is delivered
to a single socket, so a unicast reply meant for one can be received by the
other. An earlier revision of this description credited umdns's
SO_REUSEPORTretry path for the shared bind, which was wrong: umdns sets
SO_REUSEPORTonlyafter its own bind fails (interface.c), and that does not happen
here because
SO_REUSEADDRalready admits the bind — so noSO_REUSEPORTgroupforms in either start order, and there is no unicast load balancing.
🧪 Run Testing Details
Built locally against the OpenWrt SDK (x86_64 snapshot, gcc 14.4.0), replicating
the feed CI flow:
src-linkthis feed, select the package sodefconfigstagesits dependency closure, then
make package/openthread-br/{download,compile}. Thefinal tree compiles clean to
openthread-br-2026.07.0-r1.apk, with the dependencyclosure reduced to
cJSON+libnetfilter-queue(nomdnsd/mDNSResponder)and CMake reporting
OT_MDNS=ON --> OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1. Anearlier run of the same build is what surfaced the proxy-option conflict fixed in
commit 1. Coexistence was exercised separately as described above. Field testing on
a Turris Omnia NG with a Home Assistant Connect ZBT-2 is next.
A
test.shis added because the generic test requires an installed executable toprint
PKG_VERSION, and none of this package's binaries do —otbr-agentreportsthe upstream CMake project version instead. This is not caused by the version
bump: the package already fails that test on master, with its own
PKG_SOURCE_DATE-derived version (see #30096, which carries the same scripts).The test exercises
otbr-agent --versionandot-ctl -h, which also covers theirruntime library closure.
A
test-version.shis added alongside it. The generic tests run forced, so theyexecute even when a package-specific
test.shexists, and the version checkstill fails the job;
test-version.shis the override the harness looks for, asalsa-lib and avahi already use.
Separately, the generic probe also uncovered an upstream bug:
ot-ctlsegfaultson any long option it does not recognize,
--versionincluded. Itsgetopt_long()option array is missing the terminating entry, so glibc walks pastthe end of it while trying to match. Short options are unaffected, which is why
-his safe and is whattest.shuses. Fix prepared for openthread; not neededfor this PR to build.
PKG_MIRROR_HASHis pinned to the value the feed CI produces; a local repackyields a different sha only because of host
zstdversion/threading differences(the tar contents are identical). The
--rest-listen-address/--rest-listen-portoption names were checked against otbr-agent's source, andthe proto handler passes
sh -n.✅ Formalities