Skip to content
This repository

Routing Hexabus packets 

myeisha edited this page · 22 revisions

Pages 73

Clone this wiki locally

The traditional HexaBus setup is usually very simplistic. Your network consists of your home router, which is in a network with your PC; both have an IPv6 address. Your PC is equipped with a HexaBus USB stick and is directly connected to the HexaBus network, as are a few other devices (in our example, two plugs). Your PC will give out IPv6 addresses to the plugs, and will be able to communicate with them. Your PC will also be able to receive broadcasts from the plugs.

So the traditional HexaBus setup looks a little bit like this: (TODO: imagify)

|----------|        |-------------|             |----------|
| Internet |========| Home router |=============| Computer |
|----------|        |-------------|  fd00::/64  |----------|
                                                    /
                    |-------------|                /
                    | HexaBus USB |===============/
                    |-------------| fd01:1::abcd/64
                      /     \
                     /       \
           |----------|     |-----------|
           | HexaPlug |     | HexaPlug+ |
           |----------|     |-----------|
           fd01:1::XXXX      fd01:1::YYYY
            fe80::XXXX       fe80::YYYY

On the upper left there is the interet, to which your router is connected. Behind your router lies your home network with one (or more) computers, and behind your computer lies the HexaBus network. Note that your router has nothing to do with the HexaBus network, and that it does not even know that the HexaBus network exists at all.

The Problem™ with this setup

HexaBus broadcasts are actually link-local multicasts. "Multicast" means that every device connected to the same domain can see these packets. Usual domains are a single HexaBus PAN, all device connected to one WiFi access point, or all devices connected to one switch you probably have at home. "Link-local" means that only devices connected to that domain may receive these packets at all, it is explicitly forbidden to forward these packets to other domains.

Which means that you are pretty much stuck with the one computer that controls the HexaBus USB stick. No other computer on the network can, with any reasonable amount of work, talk to the hexadevices and actually receive everything they send. The same thing holds for every device on your WiFi, which is usually connected to your router - you just can't talk to HexaBus devices in a reasonable way.

The solution

Link-local multicast obviously is not the right choice if every device on your network, wired or wireless, should talk to your HexaBus installation. For this reason, link-local multicast has been deprecated in favour of site-local multicast, which is similar, but different. It is still multicast in that every device connected to a given domain may receive such packets, but site-local multicast packets may be forwarded to other domains. In our example: from the HexaBus network on the airwaves to your wired LAN or WiFi on different airwaves. Speaking in terms of the picture drawn above, the new HexaBus network looks more like this: (TODO: imagify as well)

|----------|        |-------------|             |----------|
| Internet |========| Home router |=============| Computer |
|----------|        |-------------|  fd00::/64  |----------|
                          ||         
                          ||
                          ||         
                    |-------------|
                    | HexaBus USB | fd01:1::abcd
                    |-------------|
                       /   \
                    fd00:1::/64
                     /       \
                    /         \
          |----------|       |-----------|
          | HexaPlug |       | HexaPlug+ |
          |----------|       |-----------|
          fd01:1::XXXX        fd01:1::YYYY
           fe80::XXXX         fe80::YYYY

As you can see, the HexaBus USB stick is now attached to your home router. Obviously, the router must now know that the network exists and route packets between the domains it is responsible for. Usually, one of these domains will be your HexaBus network, and another will be your wired LAN and your WiFi.

With the setup pictured above and the new firmware, every device on your LAN or WiFi can talk to the HexaBus devices, and those devices can actually talk back to the LAN. Where previously it wasn't possible to run, say, a logger on any other device than the computer the HexaBus USB stick was attached to, you could now run such a logger on any device connected to your LAN.

Unfortunately, simply plugging the USB stick into your router will not be enough. This guide will explain how to set up a network as pictured above, how the network works, and how to test whether or not it works. Also, some possible sources of problems and solutions to these problems will be given.

Setting up a HexaRouter on OpenWRT

This part of the guide will assume that you have an OpenWRT device with a USB port at your disposal. For simplicity of explanation, it will be assumed that the device has been flashed with a fresh image of OpenWRT Backfire 10.03.1 and has not been touched since. The device used to create this guide is a Buffalo WZR-HP-G300NH, the procedure should be similar for other devices with the same OpenWRT firmware version.

