Band steering vs separate SSIDs

Based on a fair amount of corporate experience:

  • Use the same SSID name for 2.4 GHz and 5 GHz. Please, for all that is good and holy, do not create dedicated SSIDs for different bands. Using different SSIDs causes clients to stick to the SSID for dear life until they can no longer reach it. A client will not willingly roam to a different SSID just because its signal strength is better. Having the same SSID name allows the client to choose which band to use.
  • Only enable band steering if you really have to. Modern clients are pretty good at deciding which band to use. Band steering tends to introduce latency in associating with an access point (as it typically relies on ignoring client association attempts to one radio if it would prefer the client to connect to another radio) which can caused increased roaming latency, which can cause voice dropouts on calls. IMO the only interesting use cases these days are the ones with commercial products that group like clients to an AP (e.g. all WiFi 6 clients on one AP, all WiFi 5 clients on another.)
5 Likes

Design tip: aim to have the crossover point between APs at a signal strength of ~--65dBm to -67dBm. The only vendor that has reasonably good documentation on thresholds is Apple but it's reasonable to assume other vendors will follow a similar approach: Wi-Fi roaming support in Apple devices - Apple Support

Interpretation:

  • iPhones (and likely others) will start looking for new APs when they reach a signal strength of -70dBm.
  • They will look for an AP that has a signal level at least 8dB better than their current AP (12dB if idle.)
  • If no neighbouring APs of -62dBm or better are found, the client will stick to the current AP until it reaches -75dBm, but increased scanning frequency will likely have a performance impact.
  • If your crossover is -65dBm, by the time your phone reaches -70dBm the signal of the neighbouring AP should be approaching ~-60dBm, making for simplified (faster) roaming.
2 Likes

I can see how a corporate setting with more AP's and more control over AP location, neighboring AP channel width and channel selection may change things. However, in my residential setting, even with wide channels I have little 5 GHz interference from any AP's. Whereas 2.4 GHz is a free-for-all mess of 40 MHz wide back haul channels, 20 MHz channels randomly chosen with no regard for using 1, 6 or 11, and all of them shouting at their full 30 dBm.

A client abandoning several hundred Mbps of low latency wide 5 GHz channel throughput at -70dBm to get a stronger -62 dBm signal on a 2.4 GHz connection delivering sub 100 Mbps high latency throughput through a sea of interference has not improved its situation. Band specific SSID's prevent this sorry result in my residential setting.

There is no location on my residential property where clients cannot reach a 5 GHZ SSID that provides vastly superior performance to 2.4 GHz. I want my clients to stick with 5 GHz for dear life :wink: . My 5 GHz SSID's have the same name on all AP's so that clients connected to them can roam between my wired AP's, but staying on 5 GHz. The exceptions are 2.4 GHz only devices that are either stationary (set once and forget) or do not need a high quality connection, and the very occasional long reach to my network from a neighbor's back yard where 2.4 GHz is Hobson's choice.

If you are forced with 1 6 11 it is quite likely 30dBm is legal also.

Correct, in my region 30 dBm 2.4 GHz is legal; channels are not restricted to 1, 6 and 11; and there is no penalty for OEM's or perpetrators if OEM firmware or they ignore a rule prohibiting 40 MHz wide 2.4 GHz channels outside of a green field. Hence, neighbors create 2.4 GHz chaos using irresponsible or ignorant OEM defaults or settings they select on their mesh systems.

Thank you for sharing your experience. Could you please clarify:

  1. which brand AP/AP management software did you use?
  2. were the fast roaming features enabled for APs?
  3. were the majority of wireless devices laptops or mobile devices?

Provided your 5GHz networks overlap at ~-65dB, it shouldn't be a problem then :slight_smile: As I say, modern clients are more intelligent than people sometimes give them credit for. I doubt it's a case of a blind "8dB better than -70dB or bust."

