Thread Border Router using Linux + KW as Host Controlled Device with Serial TAP for DHCPv6-PD

cancel
Showing results for 
Search instead for 
Did you mean: 

Thread Border Router using Linux + KW as Host Controlled Device with Serial TAP for DHCPv6-PD

Thread Border Router using Linux + KW as Host Controlled Device with Serial TAP for DHCPv6-PD

High level description to enable a Linux + KW41Z Border Router. Similar to how it’s shown for the K64 solution in the Kinetis Thread Stack Application Development Guide.

 

  1. Configure the OpenWrt router to assign the IPv6 ULA prefix 2001:2002:2003::/48. On the LAN network, the router distributes addresses from range 2001:2002:2003::/60
  2. Plug an Ethernet cable between the OpenWrt router and the Linux box. Before creating the Thread network, the Linux box has a global address on its eth interface from range 2001:2002:2003::/60. After creating the Thread network, the BR configures on its Serial TAP interface an address from range 2001:2002:2003::/60. On its 6LoWPAN interface, the BR configures an address from range 2001:2002:2003:c::/64. This is achieved with DHCPv6 prefix delegation - the router is requested to assign a new prefix space to be used by the Thread network. The forth segment in the IPv6 range might be 2, 4, 8 or c, depending of the number of DHCP-PD requests made to the router. After 4 attempts, the router will not lease any other prefixes for some time. In order to force that, you'd require to restart the odhcpd deamon in the OpenWrt router with the following command: /etc/init.d/odhcpd restart .
  3. Join the router eligible device, which configures an address in 2001:2002:2003::1/60. We then ping the "Internet" (the LAN interface on the OpenWrt router) and it works.

pastedImage_1.png

“threadtap0” interface must be bridged with an uplink interface connected to an OpenWrt DHCPv6-PD enabled router; it will act identically as the K64F solution.

 

Setup

  • Linux PC (Ubuntu)
  • OpenWrt AP/Router with DHCPv6-PD support (OpenWrt version used in this guide: OpenWrt Chaos Calmer 15.05.1)
    • For reference, hardware used on this guide: TP-Link Model TL-WR741ND 150Mbps Wireless N Router
    • OpenWRT firmware supports multiple hardware available at https://openwrt.org/
  • 1 FRDM-KW41Z (Host Controlled Device, connected to Linux)
  • 1 FRDM-KW41Z (Router Eligible Device or any joiner device)
  • Thread version 1.1.1.20 (from SDK builder at mcuxpresso.nxp.com)

 

Host Controlled Device firmware, make sure the following macros are enabled:

  • THR_SERIAL_TUN_ROUTER                       /source/config.h     -> Enables TAP interface by default (not TUN)
  • THR_SERIAL_TUN_ENABLE_ND_HOST     /app/common/app_serial_tun.h

 

OpenWRT router

  • Configure IPv6 ULA-Prefix:

 _OpenWrt.png

Linux

  • Copy HSDK folder
  • Create 'threadtap0' TAP interface:

…/host_sdk/hsdk/demo#   sudo bash make_tap.sh

  • Use "Thread_Shell" or modify “Thread_KW_Tun” demo to enable the SERIAL_TAP macro

…/host_sdk/hsdk/demo#   nano Thread_KW_Tun.c

#define SERIAL_TAP 0   modify to:  #define SERIAL_TAP  1 

      Note: For demo purposes, the "Thread_Shell" demo is recommended, it already uses TAP by default and allows input commands. If this is not required and only the TAP bridge is to be used, use the Thread_KW_Tun demo.

  • Bridge the interfaces; assuming eno1 is the interface connected directly to OpenWrt:

# brctl addbr br0

# brctl addif br0 eno1

# brctl addif br0 threadtap0

# ifconfig br0 up

  • Note: (Optional) Addresses on the bridged interfaces are lost and need to be reconfigured on the actual bridge. In this example, after bridging eno1 (interface to OpenWrt router), you’d have to run #dhclient br0 to get an IPv4 address on br0 for SSH to the router and/or #dhclient -6 br0 to get an IPv6 address to the br0 interface. There's a note here https://wiki.archlinux.org/index.php/Network_bridge#With_bridge-utils  about this.

 

  • Build C demos

…/host_sdk/hsdk/demo#   make

  • Run Thread_Shell or Thread_KW_Tun demo.

