Skip to content

Bump OpenThread Border Router and switch to internal mDNS implementation - #29784

Closed
stintel wants to merge 3 commits into
openwrt:masterfrom
stintel:bump/otbr
Closed

Bump OpenThread Border Router and switch to internal mDNS implementation#29784
stintel wants to merge 3 commits into
openwrt:masterfrom
stintel:bump/otbr

Conversation

@stintel

@stintel stintel commented Jun 19, 2026

Copy link
Copy Markdown
Member

📦 Package Details

Maintainer: me

Description:
Bump OpenThread Border Router and switch to internal mDNS implementation


🧪 Run Testing Details

  • OpenWrt Version: OpenWrt master r34992-0d7add7433
  • OpenWrt Target/Subtarget: sunxi/cortexa53
  • OpenWrt Device: Olimex A64-Olinuxino-eMMC

✅ Formalities

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

Comment thread net/openthread-br/Makefile Outdated
Comment thread net/openthread-br/test-version.sh Outdated
Comment thread net/openthread-br/Makefile
#!/bin/sh

case "$1" in
luci-app-openthread)

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.

This luci-app should moved to the LuCI repo. Ideally those all files related to LuCI in openthread repository should be upstreamed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's not in scope for a version bump PR.

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.

I understand this isn't exactly within the scope of this specific pull request. However, when openthread-br (#19218) was added, no issue was created for decoupling the LuCI files, and I just noticed this 3 years later. If we just say it's out of scope for the PR, then yes, you are absolutely right about that, which is why I created these issues:

So that it can actually be resolved properly and once and for all. :)

-DOTBR_SRP_SERVER_AUTO_ENABLE=ON \
-DOTBR_TREL=ON
-DOTBR_TREL=ON \
-DOTBR_VENDOR_NAME="OpenThread" \

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.

I wonder, not looked at it closely, shouldnt it be as OpenWrt? 🤔

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I have considered this, but the CMake build does this:

    set(OTBR_NAME "${OTBR_VENDOR_NAME}_${OTBR_PRODUCT_NAME}" CACHE STRING "The package name")

That would result in the package being name "OpenWrt-BorderRouter", which doesn't really make sense. We could go for VENDOR=OpenWrt PRODUCT=OpenThread-BorderRouter, or we could remove both variables which would expose --vendor-name and --product-name runtime options, but we'd have to integrate that in the netifd proto handler. I do not have a strong preference for either, so I went with what upstream does by default in their container.

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.

In that case, I'm wondering how they work with this in openthread-br going forward. Do they use it for some statistics, and do they even collect data at all?

stintel added 3 commits June 23, 2026 09:14
This is the first release with a proper version tag, unfortunately the
git source tarballs do not include the submodules, so we can not use
them. Use the version tag in PKG_SOURCE_VERSION instead of the commit
hash, so it is clear from the resulting file which version it is.

Remove upstreamed patches.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
Upstream switched to internal mDNS implementation in commit
openthread/ot-br-posix@fbf1e82.

Drop the mDNSresponder dependencies as they are no longer needed.

Also drop CMake options that conflict with upstream's new defaults.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
CI has a version check script that checks for PKG_VERSION in the output
of binaries included in the package. The binaries in this package do not
return the actual version:

  root@iot-br1:~# /usr/sbin/otbr-agent --version
  0.3.0
  root@iot-br1:~# /usr/sbin/ot-ctl version
  OPENTHREAD/; POSIX; May 29 2026 22:35:39
  Done

Add a minimal custom version check script to avoid CI failures.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
@neheb

neheb commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

So with a USB dongle implementing openthread at /dev/ttyACM0 , I get

Runtime error
Unhandled exception during request dispatching
/usr/lib/lua/luci/ucodebridge.lua:23: /usr/lib/lua/luci/template.lua:181: Failed to execute template 'admin_thread/thread_overview'.
A runtime error occurred: [string "/usr/lib/lua/luci/view/admin_thread/thread_..."]:24: attempt to index a nil value
stack traceback:
[string "/usr/lib/lua/luci/view/admin_thread/thread_..."]:24: in main chunk

In error(), file [C]
called from function [anonymous function] (/usr/lib/lua/luci/ucodebridge.lua:23)
called from function ((tail call))
In [anonymous function](), file /usr/share/ucode/luci/runtime.uc, line 148, byte 45:
  called from function [arrow function] (/usr/share/ucode/luci/dispatcher.uc:810:71)
  called from function render ([C])
  called from function render_action (/usr/share/ucode/luci/dispatcher.uc:797:24)
  called from function run_action (/usr/share/ucode/luci/dispatcher.uc:811:5)
  called from function [anonymous function] (/usr/share/ucode/luci/dispatcher.uc:1107:48)
  called from anonymous function (/www/cgi-bin/luci:39:13)

 `        return lcall.call(modname, method, ...args);`
  Near here ----------------------------------------^

Is this normal or something else needs to be done?

+libubox \
+libubus \
+mdnsd \
+mdnsresponder

@neheb neheb Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So this was the only user of mdnsresponder. I think mdnsresponder should be removed in a follow up PR.

@stintel
stintel marked this pull request as draft June 26, 2026 08:26
@stintel

stintel commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

This needs more work:

  • HTTP REST server now binds to 127.0.0.1 by default so e.g. Home Assistant on a different host can no longer connect to it
  • netifd proto handler checks for service mdnsd and fails if it's not running - since it's no longer a dependency otbr-agent will not be started
  • if mdnsd is running this conflicts with the internal mDNS implementation, possibly the same problem happens when avahi is running

LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 25, 2026
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 Fable 5
LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 25, 2026
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 added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 25, 2026
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
@stintel

stintel commented Jul 26, 2026

Copy link
Copy Markdown
Member Author

Let's continue this in #30091.

@stintel stintel closed this Jul 26, 2026
@openwrt

openwrt Bot commented Jul 26, 2026

Copy link
Copy Markdown

Formality Check: Suggestions Available

We completed the verification flow. Please review the formatting overview logs below.

⚠️ STYLISTIC WARNINGS & SUGGESTIONS

Package Release Audit:

  • ⚠️ Package net/openthread-br version updated from '2f3c799c7463c8f674754e65c53f78bc0bbcbd58' to '2026.06.0', but PKG_RELEASE was not reset to 1 (currently: '2')

Something broken? Consider reporting an issue.
Running version 516b28e deployed on 2026-07-26 09:31:58 CEST

LorbusChris added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 26, 2026
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 added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 26, 2026
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 added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 27, 2026
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 added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 27, 2026
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 added a commit to LorbusChris/openwrt-packages that referenced this pull request Jul 27, 2026
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
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