Routing tests

myeisha edited this page Nov 7, 2012 · 5 revisions
Clone this wiki locally

Prerequisites

Information on this page right now only applies to the branch bs-routing.

All routing tests are performed on a Linux machine with networt namespaces. Namespaces are used to simulate physically different machine with a single computer. For all tests, you should have at least two Hexabus USB sticks, named usb0 and usb1 here. They must have different PAN IDs. If they don not have different PAN IDs, change that. Configuration files for radvd and mrd are supplied in hostsoftware/multicast-tests.

The plugs used in these tests will occasionally need state machines, this will be described in each test as necessary. Many tests are only concerned with packet sending and reception, whether a packet has been sent can be verified with your favorite packet sniffer, whether a packet has been received is easily verified by compiling the plug firmware with udp handler debug and just watching the serial console of the plug in question.

Opening network namespaces

You will often be asked to enter a new network namespace with a specific set of devices. Since interacting with the hexaplugs is not easily automatable, it has been decided to not automate much at all for the moment. Thus, just follow these instructions every time you are asked to open a network namespace.

# first, open a new terminal and create a new network namespace
# you will need root privileges for this, add sudo as required
unshare -n $SHELL
# enable routing in the namespace
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# get the PID of the namespace, you will need this later
echo $$

# now change to your original shell
# for each device $dev that should be in the network namespace, do this
# <PID> is the pid of the network namespace you create
ip link set dev $dev netns $PID

Bridging Hexabus networks on a computer

Create a network namespace with usb0 and usb1 in it. Make sure to use plugs that send packets on button press.

# create a bridge and add both devices
brctl addbr br0
brctl addif br0 usb0
brctl addif br0 usb1
ip link set br0 up
ip link set usb0 up
ip link set usb1 up

# add IPv6 addresses to the bridge and start radvd
ip address add fd00::1/64 dev br0
radvd -d 5 -C bridge-direct.radvd &
# reboot your plugs here
# play around with the plug buttons, network sniffer, hexaswitch, ...

# when done, stop radvd and delete the bridge
ip link set dev br0 down
brctl delbr br0

It turns out that all packets sent via the bridge are sent with the primary MAC address of the bridge, not with the MAC address of the device via which the packet will actually be transmitted. This makes bridging useful only for networks that do not need unicast control packets. Sending unicast packets to one of the attached Hexabus networks will work, but all other unicast packets will be sent to that same network as well - regardless of whether they were intended to be sent to that network or not. Because this drastically limits the usefulness of Hexabus, setups with more than one network per bridge are not considered viable.

Routing Hexabus networks on a computer

Create a network namespace with usb0 and usb1 in it. Make sure to use plugs that send packets on button press.

# interface config
ip link set dev usb0 up
ip address add fd00::1/64 dev usb0
ip link set dev usb1 up
ip address add fd01::1/64 dev usb1

# stats radvd and mrd
radvd -d 5 -C route.radvd &
mrd6 -f route.mrd &

# reboot plugs, play around, ...

# when done, stop deamons and clean up interfaces
ip address delete fd00::1/64 dev usb0
ip address delete fd01::1/64 dev usb1

Routing two hexabus networks into a switch

Create a network namespace for usb0, and a separate namespace for usb1. In this test, we set explicit routes to the appropriate targets for simplicity. Larger installations would want to install a route advertisement for the specific hexabus network prefixes on the hexarouting devices, and, to connect them among each other, some form of dynamic routing. OSPF or similar should do fine. It can be done with radvd alone, but radvd and the kernel produce some "interesting" artifacts in the process. Expect to see routes from the device to itself via itself if you go with radvd.

In this configuration, controlling all plugs at once (using multicast) is not possible from the routing namespaces for every configuration checked here. This might be a limitation of mrd6; further tests in this direction might be needed. Since hexarouting devices are most likely to be small, embedded devices with no other purpose, and controlling all instances at once is seldomly useful, investigations are postponed for time being.

# create a virtual ethernet device pair. move veth0 to usb0, veth1 to usb1
# this pair of devices is connected by the kernel, via these devices we simulate the switch
ip link add type veth

# interface config for usb0
ip link set dev usb0 up
ip address add fd00::1/64 dev usb0
ip link set veth0 up
ip address add fd10::1/64 dev veth0
# set route to usb1
ip route add fd01::/64 via fd10::2

# interface config for usb1
ip link set dev usb1 up
ip address add fd01::1/64 dev usb1
ip link set veth1 up
ip address add fd10::2/64 dev veth1
# set route to usb0
ip route add fd00::/64 via fd10::1

# in both namespaces, start mrd and radvd
radvd -p$(mktemp -u) -d 5 -C route.radvd &
mrd6 -f route.mrd &

# reboot plugs, play around, ...

# when done, stop deamons and clean up interfaces
ip address delete fd00::1/64 dev usb0
ip address delete fd01::1/64 dev usb1