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.
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.
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.
Using Debian /etc/network/interfaces.d/
the following can be configured automatically on startup:
mesh0
interface to mesh point,mesh9
interface to some named mesh network,batctl
to add the interface to the mesh
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:
NETWORK
is a chosen name for the mesh network
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:
mesh0/c2:56:03:30:5d:e9
is the local interface with is configured MAC addressand the rest is a list of sensed mesh interfaces that have joined the configured network.
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.
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