Blacklisting client mode BSSIDs in OpenWRT

I have an OpenWRT router that I use to privately share a connection to a public hotspot. In other words, I use one of the Wi-Fi interfaces to connect to the internet via a hotspot, and share it to my own devices via another Wi-Fi interface. This is pretty easy to accomplish with OpenWRT and simply requires switching the Wi-Fi interface to client mode and setting the network interface to something in the WAN firewall zone (typically wwan).

This post isn’t going to cover the basics of that configuration, but instead cover a problem I’ve had with hotspots that associate but then fail to respond to DHCP requests. That essentially kills my internet connection for a while until udhcpc times out (sometimes it doesn’t) and a new association attempt is made with a different access point. Each hotspot has its own BSSID, which is the MAC address of the access point. You can find this address either from the Wireless section of the web frontend, or from watching the association attempts from the system log (e.g. logread -f). There is no obvious way to blacklist a particular access point by MAC address in client mode from Luci (OpenWRT’s web frontend). It is pretty easy to accomplish from the command line. First, determine which radio you are using for the client mode connection, e.g. radio0, radio1, etc. and then find its configuration “section” name, e.g. “wifinet1”, “wifinet2”, etc.

wifi status

You can also get this information another way using the uci command:

uci show wireless

Once you have found the configuration section for the radio device you are using, it’s as simple as adding the blacklist value. Here we will assume the configuration section ‘wifinet1’ and set the blacklist to include the fake MAC address values ‘xx:xx:xx:xx:xx:xx’ and ‘nn:nn:nn:nn:nn:nn’:

uci set wireless.wifinet1.bssid_blacklist='xx:xx:xx:xx:xx:xx nn:nn:nn:nn:nn:nn'

As you can tell, the MAC addresses are separated by spaces.

Now write the changes to the system configuration:

uci commit

Finally, restart the wireless interface. We’ll assume radio0 as an example:

wifi up radio0

This will prevent the wireless client interface from connecting to the access points in the blacklist. This works because the bssid_blacklist value is passed through from uci to wpa_supplicant via hostapd.sh. Note that this value may get clobbered if you touch the wireless interface configuration from the Luci frontend since it is not included there.