…/host_sdk/hsdk/demo#   sudo ./bin/Thread_Shell /dev/ttyACM0 threadtap0 25

or

…/host_sdk/hsdk/demo#   sudo ./bin/Thread_KW_Tun /dev/ttyACM0 threadtap0

        Note: Try to run the demo without parameters to get some help on the input parameters

 

ifconfig

ifconfig1.png

Thread_Shell demo

thread_shell.png

Thread_KW_Tun demo

thread_kw_tun.png

Joiner FRDM-KW41Z (shell)

  • Join the Thread network
  • Verify IP addresses
  • Ping Eth LAN interface on OpenWrt router to verify “Internet” connectivity 

shell_red.png

Regards,

JC

Labels (3)
Comments

Hello JC,

Thanks for your little Tutorial here! Maybe you could help me with my similar setup. What i want to do, is sending ipv6 packets from my PC, over a OpenWRT Router (GL AR-150), connected to a USB-KW41Z running the border_router example from SDK, to a Node in a Thread Network, which is running as Router Eligable End Device, and back. The K22F on the USB-KW41Z is running the RNDIS software, so that the USB Stick is recognized as ethernet interface.

pastedImage_1.png

If I'm trying to ping the REED's in the Thread Network from my PC it won't work. Here is the ULA from the Node which i want to ping.

2017-10-16_08h18_18.png

And here you can see the config and IPv6 ULA--Prefix from the OPenWRT Router.

2017-10-16_08h24_52.png

If I'm now try to ping the IPv6 address from the REED Thread Node i get the following.

2017-10-16_08h26_34.png

Is there maybe something wrong with ULA-Präfix configuration on the Thread-Node, the USB-KW41Z or the OpenWRT-Router? Or do i have to keep an special order for initializing the devices? If I'm trying to ping the device without the OpenWRT Router between the PC and the USB-KW41Z and stick the USB-KW41Z directly to the PC the ping is successful. It would be awesome if someone could help me with this issue.

Thanks,

Steffen

EDIT: After some testing, with another configuration than above, i found out, that the USB-KW41Z and the Thread Node don't get an IPv6 ULA Präfix from the OpenWRT Router. But that is exactly what should happen right? I added a RaspberryPi between the OpenWRT Router and the USB-KW41Z Border Router, to have better access to the Border Router and start a Thread Network for example. To forward the packets from my WindowsPC to the Thread Node I added a bridge (br0), which is forwarding the packets between the ethernet interface of the Pi and the USB-KW41Z acting as ethernet interface. Here is the setup.

Thread IPv6 packet forwarding.png

What i tried is:

  • First start the OpenWRT Router, and check the connections with a ping between the PC OpenWRT Router and Raspberry Pi (see image above)
  • Attach the USB-KW41Z BorderRouter to the RaspberryPi and started the Thread Network via the PCAPTest script in the USB-KW41Z SDK
  • and finally joined a Thread Node and try to ping it from the PC (see image above)

As you can see in the image above, the  Border Router(fd01::ea2d:d585:f3ab:4dbf:8124) and the Thread Node(fd01::3ead:752b:16f8:b908:96ed) don't have the same IPV6 ULA Präfix(fd0a:972e:6576::/48) than the OpenWRT Router, PC and Raspberry Pi? So i can not access the ThreadNode via the OpenWRT Router ?! But if I'm disconnect the connection between the OpenWRT Router and the Raspberry Pi and bring the br0 on the Pi down, I'm able to ping the Thread Node from the Pi.

Could you tell me what do i have to do, that every member of the network get the same ULA Präfix, so that they can communicate? Is there a documentation for this usecase, because i can't find some?

Thanks a lot!

Steffen

Hello Steffen,

The use case you describe is similar to “11.4 External routing via Ethernet on FRDM-K64F – ND6 host mode and OpenWrt” from the Kinetis Thread Stack Demo Applications User's Guide document but with the USB-KW41Z RNDIS interface on a OpenWRT router. You'll just need to bridge together the LAN and RNDIS interfaces. See below:

Steps on OpenWrt

  1. Install RNDIS driver support – see https://wiki.openwrt.org/doc/howto/usb.tethering
# opkg update
# opkg install kmod-usb-net kmod-usb-net-rndis kmod-usb-net-cdc-ether usbutils udev
  1. Assuming eth2 is created when you plug-in USB-KW41Z