First, you will have to install a number of packages on your router. You can do this from the web interface or from some ssh session on the router. Since console access to the router will be required anyway, this guide will use the console exclusively. Make sure your package lists on the router are up to date by running opkg update on the router. These are the packages you will have to install, if they are not installed yet:

  • mrd6
  • radvd
  • kmod-usb-net-cdc-ether
  • kmod-usb2
  • kmod-usb-acm

To install them, just run

opkg install mrd6 radvd kmod-usb-net-cdc-ether kmod-usb2 kmod-usb-acm

opkg will also install dependencies as required by each of the packages and not overwrite packages that are already installed, so you'll be fine with just this command.

Now that all required packages are installed, you will need to configure some services on the router.

Configuring basic IPv6 on OpenWRT

Remember the second network diagram from above: the network between your router and your PC (and other devices) has the IPV6 prefix fd00::/64, while the HexaBus network has the prefix fd00:1::/64. radvd, the route advertising daemon, is the program that assigns these prefixes to their respective networks, and enables devices on the network to aquire an IPv6 address that is not fe80::something/64, and thus actually useful without jumping hoops.

Devices on the network acquire addresses by a process call stateless address autoconfiguration. Because the router (the device running radvd) has an integral role in this process, it cannot assign itself an address from the prefix it manages. Thus, we have to assign an address to the router by hand before we can do anything else. Assigning an address is simple: open the file /etc/config/network, find the section named lan, and add this line:

option 'ip6addr' 'fd00::abcd/64'

This assigns the address fd00::abcd to the device, and it will happily talk to you lateron. As implied by the name of the section you have just changed, this does nothing for the HexaBus network. In fact, the network is not even known to the router yet, so you will have to add it. Go to the end of the file and add this:

config 'interface' 'hxb'                
        option 'ifname' 'usb0'
        option 'proto' 'static'
        option 'ip6addr' 'fd01:1::abcd/64'

Save the file, close it, and run uci commit and /etc/init.d/network reload. This adds a new network interface to the configuration system, named hxb, for the physical network device usb0. usb0 is the name your HexaBus USB stick will have once you have plugged it into your router. The rest of the section sets the USB stick to have a static network configuration, and assigns to it the IPv6 address fd00::1::abcd from the network fd00:1::/64 as listed in the network diagram above. This concludes the local configuration for interfaces on the router, but interplay between the router and every other device on the network remains to be set up. This is what radvd is actually in charge of.

To configure radvd, open the file /etc/config/radvd. Locate the prefix section for the interface lan and make sure a line like this exists:

list 'prefix' 'fd00::/64'

This will tell radvd to assign the prefix fd00::/64 to the network interface lan, which contains the ethernet and WiFi domains. Devices attached to these domains will from now on automatically have IPv6 addresses in the fd00::64 network.

Also, if you can find such a line in the interface or prefix sections, remove them or change the 1 to a 0 each time:

option ignore 1

Now your usual networks are configured, but the HexaBus network isn't. You will have to add an interface section to tell radvd that the HexaBus network exists at all and that it should take care of it, and a prefix section to assign a network prefix to the HexaBus network, similar to how you assigned a prefix to your local networks. The sections required are these:

config 'interface'
        option 'interface' 'hxb'
        option 'AdvSendAdvert' '1'     # advertise the router's knowledge to the HexaBus network
        option 'ignore' '0'

config 'prefix'
        option 'interface' 'hxb'
        list 'prefix' 'fd01:1::/64'
        option 'AdvOnLink' '1'         # the prefix listed here is used on the network
        option 'AdvAutonomous' '1'     # enable address autoconfiguration
        option 'ignore' '0'

Now save this file, close it, and run uci commit once more. To start radvd now and every time the router is rebooted, run these:

/etc/init.d/radvd enable
/etc/init.d/radvd start

Now wait a little bit, a minute or so. If everything worked out, you should be able to ping6 fd00::abcd, ping6 fd00:1::abcd and the HexaDevices paired to the USB sticks - just replace the fe80 used previously to address them with fd01:1. If you can't ping any device, skip ahead to (TODO: troubleshooting) and return here when everything works.

Configuring multicast routing on OpenWRT

Once a basic IP setup has been put in place, all HexaDevices and all other devices on the network can talk to each other via unicast messages. This is of little utility, though, since HexaDevices mostly act on packets sent by other devices to the whole network. In the basic setup, HexaDevices can receive these broadcast packets from other devices only if they are in the same domain.

