Linux wireless regulatory domains

I had a case where I had an embedded system that should act as a WiFi Access Point on the 5GHz band. The HW was capable and the system managed to act as a client to 5GHz networks, so everything looked good.

However, the system could not create an access point on some frequencies. How is it that? It's all about regulatory domains!

/media/tux-radio.png

Regulatory domains

Radio regulations is something that applies to all devices that make transmissions in the radio spectrum. The Linux kernel makes itself compliant to these regulations by make the regulatory restrictions as a directly part of the cfg80211 configuration API that all (new) wireless device drivers use.

Radio regulatory hasn't always been so tight integrated into the Linux kernel. This is a result to address the vendor concerns [6] about getting products based on Linux certified against all (geographically dependent) radio regulatory authorities out there.

Before that, all wireless drivers used to be a propritary blob that we load into our kernel, nowadays more and more vendors has a more FOSS driven development for such a drivers which is what we strive for.

To build trust with the chip vendors so that they could consider FOSS drivers as an real alternative, we stick to a number of principles.

Principles

There are a few principles [1] that the Linux kernel follows in order to fulfull the requirements for on use of the radio spectrum:

  • It should be reasonably impossible for a user to fail to comply with local regulations either unwittingly or by accident.
  • Default configurations should err in favor of more restrictive behavior in order to protect unwitting users.
  • Configurations that have no known compliant usage should not be part of the 'official' kernel tree.
  • Configurations that are compliant only under special circumstances (e.g. with special licenses) should not be part of the 'official' kernel tree. Any exceptions should have their legal requirements clearly marked and those options should never be configured by default.
  • Configurations that disable regulatory enforcement mechanisms should not be part of the 'official' kernel tree.
  • The kernel should rely on userland components to determine regulatory policy. Consequently, the kernel's regulatory enforcement mechanisms should be flexible enough to cover known or reasonably anticipated regulatory policies.
  • It's the moral duty of responsible distribution vendors, software developers, and community members to make every good faith effort to ensure proper compliance with applicable regulations regarding wireless communications.

The overall approach is "better safe than sorry" with respect to radio regulations. In other words, if no local configuration is setup, the system will fall back to the more restrictive world regulatory domain.

An example on such behaviour could be that the system is not allowed to initiate radio communication on certain radio frequencies that is not globally allowed.

Integration

CRDA

(Used pre Linux v4.15.)

CRDA [3], Central Regulatory Domain Agent, is a userspace agent responsible to read and intepret the regulatory.bin file and update the regulatory domains.

CRDA is intended to be trigged on uevents from the kernel (via udev) upon changes in the regulatory domain and setup the new regulations .

The udev rule to do this my look like this:

KERNEL=="regulatory*", ACTION=="change", SUBSYSTEM=="platform", RUN+="/sbin/crda"

Nowadays, CRDA is no longer needed as of kernel v.4.15 ( commit [2], "cfg80211: support loading regulatory database as firmware file"), the regulatory database is read by the Linux kernel directly as a firmware file during boot.

wireless-regdb

wireless-regdb [4] is the regulatory database used by Linux. The db.txt file in the repository contains regulatory information for each domain.

The output from this project is regulatory.db, which is loaded by the kernel as a firmware. The integrity of regulatory.db is typically ensured by the regulatory daemon by verifying the built-in RSA signature against a list of public keys in a preconfigured directory.

Although it's possible to build regulatory.db without any RSA key signature checking, it is highly recommended not to do so, as if the regulatory database is compromised in some way we could end up with a product that violates product radio compatibility.

wireless-regdb and Yocto

A side note for Yocto users.

The wireless-regdb recipe is part of oe-core [5] and should be included into your image if you intend to use any wireless LAN. wireless-regdb-static should be used with kernel >= v4.15 and wireless-regdb is intended to be used with CRDA.

In other words, add:

IMAGE_INSTALL:append = " wireless-regdb-static "

to your yocto distribution.

Hands on

iw [7] is the nl80211 based tool we use to configure wireless devices in Linux.