@stangri don't want to hijack the thread, but for commercial products: mostly HP (original, pre-2008), HP (Colubrus, 2008+), HP (Comware, 2013+), HPE (Aruba - combination of Instant-, Campus- and Central-based deployments.) Also some very brief brushes with Cisco, Ruckus, Fortinet but I don't really know those product ranges well at all. (I did have to deal quite a bit with UniFi at one stage. Let's just say I am completely mystified by how there is such a large, very vocal fanbase for that product range.)

Typical changes I make from defaults (mostly to improve roaming, but also general performance) are:

  • reducing transmit power to match what the endpoints are capable of (this is quite important)
  • the bits that are included in the concept of: Wi-Fi Agile Multiband | Wi-Fi Alliance aka 802.11k/v/u/r
  • enabling 802.11h on 5GHz to allow DFS/TCP-controlled channels to be used
  • on 2.4 GHz, disable all the BPSK/QPSK rates (1/2/5.5/11) and set Beacon Rate to 6Mbps or higher. Not worth much these days but it's a hangover from how we cleaned up some congestion in days gone by...

I have on occasion been forced to turn off 802.11r on compatibility grounds due to some misbehaving (Intel...) endpoints. Not a big deal on PSK-authenticated networks perhaps, but the impact is a bit larger on 802.1X-authenticated networks, which then makes the old PMK Caching & Pre-Auth features useful again, though that requires some config at the client-end.

Most corporate networks I deal with have managed clients (Windows laptops mostly) connected to 802.1X authenticated networks and a "guest/byod" SSID with Captive Portal & MAC authentication to which they connect anything from the cleaner's cheap Android phone to TVs and contractors' corporate laptops. Some have a separate SSID for corporate-controlled devices that don't support 802.1X (AV equipment, some cameras, etc.) but most of those devices don't roam much.

1 Like

How do you do that?

https://openwrt.org/docs/guide-user/network/wifi/basic

option cell_density '3'

Note you lose distance coverage.
It is in upper "advanced" section of wifi access points via luci/network/wireless next to country code

2 Likes

On OpenWRT:

The theory is that slower beacon broadcasts consume lots of airtime, particularly if there are lots of additional information in the beacon. This is particularly an issue if you have many APs with many SSIDs, but in a home/home office environment I just consider it neighbourly to have less impact on everyone else.

This is an excellent resource on this (arguably niche) topic: Revolution Wi-Fi: SSID Overhead Calculator (revolutionwifi.blogspot.com)

I had a couple of screenshots of a spectrum analyser capture up on the older forum at some stage but I think they went missing. Should probably do that excercise again if I can find a spot that's quiet enough to exclude external interference.

1 Like

@brada4 @atom_guy I don't see that it is working correctly. Some devices still use legacy rates.

root@mr70x:~# cat /etc/config/wireless 

config wifi-device 'radio0'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
        option band '2g'
        option htmode 'HE20'
        option country 'AR'
        option cell_density '3'
        option channel '1'

config wifi-iface '2g_lag'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'LAG'
        option encryption 'psk2+ccmp'
        option ifname '2g_lag'
        option key 'password'
        option macaddr 'random'

config wifi-device 'radio1'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0+1'
        option channel '36'
        option band '5g'
        option htmode 'HE80'
        option country 'AR'
        option cell_density '3'

config wifi-iface '5g_lag'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'Jitter'
        option encryption 'psk2+ccmp'
        option ifname '5g_jitter'
        option key 'password'
        option macaddr 'random'

config wifi-iface '2g_invitados'
        option device 'radio0'
        option mode 'ap'
        option ssid 'Invitados'
        option encryption 'psk2+ccmp'
        option ifname '2g_invitados'
        option key 'password'
        option network 'invitados'
        option macaddr 'random'

config wifi-iface '5g_invitados'
        option device 'radio1'
        option mode 'ap'
        option ssid 'Invitados'
        option encryption 'psk2+ccmp'
        option ifname '5g_invitados'
        option key 'password'
        option network 'invitados'
        option macaddr 'random'

According to this text, the minimum rate should be 24 Mbit/s.

With density 1 I have it working as described, 6Mbps is smallest announced by ap as seen by iw wlan0 scan from Linux.

I ended up doing the same, but with only two APs the effort is manageable... I also use one unique ssid per ap, this was mainly intended as a debug help to get an easier way of probing which ap works best from which location. Turns out this works well enough (including switch over) that I never bothered to improve on it.

That is an important point, as signal strength is not all that well correlated with the measure we are trying to optimize.... (signal strength likely does correlate with 'stability' and throughput, just not all that strongly).

Reading the documentation on the Wiki page, you likely will need to set "legacy_rates" to 0 for "cell_density" to work properly. Have a close look at my post.

IMO Anything above 6Mbps for beacon transmissions really has diminishing benefits. Only use higher values if you have lots of closely-spaced APs (hence the parameter name: cell_density), and even then reducing transmit power will likely be a better approach for managing density.

[OpenWrt Wiki] Wi-Fi /etc/config/wireless
cell_density
Configures data rates based on the coverage cell density. Normal configures basic rates to 6, 12, 24 Mbps if legacy_rates is 0, else to 5.5, 11 Mbps. High configures basic rates to 12, 24 Mbps if legacy_rates is 0, else to the 11 Mbps rate. Very High configures 24 Mbps as the basic rate. Supported rates lower than the minimum basic rate are not offered. The basic_rate and supported_rates options overrides this option. 0 = Disabled, 1 = Normal, 2 = High, 3 = Very High

1 Like

My understanding is that the default setting for option 'legacy_rates' is 0, so adding option legacy_rates '0' is redundant.

I think legacy rates and cell density have to be separated as it creates confusion. And the text below the drop-down list is, well, too much text.

  1. option cell_density '3'
config wifi-device 'radio0'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
        option band '2g'
        option htmode 'HE20'
        option country 'AR'
        option cell_density '3'
        option channel '1'

  1. option cell_density '3' + option legacy_rates '0'
config wifi-device 'radio0'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
        option band '2g'
        option htmode 'HE20'
        option country 'AR'
        option cell_density '3'
        option channel '1'
        option legacy_rates '0'

  1. option cell_density '2' + option legacy_rates '0'
config wifi-device 'radio0'
        option type 'mac80211'
        option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
        option band '2g'
        option htmode 'HE20'
        option country 'AR'
        option cell_density '3'
        option channel '1'
        option legacy_rates '0'

What has to be separated? Two already separate options?
Do you have rates from iw scan ?

        Supported rates: 6.0* 9.0 12.0* 18.0 24.0* 36.0 48.0 54.0 
        Supported rates: 1.0* 2.0* 5.5* 11.0* 9.0 18.0 36.0 54.0 

What is the dropdown list for? According to the text below, it serves to deactivate the rates of the 802.11b accompanied by the "legacy_rates" option. Or I'm not understanding. Which the text confuses.

The most important thing is that these options do not do what they should and in the screenshot it is seen that a device uses a rate that is not allowed (1 Mbit/s).

Entering that command in the terminal does not offer any results similar to what you wrote.

Commands has to be entered in terminal of a linux system iw wlan0 scan

This is what I get

root@mr70x:~# iw wlan0 scan
Usage:  iw [options] command
Options:
        --debug         enable netlink debugging
        --version       show version (5.19)
Commands:
        dev <devname> disconnect
                Disconnect from the current network.

        dev <devname> connect [-w] <SSID> [<freq in MHz>] [<bssid>] [auth open|shared] [key 0:abcde d:1:6162636465] [mfp:req/opt/no]
                Join the network with the given SSID (and frequency, BSSID).
                With -w, wait for the connect to finish or fail.

        dev <devname> auth <SSID> <bssid> <type:open|shared> <freq in MHz> [key 0:abcde d:1:6162636465]
                Authenticate with the given network.


        event [-t|-T|-r] [-f]
                Monitor events from the kernel.
                -t - print timestamp
                -T - print absolute, human-readable timestamp
                -r - print relative timestamp
                -f - print full frame for auth/assoc etc.

        phy <phyname> hwsim getps 


        phy <phyname> hwsim setps <value>


        phy <phyname> hwsim stopqueues 


        phy <phyname> hwsim wakequeues 


        dev <devname> ibss leave
                Leave the current IBSS cell.

        dev <devname> ibss join <SSID> <freq in MHz> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>] [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] [key d:0:abcde]
                Join the IBSS cell with the given SSID, if it doesn't exist create
                it on the given frequency. When fixed frequency is requested, don't
                join/create a cell on a different frequency. When a fixed BSSID is
                requested use that BSSID and do not adopt another cell's BSSID even
                if it has higher TSF and the same SSID. If an IBSS is created, create
                it with the specified basic-rates, multicast-rate and beacon-interval.

        phy <phyname> info
                Show capabilities for the specified wireless device.

        list
                List all wireless devices and their capabilities.

        phy
        features 


        phy <phyname> interface add <name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]
                Add a new virtual interface with the given configuration.
                Valid interface types are: managed, ibss, monitor, mesh, wds.

                The flags are only used for monitor interfaces, valid flags are:
                none:     no special flags
                fcsfail:  show frames with FCS errors
                control:  show control frames
                otherbss: show frames from other BSSes
                cook:     use cooked mode
                active:   use active mode (ACK incoming unicast packets)
                mumimo-groupid <GROUP_ID>: use MUMIMO according to a group id
                mumimo-follow-mac <MAC_ADDRESS>: use MUMIMO according to a MAC address

                The mesh_id is used only for mesh mode.

        dev <devname> interface add <name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*] [addr <mac-addr>]
        dev <devname> del
                Remove this virtual interface

        dev <devname> info
                Show information for this interface.

        dev
                List all network interfaces for wireless hardware.

        help [command]
                Print usage for all or a specific command, e.g.
                "help wowlan" or "help wowlan enable".

        dev <devname> link
                Print information about the current link, if any.

        dev <devname> mesh join <mesh ID> [[freq <freq in MHz> <NOHT|HT20|HT40+|HT40-|80MHz>] [basic-rates <rate in Mbps,rate2,...>]], [mcast-rate <rate in Mbps>] [beacon-interval <time in TUs>] [dtim-period <value>] [vendor_sync on|off] [<param>=<value>]*
                Join a mesh with the given mesh ID with frequency, basic-rates,
                mcast-rate and mesh parameters. Basic-rates are applied only if
                frequency is provided.

        dev <devname> mesh leave
                Leave a mesh.

        dev <devname> mesh_param dump 
                List all supported mesh parameters

        dev <devname> mpath probe <destination MAC address> frame <frame>
                Inject ethernet frame to given peer overriding the next hop
                lookup from mpath table.
                .Example: iw dev wlan0 mpath probe xx:xx:xx:xx:xx:xx frame 01:xx:xx:00


        dev <devname> mpath get <MAC address>
                Get information on mesh path to the given node.

        dev <devname> mpath del <MAC address>
                Remove the mesh path to the given node.

        dev <devname> mpath new <destination MAC address> next_hop <next hop MAC address>
                Create a new mesh path (instead of relying on automatic discovery).

        dev <devname> mpath set <destination MAC address> next_hop <next hop MAC address>
                Set an existing mesh path's next hop.

        dev <devname> mpath dump
                List known mesh paths.

        dev <devname> mpp get <MAC address>
                Get information on mesh proxy path to the given node.

        dev <devname> mpp dump
                List known mesh proxy paths.

        phy <phyname> channels
                Show available channels.

        reg set <ISO/IEC 3166-1 alpha2>
                Notify the kernel about the current regulatory domain.

        reg get
                Print out the kernel's current regulatory domain information.

        phy <phyname> reg get
                Print out the devices' current regulatory domain information.

        reg reload
                Reload the kernel's regulatory database.

        dev <devname> scan [-u] [freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]
                Scan on the given frequencies and probe for the given SSIDs
                (or wildcard if not given) unless passive scanning is requested.
                If -u is specified print unknown data in the scan results.
                Specified (vendor) IEs must be well-formed.

        dev <devname> scan dump [-u]
                Dump the current scan results. If -u is specified, print unknown
                data in scan results.

        dev <devname> scan trigger [freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory,coloc] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]
                Trigger a scan on the given frequencies with probing for the given
                SSIDs (or wildcard if not given) unless passive scanning is requested.
                Duration(in TUs), if specified, will be used to set dwell times.


        dev <devname> scan abort 
                Abort ongoing scan

        dev <devname> get mesh_param [<param>]
                Retrieve mesh parameter (run command without any to see available ones).

        phy <phyname> get txq 
                Get TXQ parameters.

        dev <devname> get power_save 
                Retrieve power save state.

        dev <devname> set bitrates [legacy-<2.4|5> <legacy rate in Mbps>*] [ht-mcs-<2.4|5> <MCS index>*] [vht-mcs-<2.4|5> [he-mcs-<2.4|5|6> <NSS:MCSx,MCSy... | NSS:MCSx-MCSy>*] [sgi-2.4|lgi-2.4] [sgi-5|lgi-5] [he-gi-<2.4|5|6> <0.8|1.6|3.2>] [he-ltf-<2.4|5|6> <1|2|4>]
                Sets up the specified rate masks.
                Not passing any arguments would clear the existing mask (if any).

        dev <devname> set monitor <flag>*
                Set monitor flags. Valid flags are:
                none:     no special flags
                fcsfail:  show frames with FCS errors
                control:  show control frames
                otherbss: show frames from other BSSes
                cook:     use cooked mode
                active:   use active mode (ACK incoming unicast packets)
                mumimo-groupid <GROUP_ID>: use MUMIMO according to a group id
                mumimo-follow-mac <MAC_ADDRESS>: use MUMIMO according to a MAC address

        dev <devname> set meshid <meshid>
        dev <devname> set type <type>
                Set interface type/mode.
                Valid interface types are: managed, ibss, monitor, mesh, wds.

        dev <devname> set 4addr <on|off>
                Set interface 4addr (WDS) mode.

        dev <devname> set noack_map <map>
                Set the NoAck map for the TIDs. (0x0009 = BE, 0x0006 = BK, 0x0030 = VI, 0x00C0 = VO)

        dev <devname> set mcast_rate <rate in Mbps>
                Set the multicast bitrate.

        dev <devname> set mesh_param <param>=<value> [<param>=<value>]*
                Set mesh parameter (run command without any to see available ones).

        phy <phyname> set name <new name>
                Rename this wireless device.

        phy <phyname> set freq <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
        phy <phyname> set freq <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]
                Set frequency/channel the hardware is using, including HT
                configuration.

        dev <devname> set freq <freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
        dev <devname> set freq <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]
        phy <phyname> set channel <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
        dev <devname> set channel <channel> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz]
        phy <phyname> set frag <fragmentation threshold|off>
                Set fragmentation threshold.

        phy <phyname> set rts <rts threshold|off>
                Set rts threshold.

        phy <phyname> set retry [short <limit>] [long <limit>]
                Set retry limit.

        phy <phyname> set netns { <pid> | name <nsname> }
                Put this wireless device into a different network namespace:
                    <pid>    - change network namespace by process id
                    <nsname> - change network namespace by name from /var/run/netns
                               or by absolute path (man ip-netns)


        phy <phyname> set coverage <coverage class>
                Set coverage class (1 for every 3 usec of air propagation time).
                Valid values: 0 - 255.

        phy <phyname> set distance <auto|distance>
                Enable ACK timeout estimation algorithm (dynack) or set appropriate
                coverage class for given link distance in meters.
                To disable dynack set valid value for coverage class.
                Valid values: 0 - 114750

        phy <phyname> set txpower <auto|fixed|limit> [<tx power in mBm>]
                Specify transmit power level and setting type.

        dev <devname> set txpower <auto|fixed|limit> [<tx power in mBm>]
                Specify transmit power level and setting type.

        phy <phyname> set antenna <bitmap> | all | <tx bitmap> <rx bitmap>
                Set a bitmap of allowed antennas to use for TX and RX.
                The driver may reject antenna configurations it cannot support.

        phy <phyname> set txq limit <packets> | memory_limit <bytes> | quantum <bytes>
                Set TXQ parameters. The limit and memory_limit are global queue limits
                for the whole phy. The quantum is the DRR scheduler quantum setting.
                Valid values: 1 - 2**32

        dev <devname> set power_save <on|off>
                Set power save state to on or off.

        phy <phyname> set sar_specs <sar type> <range index:sar power>*
                Set SAR specs corresponding to SAR capa of wiphy.

        dev <devname> survey dump [--radio]
                List all gathered channel survey data

        dev <devname> station get <MAC address>
                Get information for a specific station.

        dev <devname> station del <MAC address> [subtype <subtype>] [reason-code <code>]
                Remove the given station entry (use with caution!)
                Example subtype values: 0xA (disassociation), 0xC (deauthentication)

        dev <devname> station dump [-v]
                List all stations known, e.g. the AP on managed interfaces

        dev <devname> station set <MAC address> txpwr <auto|limit> [<tx power dBm>]
                Set Tx power for this station.

        dev <devname> station set <MAC address> airtime_weight <weight>
                Set airtime weight for this station.

        dev <devname> station set <MAC address> vlan <ifindex>
                Set an AP VLAN for this station.


Commands that use the netdev ('dev') can also be given the
'wdev' instead to identify the device.

You can omit the 'phy' or 'dev' if the identification is unique,
e.g. "iw wlan0 info" or "iw phy0 info". (Don't when scripting.)

Do NOT screenscrape this tool, we don't consider its output stable.