Table of Contents

About

Mesh networks have the advantage that nodes can be distributed over a wide area such that clients are able to use any node in its vicinity to connect to the wireless network thereby extending the range of the whole wireless network very conveniently and without the use of additional hardware.

The following tutorial uses very cheap aftermarket USB WiFi dongles in order to create a distributed mesh network between several machines with the hopes of the extending the range for an IoT device environment. The network will be setup on Debian, such that both generic Linux commands shall be used but also setup files that should be compatible with Debian and Debian-like distributions.

Hardware

The hardware used is some cheap UDB dongle based on the RealTek RTL8192CU chipset that does have support for mesh. In order to verify that the dongle truly has support for mesh, it is connected to the Linux machine and then the following command is executed:

iw phy | grep -i "Supported interface modes" -A 10

that leads to the following relevant output:

        Supported interface modes:
                 * IBSS
                 * managed
                 * AP
                 * AP/VLAN
                 * monitor
                 * mesh point
                 * P2P-client
                 * P2P-GO

The indicator to look for here is mesh point that is indeed listed among the supported interface modes.

Udev

More than likely the Linux machine uses the new naming scheme and picked some obnoxious "unique" name for the new wireless dongle (ie: wlx01da5c147781) and because using this "unique name" would be absurd, udev is used to rename the device to something sensible.

udevadm is invoked to list a set of attributes for the wireless device:

udevadm info --attribute-walk /sys/class/net/wlx01da5c147781

in order to generate the following rule:

SUBSYSTEM=="net", ACTION=="add", ATTRS{idProduct}=="8176", ATTRS{idVendor}=="0bda", NAME="mesh0"

that will be added to the file /etc/udev/rules.d/77-mesh.rules

One of the cool things about using an udev rule is that the match is performed against the product ID and product vendor meaning that the USB dongles can be hot-swapped between machines and the mesh network will still work without having to change the hardware identification characteristics.

Without rebooting, the udev rules are reloaded using the following command:

udevadm trigger --attr-match=subsystem=net --action="add"

and, as expected, the interface is renamed to mesh0:

mesh0     IEEE 802.11  ESSID:off/any
          Mode:Managed  Access Point: Not-Associated   Tx-Power=0 dBm
          Retry short limit:7   RTS thr=2347 B   Fragment thr:off
          Encryption key:off
          Power Management:on

Similarly, unplugging and plugging back the dongle generates the mesh0 interface via udev.

Configuring Interfaces Automatically

Using Debian /etc/network/interfaces.d/ the following can be configured automatically on startup:

In order to accomplish that, a file /etc/network/interfaces.d/mesh0 is created with the following content:

allow-hotplug mesh0
iface mesh0 inet manual
        mtu 1560
        pre-up /usr/sbin/iw mesh0 set type mp
        post-up /usr/sbin/iw mesh0 mesh join NETWORK
        post-up /usr/sbin/batctl if add mesh0

where:

The mesh interface mesh0 can now be controlled using ifup mesh0 and ifdown mesh0 in order to bring the mesh0 interface up, respectively take the mesh0 interface down.

Upon having configured a few mesh points, the batctl command can be used to list the known mesh neighbours. For instance, by issuing the following command:

batctl n

some output along the following is to be expected:

[B.A.T.M.A.N. adv 2022.3, MainIF/MAC: mesh0/c2:56:03:30:5d:e9 (bat0/ae:10:18:39:34:91 BATMAN_IV)]
IF             Neighbor              last-seen
        mesh0     8e:af:85:43:ac:e6    0.424s
        mesh0     8a:98:2a:ab:d9:25    0.244s

where:

and the rest is a list of sensed mesh interfaces that have joined the configured network.

Intermission

Right now the mesh network is entirely set up from the point of view of mesh networks and there is nothing else to do.

That might seem counter-intuitive given that the mesh0 interfaces that have been set up do not have any addresses configured. However, the mesh network works on the OSI network layer 2 such that any scheme can be chosen for setting up the interface with routable addresses.

Distributing Addresses

The default case is to just use static IP addresses for all the mesh nodes, which is not a bad decision in case one would want mesh nodes to be distinguishable. Otherwise, a DHCP server can be set up in order to dish out addresses out of the mesh0 interface on one single node but that might introduce a single point of failure in case the node distributing addresses would go down.

Another alternative is avahi-autoipd which is part of the zeroconf stack and will distribute IP addresses dynamically from the network 169.254.0.0/16 to all mesh nodes. Installing avahi-autopipd can be accomplished on Debian via aptitude install avahi-autoipd, after which the /etc/network/interfaces.d/mesh0 file would have to be modified in order to start avahi-autoipd whenever the interface is brought up.

Here is an example of the modified /etc/network/interfaces.d/mesh0:

allow-hotplug mesh0
iface mesh0 inet manual
        mtu 1560
        pre-up /usr/sbin/iw mesh0 set type mp
        post-up /usr/sbin/iw mesh0 mesh join internal
        post-up /usr/sbin/batctl if add mesh0
        post-up /usr/sbin/avahi-autoipd -s -D --force-bind mesh0
        pre-down /usr/sbin/avahi-autoipd -k mesh0