First, some background on how all of this actually works. Imagine that you have just unpacked a new HexaDevice, powered it up and paired it to a HexaBus network. Shortly after, the device will send a packet to the network inidicating that it is listening on ff05::114, the multicast address all informational HexaBus packets are sent to. It does this via a special protocol called MLD. In fact, every HexaDevice, and every other device on your network interested in HexaBus packets, does this. These MLD packets are sent to a link-local destination address, as the HexaBus packets originally were. This means that a router attached to two networks, each having devices listening on the address ff05::114, knows which network has listeners for this address.

Now imagine that both networks are large. Large large. A lot of traffic to the address ff05::114 will appear on each network. Further, there are not only two networks, but twenty. Obviously one would not want to forward traffic from one network to all other networks if the other networks are not interested in that traffic at all, or only in a small fraction of it. This is why MLD exists: the router knows which networks has interest in a given multicast address, and since every packet to a given multicast address will be seen by the router, it can selectively forward traffic to networks that are interested.

As with basic IP, we will need a dedicated program to take care of this. The program in this case is called mrd6, the multicast routing daemon for IPv6. To configure mrd6, open the file /etc/mrd6.conf on your OpenWRT device and replace it's contents with this:

interfaces {
    disable eth0;
    disable eth1;

    br-lan pim data-timeout 172800000;
    usb0 pim {
        data-timeout 172800000;
        hello-interval 172800000;
    }
}

pim {
        enable bsr-candidate;
        enable rp-candidate;
}

groups {
        ff05::/64 {
                pim {
                        enable rp_adv;
                }
        }
}

This file will tell mrd6 to not do anything on the interface eth0 and eth1, because one of these is the WAN port connected to the internet, and the other one is an internal interface we need not concern ourselves with. The interfaces to your wired and wireless networks, as well as the USB interface to the HexaBus, are automatically enabled. For all relevant interfaces, it tells mrd to not assume a sending node to be gone unless it hasn't seen any multicast packet for two days, and it instructs mrd to not attempt to find another mrd instance on the Hexabus network. It then tells mrd6 to do some magic (the "pim" sections), and to handle multicast groups matching the ff05:/114 netmask. Since our HexaBus multicast address matches, mrd6 will feel responsible for it and ensure that traffic is forwarded from one network to all other interested networks.

To enable mrd6, run uci commit, /etc/init.d/mrd6 enable and /etc/init.d/mrd6 start.

Wait a little while for the network to settle, a minute or two should suffice. If you now run hexaswitch log on your computer, you should periodically receive packets from both HexaBus networks.

Accessing your HexaBus devices from a Linux machine

If you want to use a Linux box to control your plugs, your machine has to accept the router advertisements sent by your OpenWRT devices. If you have IPv6 forwarding enabled on your machine, it will want to be a router, not listen to one, so you will have to make sure forwarding is disabled - otherwise router advertisements will be silently rejected by your machine. To check whether forwarding is disabled, run

# sysctl -a | grep forwarding
....
net.ipv6.conf.eth0.forwarding = 0

If forwarding is enabled (... = 1), you will have to disable it. To do this, run sysctl net.ipv6.conf.all.forwarding = 0. This disables forwarding on all interfaces. From now on, your machine should accept router advertisements on the network automatically, setting routes and acquiring addresses as required. This may take a while, up to a few minutes.

Setup on a Debian machine

This part of the guide assumes that you are running some recent version of Debian GNU/Linux, and that your machine has two network interfaces - eth0, which connects to the wired network, and usb0, provided by the HexaBus USB stick. We will use the same prefixes and addresses as above, and since the greatest difference between OpenWRT and Debian in this case is the syntax of some configuration files, these differences will be the focus of this section. It will also be assumed that the device you have already configured an OpenWRT router as. Owing to this, we will configure the Debian machine to not be the default router for your network, and to not announce any prefixes from which devices attached to the wired network can take addresses at their liking.

First, you will have to install these packages:

  • radvd
  • mrd6

Basic IPv6 setup

As above, your device will need a static IPv6 address. On Debian, network configuration is handled by the file /etc/network/interfaces. Open this file and add this:

iface eth0 inet6 static
    address fd00::abcd
    netmask 64

auto usb0
allow-hotplug usb0
iface usb0 inet6 static
    address fd01:1::abcd
    netmask 64

This statically assigns the IPv6 address fd00::abcd to eth0, and fd01:1::abcd to usb0.