# echo 0 >  /sys/devices/virtual/net/br-lan/bridge/multicast_snooping
# brctl addif br-lan eth2
# ifconfig eth2 up
# brctl show

 

Steps on USB-KW41Z border router project

  1. Enable USBENET_HOST instead of USBENET_ROUTER

.../source/config.h

#if defined(CPU_MKW24D512VHA5) || defined(USB_KW41)
#define USBENET_ROUTER    0       //from 1
#define USBENET_HOST      1       //from 0‍‍‍

Hope this helps.

Regards,

JC

Thanks a lot JC !!! This works fine for me! ;-)

Best Regards,

Steffen

Hello JC,

after getting the connection from my Windows PC to the Thread Node, via the OpenWRT Router and the RaspberryPi i want to use the Thread Commisssioning App from the Play Store on my Android device to add other Thread Nodes to the Network. I switched on the Wifi on the OpenWRT Router and connected the android device, to the  OpenWRT Router. But i cant find a Thread Border Router when opening the Thread App. I also checked that the wlan interface, I am connected

with, is also in the br-lan bridge, which the Border Router is also connected to.

Are there any configurations on the OpenWRT or the Borer Router, I have to do before i could see the Border Router?

Best Regards,

Steffen

Hello Steffen, 

On the remote device, you require to add a route to the Thread network. In Linux, this is done with the following commands, assuming eth0 is the interface connected to the router:

$ sudo sysctl -w net.ipv6.conf.eth0.accept_ra=2
$ sudo sysctl -w net.ipv6.conf.eth0.accept_ra_rt_info_max_plen=64
$ rdisc6 eth0

rdisc6 is available after you install ndisc6 from apt-get.

Then you should see a new route in Linux, something like:

2001:2002:2003::/48 via fe80::e695:6eff:fe40:6e1c dev eth0  proto ra  metric 1024  expires 7082sec
‍‍‍‍‍‍‍

You can confirm the route was added with the following command:

$ip -6 r 
‍‍‍‍‍

See: Linux, IPv6, router advertisements and forwarding – The ongoing struggle 

On a Windows PC, this is done without any additional configuration.

Regards,

JC

Hello JC,

thank you very much! I have the feeling you are almost the only guy at NXP that really could help me with these kind of setup. Makes totaly sense what you are saying! I will try this, and give you a response if this works!

Best Regrads,

Steffen

Hi JC,

after i tried this a several tmies, i find out, that this connection only works once after flashing the BorderRouter and the Thread Nodes and then there is no chance to ping the thread node from the PC again, if I'm doing a reboot/restart on the OpenWRT Router.

Does maybe the OpenWRT router losing the route to the nodes, which i have to reset or is there a timeout/lifetime configuration I have to change? I couldnt find any information that make sense for me, also not in the routing table of the OpenWRT. Or is the problem, that the Thread nodes just store the connection to the OpenWRT via the BorderRouter once, and if I'm restart the OpenWRT he tries to give new adresses to the nodes, which the nodes don't react to? Did you maybe also recognized this behavior?

Best Regards,

Steffen

Hi, 

I'm trying to make this work using SPI interface instead of UART on an RPI running linux.  However /dev/uio0 is not present, although I do have uio modules loaded.  I read that I need to define something more to make the uio0, but I can't find any help or instructions on this.  Any help appreciated.

Thanks

Alex

Any help would be appreciated getting SPI interface working.  

I found the following in the code:

/* SPI Slave Data Available Pin */

#define gSpiSlaveDap_Port_d   gpioPort_B_c

#define gSpiSlaveDap_Pin_d    1

So i'm guessing there is another connection I need to make from the FRDM-KW41Z to the GPIO on the RPI for the DAP signal?  Which pin would this be on the FRDM-KW41Z?

Thanks

Hi Alex, I added a new thread for this question: https://community.nxp.com/message/969722 

- JC

Hello JC,

As Steffen says, it seem you are the only one that can help us :smileyhappy:.

I followed the tutorial step by step, but I'm having some problmes.

In my configurazion I have:

OpenWrt -> Raspberry PI -> FRDM-KW41Z (Host controlled firmware), let's call it Node A -> FRDM-KW41Z (router eligible device), let's call it Node B.

