Run OTBR Docker

OpenThread Border Router (OTBR) requires a Thread NCP node in order to join a Thread network. OTBR Docker provides support for both a physical NCP (OpenThread dongle) or an emulated NCP (POSIX NCP application).

If you want to connect OTBR Docker to other physical Thread devices, use a physical NCP. If you want to test border routing with a simulated Thread network, use an emulated NCP.

Physical NCP

Use any supported OpenThread platform for the physical NCP. See the Build and flash NCP step from the OpenThread Border Router Build and Configuration guide for more information.

Attach the NCP

  1. After building and flashing, attach the NCP device to the machine running OTBR Docker via USB.
  2. Determine the serial port name for the NCP device by checking /dev:
    ls /dev/tty*
    /dev/ttyACMO

Start the OTBR Docker container

In a new terminal window, start OTBR Docker, referencing the NCP's serial port. For example, if the NCP is mounted at /dev/ttyACM0:

docker run --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 openthread/otbr \
        --ncp-path /dev/ttyACM0

Upon success, you should have output similar to this:

WARNING: Localhost DNS setting (--dns=127.0.0.1) may fail in containers.
--ncp-path
NCP_PATH: /dev/ttyACM0
TUN_INTERFACE_NAME: wpan0
NAT64_PREFIX: 64:ff9b::/96
AUTO_PREFIX_ROUTE: true
AUTO_PREFIX_SLAAC: true
Current platform is ubuntu
* Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-link-restrictions.conf ...
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /etc/sysctl.d/60-otbr-ip-forward.conf ...
net.ipv6.conf.all.forwarding = 1
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
 * Starting userspace NAT64 tayga             [ OK ]
/usr/sbin/service
 * Starting domain name service... bind9      [ OK ]
/usr/sbin/service
 * dbus is not running
 * Starting system message bus dbus           [ OK ]
   ...fail!
wpantund[139]: Starting wpantund 0.08.00d (Sep 28 2018 14:21:43) . . .
wpantund[139]:  BUILD_VERSION = 16bc8a0
wpantund[139]: Configuration file "/etc/wpantund.conf" read.
wpantund[139]: Ready. Using DBUS bus ":1.0"
wpantund[139]: Running as root without dropping privileges!
wpantund[139]: [-NCP-]: NCP was reset (STATUS_RESET_POWER_ON, 112)
wpantund[139]: State change: "uninitialized" -> "offline"
wpantund[139]: NCP is running "OPENTHREAD/20170716-00967-g677d49b4; POSIX; Oct 18 2018 08:19:20"
wpantund[139]: Driver is running "0.08.00d (/16bc8a0; Sep 28 2018 14:21:43)"
wpantund[139]: HARDWARE ADDRESS IS INVALID, MULTICAST BIT IS SET!
wpantund[139]: Network is not joinable
wpantund[139]: State change: "offline" -> "offline:commissioned"
wpantund[139]: Finished initializing NCP
wpantund[139]: AutoResume is enabled. Trying to resume.
wpantund[139]: NCP is commissioned. Resuming...
wpantund[139]: State change: "offline:commissioned" -> "associating"
   ...fail!
   ...fail!
wpantund[139]: State change: "associating" -> "associated"
wpantund[139]: Node type change: "unknown" -> "leader"
otWeb[155]: border router web started on wpan0
otbr-agent[170]: Starting border router agent on wpan0...
otbr-agent[170]: NCP requesting DBus name otbr.agent.wpan0...
otbr-agent[170]: network name OpenThreadDemo...
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Stop publishing service
otbr-agent[170]: xpanid 4919131752702882611...
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Stop publishing service
otbr-agent[170]: state associated
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Start publishing service
otbr-agent[170]: Avahi client state changed to 101.
otbr-agent[170]: Border router agent started.

OTBR Docker is now running. Leave this terminal window open and running in the background. If you quit the process or close the window, OTBR Docker will go down.

Go to Test Connectivity to continue with the OTBR Docker setup.

Emulated NCP

Use an OpenThread NCP POSIX build for an emulated NCP. This is useful if you want to test border routing with a simulated Thread network on a single machine.

Build the POSIX NCP application

  1. Clone the OpenThread repository:
    cd ~
    git clone https://github.com/openthread/openthread
  2. Bootstrap and build the POSIX application, using the appropriate build switches for Border Router support:
    cd openthread
    ./bootstrap
    make -f examples/Makefile-posix BORDER_AGENT=1 BORDER_ROUTER=1 COMMISSIONER=1 UDP_FORWARD=1
    

Set up a bidirectional data stream