Here we will take a look at what the regulations may look like.

World regulatory domain

# iw reg get
global
country 00: DFS-UNSET
        (755 - 928 @ 2), (N/A, 20), (N/A), PASSIVE-SCAN
        (2402 - 2472 @ 40), (N/A, 20), (N/A)
        (2457 - 2482 @ 20), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
        (2474 - 2494 @ 20), (N/A, 20), (N/A), NO-OFDM, PASSIVE-SCAN
        (5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
        (5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW, PASSIVE-SCAN
        (5490 - 5730 @ 160), (N/A, 20), (0 ms), DFS, PASSIVE-SCAN
        (5735 - 5835 @ 80), (N/A, 20), (N/A), PASSIVE-SCAN
        (57240 - 63720 @ 2160), (N/A, 0), (N/A)

Country 00 is the world regulatory domain. This could be a result of a system that failed to load the regulatory database.

Look into the output from dmesg for verify:

$ dmesg | grep cfg80211
[    3.268852] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    3.269107] cfg80211: failed to load regulatory.db

As a result, this is the restrictions we have on the 5GHz band:

# iw list
[...]
                Frequencies:
                        * 5040 MHz [8] (disabled)
                        * 5060 MHz [12] (disabled)
                        * 5080 MHz [16] (disabled)
                        * 5170 MHz [34] (disabled)
                        * 5190 MHz [38] (20.0 dBm) (no IR)
                        * 5210 MHz [42] (20.0 dBm) (no IR)
                        * 5230 MHz [46] (20.0 dBm) (no IR)
                        * 5180 MHz [36] (20.0 dBm) (no IR)
                        * 5200 MHz [40] (20.0 dBm) (no IR)
                        * 5220 MHz [44] (20.0 dBm) (no IR)
                        * 5240 MHz [48] (20.0 dBm) (no IR)
                        * 5260 MHz [52] (20.0 dBm) (no IR, radar detection)
                        * 5280 MHz [56] (20.0 dBm) (no IR, radar detection)
                        * 5300 MHz [60] (20.0 dBm) (no IR, radar detection)
                        * 5320 MHz [64] (20.0 dBm) (no IR, radar detection)
                        * 5500 MHz [100] (20.0 dBm) (no IR, radar detection)
                        * 5520 MHz [104] (20.0 dBm) (no IR, radar detection)
                        * 5540 MHz [108] (20.0 dBm) (no IR, radar detection)
                        * 5560 MHz [112] (20.0 dBm) (no IR, radar detection)
                        * 5580 MHz [116] (20.0 dBm) (no IR, radar detection)
                        * 5600 MHz [120] (20.0 dBm) (no IR, radar detection)
                        * 5620 MHz [124] (20.0 dBm) (no IR, radar detection)
                        * 5640 MHz [128] (20.0 dBm) (no IR, radar detection)
                        * 5660 MHz [132] (20.0 dBm) (no IR, radar detection)
                        * 5680 MHz [136] (20.0 dBm) (no IR, radar detection)
                        * 5700 MHz [140] (20.0 dBm) (no IR, radar detection)
                        * 5745 MHz [149] (20.0 dBm) (no IR)
                        * 5765 MHz [153] (20.0 dBm) (no IR)
                        * 5785 MHz [157] (20.0 dBm) (no IR)
                        * 5805 MHz [161] (20.0 dBm) (no IR)
                        * 5825 MHz [165] (20.0 dBm) (no IR)
[...]

We can see the no IR flag is set for almost all frequencies on the 5GHz band. Please note that NO-IR is not the same as disabled, it simply means that we cannot initiate radiation on those frequencies.

Initiate radiation simply includes all modes of operations that require us to initiate radiation first. Think of acting as an Access Point, IBSS, Mesh or P2P master.

We can still use the frequency though, there is no problem to connect to an Access Point (we are not the one who initiate the radiation) on these frequencies.

Local regulatory domain

When a proper regulatory database is loaded into the system, we can setup the local regulatory domain instead of the globally one.

Set Swedish (SE) as our local regulatory domain:

# iw reg set SE
# iw reg get
global
country SE: DFS-ETSI
        (2400 - 2483 @ 40), (N/A, 20), (N/A)
        (5150 - 5250 @ 80), (N/A, 23), (N/A), NO-OUTDOOR, AUTO-BW
        (5250 - 5350 @ 80), (N/A, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
        (5470 - 5725 @ 160), (N/A, 26), (0 ms), DFS
        (5725 - 5875 @ 80), (N/A, 13), (N/A)
        (5945 - 6425 @ 160), (N/A, 23), (N/A), NO-OUTDOOR
        (57000 - 71000 @ 2160), (N/A, 40), (N/A)

And we are now allowed to use the 5GHz band with other restrictions:

#iw list
[...]
                Frequencies:
                        * 5040 MHz [8] (disabled)
                        * 5060 MHz [12] (disabled)
                        * 5080 MHz [16] (disabled)
                        * 5170 MHz [34] (23.0 dBm)
                        * 5190 MHz [38] (23.0 dBm)
                        * 5210 MHz [42] (23.0 dBm)
                        * 5230 MHz [46] (23.0 dBm)
                        * 5180 MHz [36] (23.0 dBm)
                        * 5200 MHz [40] (23.0 dBm)
                        * 5220 MHz [44] (23.0 dBm)
                        * 5240 MHz [48] (23.0 dBm)
                        * 5260 MHz [52] (20.0 dBm) (no IR, radar detection)
                        * 5280 MHz [56] (20.0 dBm) (no IR, radar detection)
                        * 5300 MHz [60] (20.0 dBm) (no IR, radar detection)
                        * 5320 MHz [64] (20.0 dBm) (no IR, radar detection)
                        * 5500 MHz [100] (26.0 dBm) (no IR, radar detection)
                        * 5520 MHz [104] (26.0 dBm) (no IR, radar detection)
                        * 5540 MHz [108] (26.0 dBm) (no IR, radar detection)
                        * 5560 MHz [112] (26.0 dBm) (no IR, radar detection)
                        * 5580 MHz [116] (26.0 dBm) (no IR, radar detection)
                        * 5600 MHz [120] (26.0 dBm) (no IR, radar detection)
                        * 5620 MHz [124] (26.0 dBm) (no IR, radar detection)
                        * 5640 MHz [128] (26.0 dBm) (no IR, radar detection)
                        * 5660 MHz [132] (26.0 dBm) (no IR, radar detection)
                        * 5680 MHz [136] (26.0 dBm) (no IR, radar detection)
                        * 5700 MHz [140] (26.0 dBm) (no IR, radar detection)
                        * 5745 MHz [149] (13.0 dBm)
                        * 5765 MHz [153] (13.0 dBm)
                        * 5785 MHz [157] (13.0 dBm)
                        * 5805 MHz [161] (13.0 dBm)
                        * 5825 MHz [165] (13.0 dBm)
[...]

Regulatory flags

Some of the flags reported by iw may not be obvious at a first glance. Here is an explaination for some of them:

Flag Meaning
  Can be used without restrictions.
disabled Disabled
NO-OUTDOOR MUST be used indoor only.
DFS MUST be used with DFS regardless indoor or outdoor.
SRD MUST comply with SRD requirements regardless indoor or outdoor.
NO-OUTDOOR/DFS MUST be used with DFS and indoor only.
NO-OUTDOOR/TPC MUST be used with TPC and indoor only.
DFS/TPC MUST be used with DFS and TPC.
DFS/TPC + SRD MUST be used with DFS, TPC and comply with SRD requirements.
  • DFS: stands for Dynamic Frequency Selection and is a channel allocation scheme used to prevent electromagnetic interference with systems that predates Wi-Fi.
  • TPC: stands for Transmit Power Control which is a mechanism to automatically reduce the used transmission output power when other networks are within range.
  • SRD: stands for Short-Range Device and cover devices that are low-power transmitters typically limited to the range of 24-100mW ERP.