Now, My raspberry PI seem to work properly (I have all the IP with the same ULA setted on the OpenWrt router) but, when I start the Thread_KW_Tun software it seem it cannot forward the packet IPv6 to node B.

Node B is able to connect to the Thread network created by Node A (Join is sucessfull and Led blink stop when connected) but it cannot get the IP informations. Also, in the debug log of Thread_KW_Tun I have "a lot of" TX packet but nothing in RX.

Do you have any suggestion?

Best

Alessio

Edit: I reinstalled the SDK from scratch, flashed a USB-KW41Z with the boarder router firmware. Installed the openwrt image on a RPI3B and connected the USB-KW41Z to the RPI3. Everything works! I can ping the B node from my PC using the RPI3 as a router.

Best

Alessio

Hi Allesio,

I had the same issues a few months back, it took me a while to figure it out.  You need to reconfigure the example host controlled device, recompile and flash.  Here's our notes from our startup script.  If this doesn't work you should check your serial port communications.

# Make sure SERIAL_TAP is set on 1 in Thread_KW_Tun.c
#########################################################
# HOST CONTROLLER DEVICE DEMO ########################
# /nwk_ip/app/common/app_serial-tun.h
# THR_SERIAL_TUN_ENABLE_ND_ROUTER FALSE
# THR_SERIAL_TAP_ROUTER TRUE
##
# /nwk_ip/base/ip_media_if/ip_if_serial_tun.c
# SERIAL_TAP_ROUTER TRUE
#
# /nwk_ip/app/config/app_thread_config.h
#
# config.h
# IP_IP4_ENABLE 0
# DHCP4_CLIENT_ENABLED 0
# THR_SERIAL_TUN_ROUTER 1
# THR_USE_DHCP6_CLIENT TRUE

Hope this helps

Alex

Hi Alex,

Thanks for your suggestions! I will try with the host controlled device in the near future, menawhile the rndis_bridge firmware solved my problems.

I'm quite sure that I didn't had a look at nwk_ip/app/config/app_thread_config.h file, maybe there was some wrong settings in there :smileyhappy:

Best

Alessio

Hi JC,

I have the same configuration as Alessio (Router, Raspberry-Pi, FRDM-KW41Z as Host Controlled Device and a FRDM-KW41Z as a Router Elegible Device) but instead using TAP interface I used TUN interface following the "Kinetis FSCI Host Application Programing interface" guide, everething works fine, I am able to ping the Thread node from my Raspberry-Pi, and I used the CoAPThon python library to communicate to nodes over coap and it works perfectly. At this point as i am using TUN interface i am not able to bridge my raspberry pi to the router, so the computers connected to the router in the same network cannot ping the Thread nodes. For this reason i am looking for changing TUN interface to TAP interface in order to bridge the router (connected to ethernet port eth0 of my Raspberry-PI) and be able to ping Thread Nodes from the computers connected on the router network. However, in your tutorial you said you enabled TAP interface by this command:

  • Create fslthr0 TAP interface:

…/host_sdk/hsdk/demo#   sudo bash make_tap.sh

But in my case i only have in this directory a make_tun.sh file. Where can i find the TAP file or what commands do i suposse to do in order to etablish a TAP interface and bridge to eth0 port in my Raspberry-PI?

Thanks

Diego C.

Hi Diego,

The latest SDK can be dowloaded from mcuxpresso.com, you need to select the FRDM-KW41Z board and include the wireless stacks.

On the latest version, the VTUN is configured automatically as TAP and is much straight fwd, I need to update this thread with that info.

Hi JC,

Thanks for the quick reply! I would appreciate a new updated tutorial on how to acces from the cloud to the Thread Network with the latest SDK. By the way, I have some questions related to an application that I want to develope.

  1. Could I access to the cloud with a normal TP-Link router instead of using an Open WRT Router?
  2. Is there a way to know from my Raspberry-Pi (connected to FRDM-KW41Z HCD), using Coap, the IPv6 of a node that has just joined my Thread Network? 
  3. Because in my case I am using a FRDM-KW41Z Host Controlled Device and I am tapping the sudo ./bin/Thread_KW_Tun /dev/ttyACM0 fslthr0 command, the Host Controlled Device is always the Leader of my Thread Network. Could I create the network from another node (being the leader) and later join the Thread Network with the Host Controlled Device maintaining the TUN/TAP connectivity from the Thread network to the Raspberry-Pi?