We will also have to ensure that IPv6 routing is enabled at every reboot. This of course requires that IPv6 be available at all, so the ipv6 module will have to be loaded, first.

echo ipv6 >> /etc/modules
echo net.ipv6.conf.all.forwarding=1 >> /etc/sysctl.conf
sysctl -p

The first line ensures that the ipv6 module is loaded at every reboot, the second enables forwarding, and the third applies the setting now.

Unfortunately, some variants of Debian disable IPv6 by default, notably Raspbian, a Debian variant commonly used on the Raspberry Pi. On Raspbian, you will have to delete the file /etc/modprobe.d/ipv6.conf, on a plain Debian installation from official install media, everything should just work.

To finalize address setup, simply restart the network with /etc/init.d/networking restart.

Radvd remains unconfigured. To configure radvd, create the file /etc/radvd.conf and use this for it's contents:

interface usb0
{
    AdvSendAdvert on;
    prefix fd01:1::/64
    {
            AdvOnLink on;
            AdvAutonomous on;
    };
};

interface eth0
{
    AdvSendAdvert on;
    AdvDefaultLifetime 0;
    route fd01:1::/64
    {
    };
};

The first section configures the HexaBus network manually as OpenWRT did automatically from the configuration options given there. The second section configures radvd to send a route advertisement for fd01:1::/64, which is the HexaBus network, onto the wired network - and nothing else, to not disturb the rest of the network.

Save and close this file and run /etc/init.d/radvd restart. Your Debian machine will now route unicast packets between the wired network and the HexaBus network. You can check this by pinging addresses as listed above in the OpenWRT section.

Accessing your devices from a Linux machine

If you try to oing devices from a Linux machine, you will probably find out that ping6 fails. This happens because Linux, in the default configuration, rejects route advertisements for anything except the default, so the advertisement for fd01:1::/64 will be silently dropped. To accept route advertisements for not only the default route, but also for the route we have just configured, run these as root:

echo net.ipv6.conf.all.accept_ra_rt_info_max_plen=64 >> /etc/sysctl.conf
sysctl -p

This first allows route advertisements for network prefixes up to 64 bits in length, so our HexaBus route will be accepted. The second applies this setting.

Multicast routing on Debian

For Debian, we can almost use the mrd configuration file we created on OpenWRT. Since our Debian machine has no interface eth1, disabling it will be of no use, and since our wired interface is eth0 this time, we may not disable it at all. Simply deleting the two offending lines and replacing "br-lan" with "eth0" yields the configuration for Debian. Simply place this in /etc/mrd6.conf:

interfaces {
    eth0 pim data-timeout 172800000;
    usb0 pim {
        data-timeout 172800000;
        hello-interval 172800000;
    }
}

pim {
        enable bsr-candidate;
        enable rp-candidate;
}

groups {
        ff05::/64 {
                pim {
                        enable rp_adv;
                }
        }
}

To apply this configuration, simply restart mrd6 with /etc/init.d/mrd6 restart. After a few minutes, the network should have stabilized and you should be able to check your setup as in the OpenWRT case above.

Using multiple Hexanetworks

For each network you want to configure, follow the appropriate guide - it does not matter whether you use OpenWRT or Debian to handle any given HexaBus network. Keep in mind that every HexaBus network will need a distinct prefix. The easiest way to ensure this is to assign a distinct number x to every USB stick, and to use fd01:x::/64 for that network. You will also need a distinct static IPv6 address for every routing device. For simplicity, it will be assumed that the routing device handling the HexaBus network fd01:x/64 has the unicast address fd00::x:abcd.

The only thing we have to do now is set up routes between every pair of routing devices.

Static routes on Debian

Add one line to the "eth0 static" static section configured above. Assuming you want to set a route to fd01:3::/64 on a device that handles fd01:1::/64, the line to add would be this:

post-up ip route add fd01:3::/64 via fd00::3:abcd

For other routes, simply change the addresses accordingly. Run /etc/init.d/networking restart to apply the changes.

Static routes on OpenWRT

Add a new section to /etc/config/network. Assuming you want to set a route to fd01:3::/64 on a device that handles fd01:1::/64, the line to add would be this:

config 'route6'
    option 'interface' 'lan'
    option 'target' 'fd01:3::/64'
    option 'gateway' 'fd00:3::abcd'

Run uci commit and /etc/init.d/network restart to apply the changes.

Something went wrong with that request. Please try again.