This post is about my personal experience of manually setting up basic IEEE 802.11s mesh systems without any additional add-on packages. This all started with the need to replace two Powerline LANs in locations where it wasn't feasible to run CAT cables. After several attempts of setting up mesh networks, including using a shell script daemon that was supposed to set everything up automatically, I decided to start over from scratch. This documentation is the result of my work and my hope is that it will be useful to others.
Introduction
Setting up a small mesh can be a good solution if you want to place remote Access Points (APs) throughout an area and running cables between them is not a viable option. In a mesh, your APs communicate with each other using their own wireless channel instead of cabling. Properly configured, they will automatically find each other and work out the best way to send information back and forth between stations.
As a disclaimer, I don't consider myself an expert on meshes, programming, OpenWrt, or the Linux Kernel. With that disclosure, this is how I set up two small personal OpenWrt IEEE 802.11s mesh systems using research by consulting the standard, the OpenWrt source code, and a lot of trial and error. In the end, I found that my two OpenWrt mesh systems, one with three stations and the other with five stations, run quite reliably 24/7 without the need for any add-on packages or automatic setup programs.
To start with some terminology, in IEEE 802.11s mesh networking, there are several types of stations, each of which plays a different role within the mesh network (known in the IEEE 802.11s standard as a MBSS - a Mesh Basic Service Set that forms a self-contained network of mesh stations). Here are the main types of stations that often make up a small to medium-sized MBSS.
-
Mesh Point (MP): Mesh Points form the backbone of the mesh network by relaying data and participating in path selection. A mesh point is a basic station in the mesh network that is capable of establishing wireless mesh links with other MPs. MPs can relay frames to other MPs and participate in the mesh path selection protocol, thereby helping to create and maintain the mesh network topology.
-
Mesh Portal (MPP): A mesh portal is a specialized station that connects the mesh network to other types of networks, such as Ethernet or another 802.11 network. In OpenWrt, MPPs serve as gateways, allowing data to flow between the mesh network and external networks. This is crucial for providing Internet access or integrating the mesh network with other network infrastructures.
-
Mesh Access Point (MAP): A mesh access point is similar to a Mesh Point (MP) but combines both mesh networking capabilities and traditional access point services. It can connect regular Wi-Fi clients (stations) to the mesh network, effectively acting as a bridge between client devices and the mesh infrastructure. MAPs are useful for extending network coverage and integrating client devices into the mesh.
Small personal OpenWrt IEEE 802.11s mesh networks will typically only involve a single Mesh Portal (MPP), some Mesh Access Points (MAPs), and possibly some Mesh Points (MPs).
I need to clear up a misunderstanding regarding the configuration of OpenWrt IEEE 802.11s parameters. Previous versions of OpenWrt IEEE 802.11s may have required some mesh parameters to be configured once the mesh was up and running, using iw
commands. While this may have been true a few years ago, it is not the case now with current versions of OpenWrt. All mesh parameters (about 30) have default values at startup, and the few that need to be changed can be defined in the /etc/config/wireless
file. More details on this later in this article.
Preliminary Planning
Locating your mesh stations is a key factor in the viability of your MBSS. I've found it to be an iterative process and here's how I started. From the location of your main router, which will most likely be your mesh portal and gateway, consider the areas that need to be covered and anticipate the obstacles and distances that you will need to cover. I then used my phone and an application such as the open source WiFiAnalyzer to do a preliminary site survey.
Unused Channels are the best to select for your mesh if possible. A site scan using a phone Wifi analyzer application will help you find either an unused channel or one that hopefully won't provide too much interference which will harm your mesh performance. 2GHz channels, while slower, provide the best distances and are better at penetration through obstacles like walls and floors compared to higher 5GHz bands. Unfortunately, the 2.4GHz band is often crowded with many neighboring Wi-Fi networks and other devices leading to interference and lower performance.
The 5GHz band is generally less crowded than the 2.4GHz band, resulting in less interference and higher performance, and the 5GHz band supports higher data rates and wider channels (20/40/80MHz), which can significantly improve performance. Unfortunately, some 5GHz channels require Dynamic Frequency Selection (DFS) to avoid interference with radar and other systems, which can cause mesh disruption. For example, in the UK, channels 52, 56, 60 and 64 of the U-NII-2A band and channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136 and 140 of the U-NII-2C band require DFS, so avoid these channels if possible. Check with your country's regulatory agency to see which DFS bands apply in your country or you can use the Linux Kernel Regulatory Database which I believe is the source of OpenWrt's settings for various countries. Avoid using any DFS channels in your country for an IEEE 802.11s mesh unless you are sure that there are no other devices in your area that use these frequencies, such as radar. For DFS frequencies, it is mandatory that routers automatically switch channels if they detect that the band is being used by something else. This will disrupt your mesh and probably render it inoperable unless the individual mesh stations all switch to the same new band at the same time (unlikely), requiring manual intervention. Using non-DFS bands results in a more limited selection of bands, so choose your best ones and adjust the bandwidth to avoid interference from adjacent bands.
Once you've chosen a primary location for the mesh portal and the channel, set up the router temporarily as an AP using these settings. You can then use your phone as a WiFi signal strength meter to find good locations for your first level of one-hop mesh stations. I have found signal strengths of no less than -70 dBm to be a good balance between reasonable signal strength and maximum distance between routers. This will get you started with your direct neighbors of your root station. If you are planning upon a larger mesh, you will need to repeat the process for your first level multi-hop stations as you locate your mesh stations throughout your location.
Router Setup
I began with setting up my mesh OpenWrt routers in a way that is described by OneMarkFifty in this YouTube video:
One item that has changed since this video was made is that the default package that provides the IEEE 802.1x/WPA Authenticator and Supplicant is wpad-basic-mbedtls
, not wpad-basic-openssl
. To be consistent with the current releases of OpenWrt, you should install the mbed TLS package, wpad-mesh-mbedtls
in place of the wpad-mesh-openssl
package shown in the video.
While I found the basics in his approach to be well explained, but I did discover it is incomplete. I'll start with the three most important. The first item is how IEEE 802.11s stations communicate with each other. The OSI (Open Systems Interconnection) model has seven layers of protocols, and IEEE 802.11s operates at Level 2 (Layer 2), the Data Link Layer. Layer 2 uses Media Access Control (MAC) addresses to identify stations, rather than IP addresses (Level 3). In the context of IEEE 802.11s, communication links between stations using MAC addresses are called 'paths' rather than 'routes'.
The first version of my mesh systems used all TP-Link C7 routers. I didn't realise that all these routers were using the same MAC address for the IEEE 802.11s mesh channel. That's not a great idea if the 802.11s firmware is trying to use MAC addresses to select paths to different stations. This is easily fixed by setting the MAC address in LUCI for mesh channel to be either random or a specific address under Advanced Options. You can also define the MAC address in the /etc/config/wireless file under the mesh device.
config wifi-iface <interface_name>'
....
option macaddr 'xx:xx:xx:xx:xx:xx'
....
I chose to use a fixed MAC address and picked the first two digits to easily identify individual routers as this made it easier for me to identify the mesh station by MAC address. To make sure you are using a valid MAC address, I suggest a MAC generator site like this one.
I also decided to change the Network Interface Device br-lan
to this same address. Here's my reasoning: in OpenWrt's implementation of IEEE 802.11s, when a mesh station needs to contact another station using an IP address, it relies on the Address Resolution Protocol (ARP) to map the IP address to a MAC address. The ARP maps your mesh routers use is the MAC address of the br-lan
for each router, not the MAC address that is assigned to the mesh channel. By making the OSI layer-2 and layer-3 MAC addresses, of the mesh channel and the br-lan
channel the same, I am hoping to resolve what I see as an issue but I fully accept, more research is required on this subject.
You can set the MAC address of br-lan
either by LuCI in the Interfaces, Device tab, br-lan
, Configure button. "The General devices options' has a box for entering a MAC address.
You can also set it via the /etc/config/network
file.
config device
option name 'br-lan'
option type 'bridge'
list ports '<ports assigned>'
option macaddr 'xx:xx:xx:xx:xx:xx'
Remember, that whenever you are editing the /etc/config/wireless
file or the /etc/config/network
file, you will need to either reboot your router or apply this command for the networking service for the changes to be applied.
# /etc/init.d/network restart
Note: If you are planning upon using B.A.T.M.A.N. Advanced (batman-adv), you can stop now as B.A.T.M.A.N Advanced does not require an IEEE 802.11s mesh network to have root nodes or gateways defined within an IEEE 802.11s MBSS.
The next significant advancement was the realisation of the importance of the mesh_hwmp_rootmode
setting. This setting defines which station within the mesh network acts as the central point for path determination and traffic management. The default setting is that all the mesh stations are peers with no root station in the MBSS. The role of a root station is to interact with other mesh stations primarily for proactive routing and path management processes. Without a root station, the network relies on reactive routing mechanisms rather than proactive ones, resulting in a viable but poorer performing MBSS.
The mesh_hwmp_rootmode
setting is not available in LUCI but can be set in the /etc/config/wireless file
. The setting is an integer with possible values of 0 (default), 2, 3, or 4. The following is a brief definition of the mesh_hwmp_rootmode
possible settings:
- Mode
0
(not Root): This is default mode OpenWrt and ensures that the mesh point does not engage in any root-specific activities. Mode0
stations respond to root stations PREQs (Path Requests) with PREPs, (Path Responses). A Mode0
station will store paths derived from PREQ it has received and PREPs from PREQs it has sent out. - Mode
2
(Root with PREQ announcements only): This mode informs other mesh points of its presence as a root station managing paths. It does this by sending out PREQs (Path Requests) but does not respond to PREQs with PREPs from other stations. - Mode
3
(Root with PREQ announcements and responds to other PREQs with PREPs): This mode periodically sending PREQ messages, to determine mesh station paths. It will also respond to PREQs from other stations with PREPs. - Mode
4
(Root Proactive RANN announcements in addition to PREQ announcements PREP responses): A RANN message includes information such as the root station's address, a sequence number (to prevent routing loops and ensure the freshness of the information), and other metrics that can help in routing decisions.
The absence of a root station means that there's no central entity that proactively maintains routes; individual stations can still maintain routes to their neighbours and to any station they've recently communicated with. Stations rely on what is known as reactive routing. Stations only initiate route discovery when they need to communicate with another station, which can cause additional delays in sending or receiving information. Defining a root station allows for proactive routing, where a central entity proactively maintains routes between stations. The different modes above define the mechanisms used in proactive routing.
A small personal mesh typically involves multiple Mesh Access Points (MAPs) and a single Mesh Portal (MPP). For the Mesh Access Points (MAPs) The value should stay as the default mesh_hwmp_rootmode = 0
and for Mesh Portal (MPP), I suggest a value of mesh_hwmp_rootmode = 3
or mesh_hwmp_rootmode = 4
As the default value of mesh_hwmp_rootmode is 0
, nothing needs to be done in the /etc/config/wireless file for each of the Mesh Access Points (MAPs), If you chose to set specifically, you can add this to your /etc/config/wireless file.
config wifi-iface <interface_name>'
....
option mesh_hwmp_rootmode '0'
....
For your Mesh Portal (MPP), I suggest setting the mesh_hwmp_rootmode to 3
, in the /etc/config/wireless
file as I think this is sufficient for a small mesh and puts less load on a consumer router. Others might suggest that this should be set to 4
. Both worked for me, but I preferred 3
. I won't argue the point; try either one. The important thing is to make sure that your portal is identified as the root station and is proactively managing the paths.
config wifi-iface <interface_name>
....
option mesh_hwmp_rootmode '3'
....
There is one more setting that needs to be changed from the default for the Mesh Portal (MPP) and that is the setting mesh_gate_announcements
.
mesh_gate_announcements
is used to enable or disable the announcement of mesh gateways. This setting is important for informing other mesh stations about the presence of gateways that can provide access to external networks, such as the Internet. The variable is also set in the /etc/config/wireless
and controls which of the mesh stations will announce itself as a gateway to other stations in the mesh. Only mesh stations that provide connectivity to external networks should have mesh_gate_announcements
set to '1' so that regular mesh stations discover and maintain routes to the gateways, ensuring that traffic destined for external networks is efficiently routed. The default is 0
. The Mesh Portal (MPP) needs mesh_gate_announcements
set to 1
.
config wifi-iface <interface_name>
....
option mesh_gate_announcements '1'
....
Hopefully, this should get your mesh and running more efficiently. The rest of the settings are not necessary but I thought it would be beneficial show how I changed the defaults to something that would be suitable for a small personal mesh.
Additional Settings & Information
Probably unnecessary tuning... but what fun would it be not to tinker with things? Besides, it's a way to learn...
You can find out what your default mesh settings are by using some commands in a terminal window of your router.
Here's a command that will show all of the available IEEE 802.11s parameters available in your OpenWrt router.
iw dev <dev_name> get mesh_param
Using a Linksys EA8300 mesh portal as an example, here is the command and the output.
# iw dev phy2-mesh0 get mesh_param
Possible mesh parameters are:
- mesh_retry_timeout
- mesh_confirm_timeout
- mesh_holding_timeout
- mesh_max_peer_links
- mesh_max_retries
- mesh_ttl
- mesh_element_ttl
- mesh_auto_open_plinks
- mesh_hwmp_max_preq_retries
- mesh_path_refresh_time
- mesh_min_discovery_timeout
- mesh_hwmp_active_path_timeout
- mesh_hwmp_preq_min_interval
- mesh_hwmp_net_diameter_traversal_time
- mesh_hwmp_rootmode
- mesh_hwmp_rann_interval
- mesh_gate_announcements
- mesh_fwding
- mesh_sync_offset_max_neighor
- mesh_rssi_threshold
- mesh_hwmp_active_path_to_root_timeout
- mesh_hwmp_root_interval
- mesh_hwmp_confirmation_interval
- mesh_power_mode
- mesh_awake_window
- mesh_plink_timeout
- mesh_connected_to_gate
- mesh_nolearn
- mesh_connected_to_as
To see the default and confirm set values set in /etc/config/wireless, use this command:
iw dev <dev_name> mesh_param dump
These are the default values in my EA8300 when first setting up a mesh device in LUCI.
# iw dev phy1-mesh0 mesh_param dump
mesh_retry_timeout = 100 milliseconds
mesh_confirm_timeout = 100 milliseconds
mesh_holding_timeout = 100 milliseconds
mesh_max_peer_links = 99
mesh_max_retries = 3
mesh_ttl = 31
mesh_element_ttl = 31
mesh_auto_open_plinks = 0
mesh_hwmp_max_preq_retries = 4
mesh_path_refresh_time = 1000 milliseconds
mesh_min_discovery_timeout = 100 milliseconds
mesh_hwmp_active_path_timeout = 5000 TUs
mesh_hwmp_preq_min_interval = 10 TUs
mesh_hwmp_net_diameter_traversal_time = 50 TUs
mesh_hwmp_rootmode = 0
mesh_hwmp_rann_interval = 5000 TUs
mesh_gate_announcements = 0
mesh_fwding = 1
mesh_sync_offset_max_neighor = 50
mesh_rssi_threshold = 0 dBm
mesh_hwmp_active_path_to_root_timeout = 6000 TUs
mesh_hwmp_root_interval = 5000 TUs
mesh_hwmp_confirmation_interval = 2000 TUs
mesh_power_mode = active
mesh_awake_window = 10 TUs
mesh_plink_timeout = 0 seconds
mesh_connected_to_gate = 0
mesh_nolearn = 0
mesh_connected_to_as = 0
A TU
is defined as 1.024 millisecond. In other words, 1000 TUs
equals 1.024 seconds or conversely, 977 TUs
is 1.000 seconds.
This is my EA8300 portal after changing some of the defaults in /etc/config/wireless
to what i thought are settings more suitable for a small network portal configuration:
# iw dev phy2-mesh0 mesh_param dump
mesh_retry_timeout = 100 milliseconds
mesh_confirm_timeout = 100 milliseconds
mesh_holding_timeout = 100 milliseconds
mesh_max_peer_links = 15
mesh_max_retries = 3
mesh_ttl = 5
mesh_element_ttl = 3
mesh_auto_open_plinks = 0
mesh_hwmp_max_preq_retries = 4
mesh_path_refresh_time = 1000 milliseconds
mesh_min_discovery_timeout = 100 milliseconds
mesh_hwmp_active_path_timeout = 5000 TUs
mesh_hwmp_preq_min_interval = 10 TUs
mesh_hwmp_net_diameter_traversal_time = 50 TUs
mesh_hwmp_rootmode = 3
mesh_hwmp_rann_interval = 5000 TUs
mesh_gate_announcements = 1
mesh_fwding = 1
mesh_sync_offset_max_neighor = 150
mesh_rssi_threshold = 0 dBm
mesh_hwmp_active_path_to_root_timeout = 6000 TUs
mesh_hwmp_root_interval = 5000 TUs
mesh_hwmp_confirmation_interval = 2000 TUs
mesh_power_mode = active
mesh_awake_window = 10 TUs
mesh_plink_timeout = 0 seconds
mesh_connected_to_gate = 0
mesh_nolearn = 0
mesh_connected_to_as = 0
I will now briefly describe some of the additional parameters I changed from their default values by defining them in the /etc/config/wireless
file.
mesh_max_peer_links: determines the maximum number of peer links (connections between mesh stations) that a single mesh station can establish. This parameter's role is in managing the connectivity and performance of the mesh network, especially as the network size and complexity increases. For a small to medium sized network (up to 20 stations), a setting of 3 to 5 peer links per station should be sufficient. A moderate number of peer links ensures reliable connectivity without overloading more distant individual stations.
'mesh_fwding: This option controls whether the mesh station will forward packets not destined for it. Setting mesh_fwding
to 0
disables this behaviour, meaning that the station will only handle its own traffic and will not forward packets from other stations. This should only be set to 0
for some specific reason and only if any of the other mesh access points don't need to hop through this router to get to the mesh portal. For example, I have one mesh point set up as a NAS (Network Attached Storage) device and as it is a low bandwidth router (a TP-Link C7). I used this setting to insure other traffic doesn't burden this TP-Link NAS device.
mesh_rssi_threshold
: is used to define the minimum signal strength (RSSI, Received Signal Strength Indicator) that a mesh station requires to establish and maintain a link with another mesh station. If the signal strength of a potential link falls.
mesh_ttl
: is the mesh Time-To-Live value controlling the number of hops a mesh packet can traverse in the network. TTL settings (this one and the next) are used to limit the number of hops a packet can take before being discarded, preventing packets from circulating indefinitely and potentially causing network congestion. With small personal mesh systems of less than 10 stations, this can be a small value, something no larger than 3 to 5 unless you have your mesh stations all in a single line requiring more hops.
mesh_element_ttl
: is the parameter that determines the mesh management frames Time-To-Live (TTL) hops. Management frames are used for mesh routing and control purposes within the mesh network. Again, for small personal mesh systems of less than 10 stations, this can be a small value, something no larger than 3 to 5 unless you have an unusual arrangement of your mesh stations. mesh_element_ttl
applies to management frames used for network control and routing information dissemination, while mesh_ttl
applies to data frames carrying actual user data.
mesh_hwmp_max_preq_retries
specifies the maximum number of times a mesh point (MP) will retry sending a Path Request (PREQ) message when trying to establish or update a route to another mesh point. For small to medium sized networks (up to 20 stations), I found 1 to 2 retries to be sufficient.
mesh_max_peer_links
: determines the maximum number of peer links (direct connections between mesh stations) that a single mesh station can establish. For small to medium sized networks (up to 20 stations), I would think 3 to 5 peer links per station should be sufficient.
A Red Herring
I found the setting mesh_connected_to_gate
was unnecessary in the functioning of up my small mesh networks.
The root station of your mesh systems determines if it has a connection to the outside via its routing configuration, network interface status, DNS resolution, and successful connections to external hosts. Using the settings I've specified above, your root station is sending out announcements to the other stations identifying itself as the gate station.(mesh_gate_announcements
set to TRUE)
Mesh gate connection status of non-root stations (MPs and MAPs) is determined by the reception of the mesh gate announcements by the gate connected mode. Consequently, once these stations receive a gate announcement, they will announce themselves as connect to a gate in path requests.
You cannot set mesh_connected_to_gate
in /etc/config/wireless
as OpenWrt does not support this and may have done this intentionally. While mesh_connected_to_gate:
can be set with iw
commands after the router is up and running, this overrides the automatic mechanism for correctly setting this value. Also, I have tried setting the option to true both manually and by writing a small daemon that issues iw commands after boot and checks that the option is set. In terms of latency or bandwidth to eternal locations through the MAPs, I saw no advantage in performance. Lastly, I could find no role for this setting other than being a state variable in the IEEE 802.11s documentation.
I admit that this is a bit of a supposition and pragmatic solution on my part does and not constitute a solid proof. I think the best way to resolve any questions or debate is to examine the OpenWrt source code, which handles the 802.11s mesh functions, particularly gate connections and status.
Testing & Diagnostics
Due to post size limitations, the next sections will be posted in the replies to this thread.