Best,

Diego Comin

Hi Diego,

Refer to "Chapter 6.3 - Userspace module in TAP mode and global addressing scheme" from doc/wireless/common/Kinetis FSCI Host Application Programming Interface.pdf document. It includes instructions to enable the TAP interface and run C example.

1) You can use any router as long as it has DHCPv6-PD and IPv6-ND support.

2) See the Thread_Shell demo, it demonstrates management message (getnodesip) that queries for the IPv6 nodes in the Thread network.

3) Yes, you can start the device as a Joiner, see Thread_Shell demo, it allows you to create or join a network while maintaining the TAP interface enabled to communicate to external interface.

Hi JC,

As I said before I used TUN interface following the "Kinetis FSCI Host Application Programing interface" guide, with the 1.0.2 Connectivity Software running projects on Kinetis Design Studio and everything in TUN interface worked well. Now to test the new SDKs includying TAP interface, I have downloaded the new SDK for MCU Expresso IDE, I tested TAP interface without any router, just to test the connection between Raspi with FRDM-KW41Z (as HCD) and an active router but in this case the node dont get a ULA IPv6 to test connection.

I also made the TUN interface (as I had with the 1.0.2 Connectivity Software) with the new SDK, and the node still don't get the ULA IPv6 address. I attach the command windows from my Pi:

pastedImage_1.png

pastedImage_2.png

And I attach the terminal of the Active Router node, where I can not find the ULA address:

pastedImage_3.png

What could be happening? I only moved to the new SDK.

Best,

Diego C.

Hi Diego,

The TAP interface is now defined by default when enabling THR_SERIAL_TUN.

As seen in this post, the TAP Interface is intended to be used in a topology where a DHCPv6-PD provides a Prefix to the Border Router interface and the devices within the Thread network. If you want to use TAP but keep using static Unique Local Address (ULA), you need to disable THR_SERIAL_TUN_USE_DHCP6_ADDR. As the comment in the macro states: /* When DHCPv6-PD is turned off, local static configuration is used, even in TAP mode */

If you want to enable the TUN interface, you need to disable THR_SERIAL_TUN_ENABLE_ND_HOST and THR_SERIAL_TUN_USE_DHCP6_ADDR in app_serial_tun.h

Hope this helps,

JC

Hi JC,

I have new issues to my development (Router, Raspberry-Pi, FRDM-KW41Z as Host Controlled Device and a FRDM-KW41Z as a Router Elegible Device). Because in my company there is not Internet Ipv6 Service I did not purchase a DHCPv6-PD and IPv6-ND router to link the nodes to ISP. So I can only access the nodes through my Raspberry PI by ipv6, and then mi Raspi send communication to the Internet trough wifi iPv4 connection. In my Raspberry I can ping individually my nodes though their ipv6 but i can not ping the multicast group ff02::1, I can only ping the multicast group if a put %threadtap0 (my TAP interface) just after the multicast address ff02::1 (ping6 ff02::1%threadtap0). The problem is that I am using a python library for Coap communications (CoAPthon) that do not allow to put the %threadtap0 interface, so I can not send multicast messages to my nodes.

Do you know how to ping the ipv6 multicast address (ff02::1) without specifying my interface (%threadtap0) in RaspberryPi?

Do you know some Coap libraries that allow to include the interface when specifying an ipv6 multicast address?

We have been stucked in my company since we do not solve the multicast problem.

Regards,

Diego Comin

Hi Diego,

Our dev team used txThings with some changes for multicast as described here but we didn't test using link local scope addresses (ff02::1). Hence, we didn't require to set the outgoing interface. Could you try to bind the socket on the interface (as shown here) and see if that helps?

Hi JC,

I tried to bind the socket on the interface as you pointed here but neither using Coapthon and Txthings it works.... Maybe there is no way to perform multicast with link local scope address? Because my company does not have ipv6 ISP, the link local address is the unique address which I can communicate to the nodes through the Host Controlled Device + Raspberry Pi. 

Could you suggest me other options to multicast my nodes through my Border Router architecture? 

Regards,

Diego C.

Version history
Revision #:
1 of 1
Last update:
‎05-03-2017 08:39 AM
Updated by: