Setting up an Ad-Hoc Mesh Network with Raspberry Pi 3B+ using BATMAN-Adv

Setting up an Ad-Hoc Mesh Network with Raspberry Pi 3B+ using BATMAN-Adv

Image for postPhoto from

An ad-hoc mesh network implies a leader-less topology, in which all of the belonging nodes cooperate on the distribution of the data, which themselves feed into the network at the first place. This is the minimum theoretical requirement for any ad-hoc mesh network. From now on, I will follow a practical walk-through that will end up with a, hopefully, working mesh network. Below are the specific tools.


  • Ubuntu 16.04 Mate OS
  • BATMAN-Adv
  • Raspberry Pi 3B+


Since I have been working on ad-hoc mesh network for a while, I have encountered different notions on mesh networks. In order to eliminate any confusion, I would like to clarify the exact setting that I work with. A true ad-hoc mesh network should have no master/gateway/DNS server and any similar component that implies a leader. In that case, the network depends on some subset of the nodes, which ends up in a single point of failure problem. Obviously this is not desirable especially in a mobile network, where any two node should be able to communicate without depending on a third.


batman-adv module is implemented as the part of official Linux kernel tree since 2.6.38. Therefore you don?t need to install that from scratch. However its userspace driver, batctl, and its user daemon alfred need to be installed. For that execute following snippet:

sudo apt install libnl-3-dev libnl-genl-3-devgit clone batctlsudo make installsudo apt-get install alfred

Above snippet finishes the prerequisites installation. Since we are using Raspberry Pi 3B+, the onboard Wi-Fi module supports IBSS(Ad-Hoc) interface mode, therefore an external Wi-Fi dongle is not required.

Network Setup

The network setup is realized by a Bash script that is executed at the boot via /etc/rc.local. First we need to disable wpa_supplicant, since it does not allow to freely configure network interfaces. Execute:

bash service wpa_supplicant stop sudo systemctl mask wpa_supplicant.service sudo update-rc.d dhcpcd disable

After this command, both dhcpcd and wpa_supplicant services will cease to run. This is needed, since these services manipulate the ad-hoc mesh network configurations that effectively breaks the network. An advanced setup should compromise with these services, but this tutorial will not cover such a setup. In addition I also disable hostapd just to be sure, but you may regressively try to enable above services with the necessary configurations after having a working base. Following snippet sets up a password-free ad-hoc connection on each node:

ip link set <if> down #e.g. <if> = wlan0iw <if> set type ibssifconfig <if> mtu 1532 # This is necessary for batman-adviwconfig <if> channel 3ip link set <if> upiw <if> ibss join <ssid> 2432 # e.g. <ssid> = my-mesh-network#Frequency is 2.432. 0.0x should match with channel.

The last command can be extended with key <key> for a WEP security, but since it is known to be insecure I just don?t add in this prototype. A true setup requires WPA2 security. Then follows the batman configuration:

modprobe batman-advbatctl if add <if># e.g. <if> = wlan0ip link set up dev <if>ip link set up dev bat0ifconfig bat0 # Can be any other valid IP.

After these commands, check your connection via:

$ sudo iwconfigeth0 no wireless extensions.wlan0 IEEE 802.11 ESSID:”my-mesh-network” Mode:Ad-Hoc Frequency:2.432 GHz Cell: 72:A7:18:B3:42:C3 Tx-Power=31 dBm Retry short limit:7 RTS thr:off Fragment thr:off Encryption key:off Power Management:on lo no wireless extensions.bat0 no wireless extensions.

The important part of above output is essid and cell value. They should be same on all devices. If you see a similar outcome, then the network has been setup. You can also execute sudo batctl o and sudo batctl n to see that all the Raspberry Pis are devised as BATMAN nodes. Lastly, I add alfred and batadv-vis commands to enable the mesh network be visually inspected.

sleep 3alfred -i bat0 -m -p 1 &sleep 10batadv-vis -i bat0 -s &

Now in any node, executing batadv-vis outputs a graphviz compatible digraph. Visualizing it is pretty straightforward as explained in here.

Image for postOutput from the script, MAC addresses are edited.

At the end, combine related snippets above in one bash script, such as . Make it executable with chmod u+x and finally add its absolute path into /etc/rc.local before return 0 line.


Troubleshooting network problems might be the most difficult and most subtle task I have ever encountered. Definitely kernel logs say ?something?, but they are mostly far-fetched and most of the time one cannot find any reasonable explanation. My problem was that the devices properly join to the network at the boot, but in 5 minutes they start to drop from it one by one. In order to solve that:

  • Enable multicasting by adding net.ipv4.icmp_echo_ignore_broadcasts=0 in /etc/sysctl.conf . Then execute sudo service procps restart for the changes to take effect immediately.
  • Disable wi-fi power saving by assigning 1 to both WIFI_PWR_ON_AC and WIFI_PWR_ON_BAT variables under /etc/default/tlp.


There are other alternatives on mesh networking. Below is a nonexhaustive list:

  • babeld
  • Toronto Mesh


In this post, I have tried to explain the steps needed to set up an ad-hoc mesh network, which works in my case. Since I?m not a networking expert, there might be problems or redundant steps. If you find any gap to fill or just want to recommend a better method on any aspect, you are most welcomed ?


  • How to Setup a Raspberry Pi Ad-Hoc Network using BATMAN-ADV on Raspbian Stretch Lite

No Responses

Write a response