Skip to content

openthread-br: update to 2026.07.0, internal mDNS, configurable REST listen address - #30091

Open
LorbusChris wants to merge 3 commits into
openwrt:masterfrom
LorbusChris:openthread-br-2026.06.0
Open

openthread-br: update to 2026.07.0, internal mDNS, configurable REST listen address#30091
LorbusChris wants to merge 3 commits into
openwrt:masterfrom
LorbusChris:openthread-br-2026.06.0

Conversation

@LorbusChris

@LorbusChris LorbusChris commented Jul 25, 2026

Copy link
Copy Markdown

📦 Package Details

Maintainer: @stintel

Description

Updates openthread-br to the 2026.07.0 release and switches to OpenThread's
internal 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:

  1. Update to 2026.07.0 — switch from a pinned commit to the release tag and
    drop 101-rest-Permit-to-externally-provide-cJSON-library.patch and
    102-openwrt-fix-LuCI-icons.patch (both fixes are upstream at this tag).
    Also adjust CMAKE_OPTIONS for the release's proxy rework: 2026.07.0 adds OT
    core Advertising/Discovery proxies that default on with any OTBR_MDNS
    backend and are now mutually exclusive with the legacy POSIX proxies, so the
    old OTBR_SRP_ADVERTISING_PROXY=ON / OTBR_DNSSD_DISCOVERY_PROXY=ON fail
    configure 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 a test.sh
    (see Run Testing below).

  2. 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 Home
    Assistant (Bump OpenThread Border Router and switch to internal mDNS implementation #29784 issue 1). Add rest_listen_address / rest_listen_port
    proto options; unset keeps the secure loopback default. Also drops the unused
    foobar proto option.

  3. Use OpenThread's internal mDNSOTBR_MDNS=openthread, drop the mdnsd
    / mDNSResponder dependencies, and remove the proto handler's mdnsd service
    check, 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_mdns services (dropbear ssh, ksmbd, and on Turris the
fosquitto remote-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 from gethostname(),
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-agent built
-DOTBR_MDNS=openthread against a simulated RCP (Thread state=leader,
ba state=Active), running alongside umdns. What that run showed:

  • both bind UDP 5353 in either start order, via SO_REUSEADDR, which is what
    admits the second bind on a wildcard UDP port
  • OT registers _meshcop._udp and _trel._udp under ot<ExtAddress>.local
  • umdns reaches STATE_ANNOUNCE for <hostname>.local with zero conflicts,
    and its own _http._tcp test service stays advertised
  • a third-party python-zeroconf browse discovers both sets of services,
    each resolved to its correct host
  • on the wire, each responder answers only for its own names

Three caveats worth recording. OT's mDNS serves a single interface — the one
from backbone_network — so Thread records appear on that network only; a
separate 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_REUSEPORT
retry path for the shared bind, which was wrong: umdns sets SO_REUSEPORT only
after its own bind fails (interface.c), and that does not happen
here because SO_REUSEADDR already admits the bind — so no SO_REUSEPORT group
forms 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-link this feed, select the package so defconfig stages
its dependency closure, then make package/openthread-br/{download,compile}. The
final tree compiles clean to openthread-br-2026.07.0-r1.apk, with the dependency
closure reduced to cJSON + libnetfilter-queue (no mdnsd / mDNSResponder)
and CMake reporting OT_MDNS=ON --> OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1. An
earlier 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.sh is added because the generic test requires an installed executable to
print PKG_VERSION, and none of this package's binaries do — otbr-agent reports
the 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 --version and ot-ctl -h, which also covers their
runtime library closure.

A test-version.sh is added alongside it. The generic tests run forced, so they
execute even when a package-specific test.sh exists, and the version check
still fails the job; test-version.sh is the override the harness looks for, as
alsa-lib and avahi already use.

Separately, the generic probe also uncovered an upstream bug: ot-ctl segfaults
on any long option it does not recognize
, --version included. Its
getopt_long() option array is missing the terminating entry, so glibc walks past
the end of it while trying to match. Short options are unaffected, which is why
-h is safe and is what test.sh uses. Fix prepared for openthread; not needed
for this PR to build.

PKG_MIRROR_HASH is pinned to the value the feed CI produces; a local repack
yields a different sha only because of host zstd version/threading differences
(the tar contents are identical). The --rest-listen-address /
--rest-listen-port option names were checked against otbr-agent's source, and
the proto handler passes sh -n.

✅ Formalities

  • I have reviewed the CONTRIBUTING.md file for detailed contributing guidelines.

@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch from 522cae5 to 7aa6e5a Compare July 25, 2026 14:50
@LorbusChris LorbusChris changed the title openthread-br: update to 2026.06.0, keep mDNSResponder, configurable REST; drop luci-app openthread-br: update to 2026.07.0, keep mDNSResponder, configurable REST; drop luci-app Jul 25, 2026

@stintel stintel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@LorbusChris

Copy link
Copy Markdown
Author

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.

@stintel

stintel commented Jul 25, 2026

Copy link
Copy Markdown
Member

👍 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.

@LorbusChris

Copy link
Copy Markdown
Author

@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.

@stintel

stintel commented Jul 25, 2026

Copy link
Copy Markdown
Member

@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.

@LorbusChris

Copy link
Copy Markdown
Author

@stintel could you approve the "Test and Build" CI workflow? This should build now and I'm curious if anything else pops up.

@LorbusChris

Copy link
Copy Markdown
Author

I'd also be happy to split the 3rd commit out into its own PR so the update can go in independently.

@stintel

stintel commented Jul 25, 2026

Copy link
Copy Markdown
Member

@stintel could you approve the "Test and Build" CI workflow? This should build now and I'm curious if anything else pops up.

Done

@stintel

stintel commented Jul 25, 2026

Copy link
Copy Markdown
Member

I'd also be happy to split the 3rd commit out into its own PR so the update can go in independently.

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.

@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch from e49c1c9 to d1ae6dc Compare July 25, 2026 19:23
@LorbusChris LorbusChris changed the title openthread-br: update to 2026.07.0, keep mDNSResponder, configurable REST; drop luci-app openthread-br: update to 2026.07.0, keep mDNSResponder, configurable REST Jul 25, 2026
@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch from d1ae6dc to bc2d58f Compare July 25, 2026 20:20
@LorbusChris LorbusChris changed the title openthread-br: update to 2026.07.0, keep mDNSResponder, configurable REST openthread-br: update to 2026.07.0, internal mDNS, configurable REST listen address Jul 25, 2026
@LorbusChris

Copy link
Copy Markdown
Author

Switched to OTBR_MDNS=openthread as you preferred — that also takes care of both blockers you mentioned on #29784 (the REST bind, and the proto handler's mdnsd check).

I tested it alongside umdns on a simulated RCP and they seem to get along fine: OT names its host ot<ExtAddress>.local rather than taking <hostname>.local, so there's nothing to fight over. Both bound 5353 in either start order, umdns kept announcing normally, and a zeroconf browse picked up _meshcop._udp and _trel._udp alongside umdns's own services.

One thing worth knowing: OT's mDNS only serves the single backbone_network interface, so a separate guest/IoT VLAN wouldn't see Thread records.

Also added a test.sh — with the release tag in PKG_VERSION the generic version check can't pass, since otbr-agent reports the CMake project version. And the LuCI removal is split out to #30096.

Hardware testing on a Turris Omnia NG + ZBT-2 next. Mind re-approving the build workflow?

@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch 2 times, most recently from a12c137 to a1c33b2 Compare July 25, 2026 22:58
LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 25, 2026
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
LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 25, 2026
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 openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread net/openthread-br/Makefile Outdated
Comment thread net/openthread-br/test.sh
Comment thread net/openthread-br/files/openthread-proto.sh Outdated
Comment thread net/openthread-br/files/openthread-proto.sh Outdated
Comment thread net/openthread-br/Makefile
@TimB87

TimB87 commented Jul 26, 2026

Copy link
Copy Markdown

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:
As for my setup over here, I have an SLZB-06M with Thread firmware running, using socat on openwrt to create a socket that otbr-agent can connect to.

@stintel

stintel commented Jul 26, 2026

Copy link
Copy Markdown
Member

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.

@TimB87

TimB87 commented Jul 26, 2026

Copy link
Copy Markdown

I don't think that's a claim you can make just based on the fact you tested with your local changes.

Fair point! I wouldn't ask to disregard all testing either, just adding a "it runs for me". :)

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.

Agreed! While it didn't break my setup, what happend to me was:

  • mdnsd and mdnsresponder spamming /tmp/log/messages
  • me running otbr-agent with verbose output - spamming /tmp/log/messages as well

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.

Maybe we can make things easier by keeping mDNSResponder for now

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.

not WAF-friendly

100% agreed :D

@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch 2 times, most recently from 34ac20c to 4d85a3c Compare July 26, 2026 15:06
LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 26, 2026
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
@LorbusChris

Copy link
Copy Markdown
Author

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.

@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch from 4d85a3c to 7e7405e Compare July 26, 2026 15:15

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the CMAKE_OPTIONS changes exhaustively and by name (drops OTBR_SRP_ADVERTISING_PROXY, OTBR_DNSSD_DISCOVERY_PROXY, OTBR_DUA_ROUTING, each with its reason), but the diff also adds -DOTBR_PRODUCT_NAME=OTBR and -DOTBR_VENDOR_NAME=OpenWrt and 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 7e7405e is right, though — the #ifndef OTBR_VENDOR_NAME check 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

Comment thread net/openthread-br/README.md Outdated
Comment thread net/openthread-br/test.sh Outdated
Comment thread net/openthread-br/Makefile Outdated
@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch 2 times, most recently from d280deb to fb7b1bf Compare July 27, 2026 12:20
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
@LorbusChris
LorbusChris force-pushed the openthread-br-2026.06.0 branch from fb7b1bf to 6f49dba Compare July 27, 2026 12:32
@LorbusChris

Copy link
Copy Markdown
Author

Fixed — openthread-br: update to 2026.07.0 now covers the two options it adds,
including that they are required at this tag and that they set the MeshCoP
instance name.

Also added a test-version.sh. The generic tests run forced, so they execute
even with a package-specific test.sh present
(test_entrypoint.sh:349)
and the version check still failed the job; test-version.sh is the override the harness looks
for, as alsa-lib and avahi use. That was the CI failure on #30096, which now
carries the same script.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<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.

Suggested change
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants