Build and Installation Instructions for the Border Router Host#
Note: In theory, the same Border Router host should work with both RCP and NCP architectures. The host automatically detects whether it is communicating with an RCP or NCP device and switches its operating mode accordingly. However, due to some advanced 1.4 OTBR features, we recommend different build steps for the host for RCP and NCP architectures. See Build Steps.
Install the Hardware#
Connect each Wireless Starter Kit main board and the host computer to an Ethernet switch with an Ethernet cable as shown in the following figure. These connections will permit programming and network analysis of the Co-Processor and end devices. Optionally, end devices may be connected to the host computer by USB rather than Ethernet. To connect Raspberry Pi Border Router with a Co-Processor over SPI, you can either hardwire the SPI pins with WSTK's expansion connector or you can use wireless expansion board (brd8016), which mounts on the top of Raspberry Pi.


Hardwire SPI Connections Between Raspberry Pi and WSTK#
Connect the SPI pins as shown below:
Raspberry Pi Connector (SPI Pins) | WPK’s Expansion Connector (brd4002) |
|---|---|
GPIO10 / Pin19 (MOSI) | Pin 4 |
GPIO9 / Pin21 (MISO) | Pin 6 |
GPIO11 / Pin23 (SCLK) | Pin 8 |
GPIO7/8 / Pin24/26 (CS0/CS1) | Pin 10 |
GPIO21 / Pin40 (Interrupt line) | Pin 7 |
GND / Pin 6 | Pin 1 |
GPIO20 / Pin38 (Reset line) | Pin F4 on breakout connector |


Wireless Expansion Board for SPI Connections Between Raspberry Pi and WSTK#
You can also use a wireless expansion board, which mounts on the top of Raspberry Pi to avoid hardwire connection, as shown below.


Note: Use correct OTBR_AGENT_OPTS as described in section OTBR Configurations using SPI Interface depending on the SPI connections.
Install and Configure a Raspberry Pi for Use with a Co-Processor#
Three different methods for installing the OTBR software in a Raspberry Pi for use with a Co-Processor are:
Manual installation
Pre-built packages for Debian bookworm
Docker container (older releases only)
Manual Installation#
This guide covers how to build the OTBR using the tools provided by the Silicon Labs Simplicity SDK. You may also install the OTBR using the instructions detailed at https://openthread.io/guides/border-router/build. Note that this is a different build option, and either guide may be followed to build the OTBR.
Begin by cloning the Simplicity SDK repository:
git clone https://github.com/SiliconLabsSoftware/sisdk-release.gitCheck out the desired SDK branch. For this guide, we use the sisdk-2026.6 branch.
For the rest of this document, $SDK_DIR refers to the location the above repo is checked out. Set this variable now:
export SDK_DIR=<absolute path to the SDK checkout>Silicon Labs maintains both openthread and ot-br-posix as forks of their respective upstream projects. To make the changes transparent, the SDK package ships the following under $SDK_DIR/openthread_stack/:
README.md— overview of the patch files and how to inspect or apply themopenthread.patch— diff between the upstreamopenthreadbase commit and the Silicon Labs forkot-br-posix.patch— diff between the upstreamot-br-posixbase commit and the Silicon Labs forkupstream-commits— the upstream base commit for each repositoryCHANGELOG.md— per-release summary of fork changes relative to upstream
The upstream commit SHAs are also listed in the Silicon Labs OpenThread Release Notes. You can use the patch files to inspect exactly what Silicon Labs changed, reproduce the diff independently, or apply it to your own fork with git apply.
Make sure that this symbolic link is present. If it does not exist, create it:
ln -s $SDK_DIR/openthread_stack/util/third_party/openthread \
$SDK_DIR/openthread_stack/util/third_party/ot-br-posix/third_party/openthread/repoConfiguration Options Reference#
Starting with SiSDK 2026.6, we recommend that the bootstrap and setup scripts accept explicit environment variables that control which service implementations are compiled in. These must be passed consistently to both the bootstrap and setup steps.
The tables below document every environment variable recognized by ./script/bootstrap and ./script/setup. Variables shared by both scripts must be set to the same value for each script.
./script/bootstrap
bootstrap resolves system package dependencies. These variables control which optional packages are installed.
Variable | Repo Default | RCP Default | NCP Default | Description | Values |
|---|---|---|---|---|---|
|
|
|
| Select mDNS implementation |
|
|
|
|
| Select DHCPv6 Prefix Delegation client |
|
|
|
|
| Install NAT64-related packages (iptables, bind9) |
|
|
|
|
| Select NAT64 translator implementation |
|
|
|
|
| Install backbone router library packages ( |
|
|
|
|
| Install firewall packages ( |
|
|
|
|
| Install web GUI dependencies (nodejs, npm) |
|
|
|
|
| Install reference device packages ( |
|
|
|
|
| Install additional packages required for backbone CI testing ( |
|
./script/setup#
setup builds and installs the border router. These variables govern which Thread features are compiled in and how the infrastructure link is configured.
Variable | Repo Default | RCP Default | NCP Default | Description | Values |
|---|---|---|---|---|---|
|
| Valid interface | Valid interface | Infrastructure network interface name | Any valid interface, e.g. |
|
|
|
| mDNS implementation compiled into |
|
|
|
|
| DHCPv6 PD client compiled in; |
|
|
|
|
| Enable NAT64 support ( |
|
|
|
|
| NAT64 dataplane translator |
|
|
|
|
| IPv4 address pool for the OpenThread NAT64 translator; passed as | Any valid CIDR |
|
|
|
| Enable Thread border routing (IPv6 RA install/forwarding) |
|
|
|
|
| Enable Thread Backbone Router feature ( |
|
|
|
|
| Enable DNS-SD discovery proxy; automatically disabled when |
|
|
|
|
| Install and enable the |
|
|
|
|
| Build the OTBR web management UI ( |
|
|
|
|
| Build the OTBR REST API ( |
|
|
|
|
| Build as a Thread certification reference device; sets |
|
|
|
|
| Vendor name advertised by the OTBR service ( | Any string |
|
|
|
| Product name advertised by the OTBR service ( | Any string |
| (unset) | (see build command) | (see build command) | Additional CMake | Any valid CMake flags |
Note:
OTBR_MDNS=avahiis deprecated as of SiSDK 2026.6 and is not recommended.
Build Steps#
Note: The values shown below are what Silicon Labs builds the host with when qualifying our co-processor for certification. Alternate values are supported — if your integration requires a different combination, try the available options. For example, if your ecosystem relies on mDNSResponder, set
OTBR_MDNS=mDNSResponderindependently.
Set up the required environment variable before running any build commands (if not already set):
export SDK_DIR=<absolute path to the SDK checkout>For the following steps, run from the ot-br-posix directory in the SDK:
cd $SDK_DIR/openthread_stack/util/third_party/ot-br-posix/Step 1: Run the bootstrap script
For RCP:
sudo OTBR_MDNS=openthread OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 NAT64_SERVICE=openthread \
./script/bootstrapFor NCP:
sudo OTBR_MDNS=mDNSResponder OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 NAT64_SERVICE=tayga \
./script/bootstrapStep 2: Copy the Silicon Labs configuration header
To use Silicon Labs-specific configuration settings for border router, copy the special configuration header hosted in the SDK:
sudo cp $SDK_DIR/openthread/platform-abstraction/posix/openthread-core-silabs-posix-config.h \
$SDK_DIR/openthread_stack/util/third_party/openthread/src/posix/platform/Note: This configuration header overrides many settings to recommended values from the certifiable OTBR configuration. Review the file for any settings specific to your scenario.
Step 3: Run the setup script
Adjust INFRA_IF_NAME to match your network interface (eth0 for Ethernet, wlan0 for Wi-Fi).
These examples are for UART. To build OTBR with SPI interface, include the -DOT_POSIX_RCP_SPI_BUS=ON flag in OTBR_OPTIONS.
For RCP:
sudo INFRA_IF_NAME=eth0 OTBR_MDNS=openthread OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 \
NAT64_SERVICE=openthread \
OTBR_OPTIONS="-DOT_THREAD_VERSION=1.4 -DOT_PLATFORM_CONFIG=openthread-core-silabs-posix-config.h \
-DOTBR_DUA_ROUTING=ON -DOTBR_DHCP6_PD=ON" \
./script/setupFor NCP:
sudo INFRA_IF_NAME=eth0 OTBR_MDNS=mDNSResponder OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 \
NAT64_SERVICE=tayga \
OTBR_OPTIONS="-DOT_THREAD_VERSION=1.4 -DOT_PLATFORM_CONFIG=openthread-core-silabs-posix-config.h \
-DOTBR_DUA_ROUTING=ON -DOTBR_DHCP6_PD=ON" \
./script/setupRefer to openthread/src/core/config and openthread/examples/README.md for compile-time constants and cmake build options, respectively.
Build Troubleshooting#
Missing .default-version file**#
If CMake reports an error such as:
file failed to open for reading: .../third_party/openthread/repo/.default-version
Create the missing file manually from the root of ot-br-posix before re-running setup:
echo "0.01.00" > ./third_party/openthread/repo/.default-version
OTBR Feature Configuration for Certification#
For information on how to properly configure OpenThread Border Router features and services, visit https://openthread.io/guides/border-router.
Important: For Thread Certification, the OpenThread and ot-br-posix repositories used for your build must be based on one of the following:
The versions included in the Silicon Labs Simplicity SDK for the target release (as described in Manual Installation), or
The specific upstream commits associated with the release, listed in the Silicon Labs OpenThread Release Notes.
Builds based on unverified forks or commits not tied to a supported release are not suitable for certification.
For information on Thread 1.4, see Configuring OpenThread Applications for Thread 1.4.
The build commands for a Thread Certification Device Under Test (DUT) are as follows. Run from $SDK_DIR/openthread_stack/util/third_party/ot-br-posix/ (set $SDK_DIR as described in Build Steps). Use the RCP or NCP variant as appropriate for your co-processor type.
RCP — bootstrap:
sudo OTBR_MDNS=openthread OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 NAT64_SERVICE=openthread \
./script/bootstrapRCP — setup:
sudo INFRA_IF_NAME=eth0 OTBR_MDNS=openthread OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 \
NAT64_SERVICE=openthread \
OTBR_OPTIONS="-DOT_THREAD_VERSION=1.4 -DOT_PLATFORM_CONFIG=openthread-core-silabs-posix-config.h \
-DOTBR_DUA_ROUTING=ON -DOTBR_DHCP6_PD=ON" \
./script/setupNCP — bootstrap:
sudo OTBR_MDNS=mDNSResponder OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 NAT64_SERVICE=tayga \
./script/bootstrapNCP — setup:
sudo INFRA_IF_NAME=eth0 OTBR_MDNS=mDNSResponder OTBR_DHCP6_PD_CLIENT=dhcpcd NAT64=1 \
NAT64_SERVICE=tayga \
OTBR_OPTIONS="-DOT_THREAD_VERSION=1.4 -DOT_PLATFORM_CONFIG=openthread-core-silabs-posix-config.h \
-DOTBR_DUA_ROUTING=ON -DOTBR_DHCP6_PD=ON" \
./script/setupOTBR Serial Configuration#
OTBR Configurations Using UART Interface#
Configure the desired tty* port to use for the OTBR to connect your Co-Processor at startup. Look for the tty* port of the Co-Processor device. The easiest way to do this is to look for a
/tty/dev…entry once the device is connected. It should generally either be/dev/ttyUSB0or/dev/ttyACM0.Edit the
/etc/default/otbr-agentfile and look for theOTBR_AGENT_OPTSconfiguration. Include the tty* port name in that parameter as follows:OTBR_AGENT_OPTS="-I wpan0 spinel+hdlc+uart:///dev/ttyACM0"If running a Backbone Border Router (Thread protocol version 1.2 or above), add the backbone interface as follows:
OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+hdlc+uart:///dev/ttyACM0"If running a Thread 1.3 or greater Border Router, specify the Thread Radio Encapsulation Link (TREL) interface to enable Thread over Infrastructure links as follows:
OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+hdlc+uart:///dev/ttyACM0 trel://eth0"UART Baud Rate Settings#
By default, OTBR agent (the host daemon) is built to work with a baud rate of 460800. We recommend this configuration for a lot of realistic OTBR deployment scenarios. Please make sure your Co-Processor and WSTK/WPK/STK adapter are configured accordingly.
If you wish to change the default baud rate, we recommend that you update the radio URL options:
For example, to lower the baud rate to 115200:
OTBR_AGENT_OPTS="-I wpan0 spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=115200 trel://eth0"If intending to change this value, you must also match the correct baud rate on the adapter board by issuing the following command on the admin console of the Co-Processor WSTK/WPK/STK adapter:
> serial vcom config speed 115200 (optional if you have updated adapter firmware that will autosense this rate)
Make sure to also set the correct baud rate in your Co-Processor project in the IO STREAM USART or IO STREAM EUSART component as shown in the following figure:


To verify the baud rate in use, issue the command:
stty -F /dev/ttyACM0
OTBR Configurations using SPI Interface#
Configure the desired SPI ports to use for the OTBR to connect your Co-Processor at startup. Ensure the SPI interface is enabled on the Raspberry Pi. If not:
Enable it by adding following in /boot/config.txt
dtparam=spi=on dtoverlay=disable-bt #Maybe not requiredRemove/comment
dtoverlay=spi0-1cs,cs0_pin=26if it is defined in /boot/config.txt.Reboot the Raspberry Pi.
Use this command to validate the SPI port
ls /dev | grep spi.Two devices should be visible,
spidev0.0andspidev0.1, depending on your Raspberry Pi version.Edit the
/etc/default/otbr-agentfile and look for the OTBR_AGENT_OPTS configuration. Include the correct GPIOs in that parameter as per the hardware setup in sections Hardwire SPI Connections Between Raspberry Pi and WSTK and Wireless Expansion Board for SPI Connections Between Raspberry Pi and WSTK.Use the following parameters if Raspberry Pi is hardwired to SPI pins on WSTK’s expansion connector. Use spidev0.0 if using Raspberry Pi’s CS0 or replace to spidev0.1 for CS1 pin.
OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+spi:///dev/spidev0.0?gpio-int-device=/dev/gpiochip0&gpio-int-line=21&gpio-reset-device=/dev/gpiochip0&gpio-reset-line=20&no-reset=1&spi-speed=1000000"Use the following parameters if the radio board is mounted on Raspberry Pi using wireless expansion board (brd8016A).
OTBR_AGENT_OPTS="-I wpan0 -B eth0 spinel+spi:///dev/spidev0.0?gpio-int-device=/dev/gpiochip0&gpio-int-line=22&gpio-reset-device=/dev/gpiochip0&gpio-reset-line=23&no-reset=1&spi-speed=1000000"If using custom hardware connections, make sure to provide respective GPIOs pins.
Start
otbr-agentservice by either rebooting the Raspberry Pi or issue> sudo systemctl restart otbr-agent.Issue the
> sudo ot-ctl statecommand on the Raspberry Pi to see the status of the connection between the host and Co-Processor.Check whether all required services are running on the OTBR.
sudo systemctl statusshould not report any services as running in a “degraded” state.Check
/var/log/syslogfor a running log of otbr-agent.
OTBR Configuration for CSL#
Note: This setting applies only when OpenThread runs on an RCP. In NCP mode the Thread stack runs on the co-processor, so this host-side configuration does not apply.
When the OTBR acts as a CSL transmitter with an RCP, you may see Handle transmit done failed: Abort if OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US is too low. Use 5000 µs with Series-2 RCPs and 18000 µs with Series-3 RCPs. Series-3 may require more preparation lead time today; Silicon Labs continues to optimize this path.
This value controls how early the host hands the frame to the radio stack. The on-air transmit time stays anchored to the child's CSL receive window, so extra lead time does not change over-the-air timing.
The bundled openthread-core-silabs-posix-config.h uses 18000 µs so one configuration works with both RCP families. Use the latest header when following Build Steps.
If building the OTBR on your own using the instructions on the OpenThread website, then either:
Modify the value of
OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_USinot-br-posix/third_party/openthread/repo/src/core/config/mac.hor
Include the configuration flag under
OTBR_OPTIONS, using5000for Series-2 RCPs or18000for Series-3 RCPs:-DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US=5000'-DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US=18000'
Pre-built Option - Host Packages#
Refer to Running Host Applications with Pre-Built Packages for a sample OTBR package built for Debian bookworm for the CPC/multiprotocol architecture, which can still be run purely for the Thread interface.
Pre-built Option - Docker Installation#
Note: The following Docker containers are only supposed to be used with older GSDKs (prior to 2025.12), for RCPs built using Simplicity Studio for those SDKs. Be sure to match the container tag version with the Simplicity SDK version that you are using for testing.
https://hub.docker.com/r/siliconlabsinc/openthread-border-router/tags
Prerequisites#
On the SD card, make sure to flash the Raspberry Pi OS Lite image or Raspberry Pi OS with Desktop.
Make sure to update the local repositories and package manager (apt-get update and apt-get upgrade prior to installing Docker).
Optional but recommended: Install Haveged for better entropy conditions.
Installation Guidance#
Note: Replace the string <version> in the following commands with the actual version you are using. For example, gsdk-4.4.0, sisdk-2024.6.0, etc.
Make sure to reboot after any updates:
curl -sSL https://get.docker.com | shOnce finished, you can modify the Docker user settings to not require sudo before each command:
sudo usermod -aG docker $USERRaspberry Pi and Linux users, make sure to run:
sudo modprobe ip6table_filterfor OTBR firewall support. This allows OTBR scripts to create rules inside the Docker container before otbr-agent starts.
To make sure this setting persists between reboots, add the following line to
/etc/modules:ip6table_filterIf this step is not completed, modprobe errors may be displayed when starting a Docker container.
Issue the following commands to install the containers. Note that only one Border Router container can be running at one time with a Co-Processor. Also, be sure to verify the device version (Thread protocol version 1.4) that should be run against this container.
UART interface: docker pull siliconlabsinc/openthread-border-router:<version> SPI interface: docker pull siliconlabsinc/openthread-border-router:<version>_spiTo run an OpenThread Border Router (default is Thread protocol version 1.4), issue the following command:
Example for UART interface
docker run -d --name "otbr" \ --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \ -p 8080:80 --dns=127.0.0.1 -it \ --volume /dev/ttyACM0:/dev/ttyACM0 \ --privileged siliconlabsinc/openthread-border-router:<version> \ --radio-url “spinel+hdlc+uart:///dev/ttyACM0” \ --backbone-interface eth0
See sections OTBR Configurations Using UART Interface and UART Baud Rate Settings for notes on configuring the UART Radio URL.
Example for SPI interface (for more information, see OTBR Configurations using SPI Interface)
docker run -d --name "otbr" \
--sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \
-p 8080:80 --dns=127.0.0.1 -it \
--volume /dev/spidev0.0:/dev/spidev0.0 \
--privileged siliconlabsinc/openthread-border-router:<version> \
--radio-url “spinel+spi:///dev/spidev0.0?gpio-int-device=/dev/gpiochip0&gpio-int-line=21&gpio-reset-device=/dev/gpiochip0&gpio-reset-line=20&no-reset=1&spi-speed=1000000” \
--backbone-interface eth0(See section OTBR Configurations using SPI Interface for notes on configuring the SPI Radio URL.)
Use additional arguments to configure the containers. For more information, see the section below or the Dockerfile in the ot-br-posix installation directory.
Docker Configuration Notes#
Note: Silicon Labs-hosted Docker containers are only supposed to be used with RCPs built using Simplicity Studio for a given release. Be sure to match the container tag version with the Simplicity SDK version that you are testing with.
Note: Replace the string <version> in the following commands with the actual version you are using. For example, gsdk-4.4.0, sisdk-2024.6.0, etc.
Configure the desired TTY port for the OTBR to connect the Co-Processor at startup. Look for the TTY port of the Co-Processor device. The easiest way to do this is to look for a /tty/dev… entry once the device is connected. It should generally either be
/dev/ttyUSB0or/dev/ttyACM0.Run the Docker installation as follows (example for UART interface):
docker run -d --name "otbr" \
--sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" \
-p 8080:80 --dns=127.0.0.1 -it \
--volume /dev/ttyACM0:/dev/ttyACM0 \
--privileged siliconlabsinc/openthread-border-router:<version> \
--radio-url “spinel+hdlc+uart:///dev/ttyACM0” \
--backbone-interface eth0-densures that the container runs in detached mode.Review the running logs for the container any time using the
docker logscommand.--nameis sticky until the docker container is properly closed (or removed).Port
8080indicates the port of the web server hosting the Border Router management webpage.Issue commands directly to the container without having to attach to it:
docker exec -ti otbr sh -c "sudo ot-ctl state"For more information, see the docker exec documentation.
Directly obtain an interactive shell above by issuing this command:
docker exec -ti otbr sh -c "sudo ot-ctl"Check the window running the OTBR Docker container for running log output of the Border Router, or follow the container log as follows:
docker logs [container-id] -fManage the containers as shown below if they are loaded improperly:
# list all container images docker images otbr # remove existing container docker image rm -f \<container ID\> # list running containers docker ps -a # to remove running container docker rm -f \<container name\>
Usage#
Check whether all required services are running on the OTBR.
sudo systemctl status should not report any services as running in a “degraded” state.
Check /var/log/syslog for a running log of otbr-agent.
For a full command list, run:
> sudo ot-ctl helpRefer to https://openthread.io/guides/border-router/form-network or https://openthread.io/guides/border-router/external-commissioning for examples on how to manually set up a Thread Network, by hand (out-of-band) or using external commissioning.
Run these two commands to check for a running Thread Network:
> sudo ot-ctl stateand
> sudo ot-ctl ifconfigNote: The error message OpenThread Daemon is not running indicates a problem with the Co-Processor connection. Check both for a valid /dev/tty entry and that a valid Co-Processor application was flashed onto the device.
Known Issues#
When OpenThread runs on the NCP (network co-processor), the border router does not forward DNS queries from Thread devices to upstream resolvers on the infrastructure link, so upstream DNS forwarding is not supported in NCP mode. Product flows where the border router must resolve arbitrary Internet names for Thread clients are out of scope for this release. If you need assistance implementing upstream DNS forwarding or integrating a host-side DNS forwarder into an NCP OTBR platform image, please contact Silicon Labs support.
Guidance#
Silicon Labs does not recommend using the default NAT configuration on a network using 192.168.x.x addresses because that NAT uses those addresses by default on the NAT64 interface.
For properly resolving mDNS queries, make sure the "hosts:" line under /etc/nsswitch.conf looks like the following:
hosts: files mdns4 minimal mdns5 minimal dnsIf using native OpenThread based DHCP prefix delegation client, dhcpcd management of ipv6 should be disabled.
Check that the following lines are present in /etc/dhcpcd.conf:
noipv6
noipv6rs