Use the socat command line utility to establish a bidirectional data stream to transfer data between the emulated POSIX NCP and OTBR Docker.

  1. Open a new terminal window to run this process, as it must be left running while OTBR Docker is running.
  2. Install socat:
    sudo apt-get install socat
  3. Start socat:
    socat -d -d pty,raw,echo=0 pty,raw,echo=0
    2018/09/06 09:58:29 socat[242994] N PTY is /dev/pts/2
    2018/09/06 09:58:29 socat[242994] N PTY is /dev/pts/7
    2018/09/06 09:58:29 socat[242994] N starting data transfer loop with FDs [5,5] and [7,7]
    

Make a note of the two serial ports bolded in the output. Use the first one for the emulated POSIX NCP and the second one for OTBR Docker. In the example output above:

  • /dev/pts/2 = Emulated POSIX NCP port
  • /dev/pts/7 = OTBR Docker

Leave this terminal window open and running in the background.

Start the POSIX NCP

  1. Open a new terminal window to run the emulated POSIX NCP, as it must be left running while OTBR Docker is running.
  2. Using the first serial port in the socat output, start the POSIX NCP application. For example, if using /dev/pts/2 from the socat output:
    ~/openthread/output/x86_64-unknown-linux-gnu/bin/ot-ncp-ftd 1 \
        > /dev/pts/2 < /dev/pts/2

There is no output from this command. Leave this terminal window open and running in the background.

Start the OTBR Docker container

In a new terminal window, start OTBR Docker, using the second serial port in the socat output. For example, if using /dev/pts/7 from the socat output:

docker run --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/pts/7:/dev/ttyUSB0 --privileged openthread/otbr

Note that the command is also using the /dev/ttyUSB0 port. This is the default mount point within the Docker container.

Upon success, you should have output similar to this:

WARNING: Localhost DNS setting (--dns=127.0.0.1) may fail in containers.
NCP_PATH: /dev/ttyUSB0
TUN_INTERFACE_NAME: wpan0
NAT64_PREFIX: 64:ff9b::/96
AUTO_PREFIX_ROUTE: true
AUTO_PREFIX_SLAAC: true
Current platform is ubuntu
* Applying /etc/sysctl.d/10-console-messages.conf ...
kernel.printk = 4 4 1 7
* Applying /etc/sysctl.d/10-ipv6-privacy.conf ...
net.ipv6.conf.all.use_tempaddr = 2
net.ipv6.conf.default.use_tempaddr = 2
* Applying /etc/sysctl.d/10-kernel-hardening.conf ...
kernel.kptr_restrict = 1
* Applying /etc/sysctl.d/10-link-restrictions.conf ...
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/10-magic-sysrq.conf ...
kernel.sysrq = 176
* Applying /etc/sysctl.d/10-network-security.conf ...
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
* Applying /etc/sysctl.d/10-ptrace.conf ...
kernel.yama.ptrace_scope = 1
* Applying /etc/sysctl.d/10-zeropage.conf ...
vm.mmap_min_addr = 65536
* Applying /etc/sysctl.d/60-otbr-ip-forward.conf ...
net.ipv6.conf.all.forwarding = 1
net.ipv4.ip_forward = 1
* Applying /etc/sysctl.conf ...
 * Starting userspace NAT64 tayga             [ OK ]
/usr/sbin/service
 * Starting domain name service... bind9      [ OK ]
/usr/sbin/service
 * dbus is not running
 * Starting system message bus dbus           [ OK ]
   ...fail!
wpantund[139]: Starting wpantund 0.08.00d (Sep 28 2018 14:21:43) . . .
wpantund[139]:  BUILD_VERSION = 16bc8a0
wpantund[139]: Configuration file "/etc/wpantund.conf" read.
wpantund[139]: Ready. Using DBUS bus ":1.0"
wpantund[139]: Running as root without dropping privileges!
wpantund[139]: State change: "uninitialized" -> "offline"
wpantund[139]: NCP is running "OPENTHREAD/20170716-00967-g677d49b4; POSIX; Oct 18 2018 08:19:20"
wpantund[139]: Driver is running "0.08.00d (/16bc8a0; Sep 28 2018 14:21:43)"
wpantund[139]: Network is not joinable
wpantund[139]: Resetting interface(s). . .
wpantund[139]: Finished initializing NCP
   ...fail!
   ...fail!
otWeb[155]: border router web started on wpan0
otbr-agent[170]: Starting border router agent on wpan0...
otbr-agent[170]: NCP requesting DBus name otbr.agent.wpan0...
otbr-agent[170]: network name OpenThread...
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Stop publishing service
otbr-agent[170]: xpanid 18359487860614147550...
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Stop publishing service
otbr-agent[170]: state offline
otbr-agent[170]: Handle Thread change
otbr-agent[170]: Stop publishing service
otbr-agent[170]: Border router agent started.

OTBR Docker is now running. Leave this terminal window open and running in the background. If you quit the process or close the window, OTBR Docker will go down.