ath_hw_setbssidmask(9)
π ath_hw_setbssidmask(9) β the one from the Kernel API Manual π
okay bestie, so this is a kernel API manual page, and it's literally about filtering out bssids we listen β that's the whole name, no cap.
β¨ SYNOPSIS β¨
void ath_hw_setbssidmask (struct ath_common *common );
π«Ά ARGUMENTS π«Ά
commonβ theath_commonstruct for the device. that's it, that's the whole vibe check.
πΈ DESCRIPTION πΈ
BSSID masking is a method used by AR5212 and newer hardware to inform PCU which bits of the interface's MAC address should be looked at when trying to decide which packets to ACK. highkey iconic behaviour tbh.
So in station mode, and in AP mode with a single BSS, every bit matters since we lock to only one BSS. but in AP mode with multiple BSSes (virtual interfaces), not every bit matters, because hw must accept frames for all BSSes β so we tweak some bits of our mac address in order to have multiple BSSes. slay, we're flexible like that π
β NOTE β
okay important, listen up π β this is a simple filter and does not filter out all relevant frames. Some frames that are not for us might get ACKed from us by PCU because they just match the mask. like, the mask is doing its best, not its best-best. π
When handling multiple BSSes you can get the BSSID mask by computing the set of ~ ( MAC XOR BSSID ) for all bssids we handle.
When you do this you are essentially computing the common bits of all your BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with the MAC address to obtain the relevant bits and compare the result with (frame's BSSID & mask) to see if they match. it's giving bitwise matchmaking fr fr π¦
Simple example: on your card you have two BSSes you have created with BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address. There is another BSSID-03 but you are not part of it. For simplicity's sake, assuming only 4 bits for a mac address and for BSSIDs you can then have:
MAC: 0001 | BSSID-01: 0100 | --> Belongs to us BSSID-02: 1001
| / ------------------- BSSID-03: 0110 | --> External
-------------------
Our bssid_mask would then be:
On loop iteration for BSSID-01: ~(0001 ^ 0100) -> ~(0101) -> 1010
bssid_mask = 1010
On loop iteration for BSSID-02: bssid_mask &= ~(0001 ^ 1001)
bssid_mask = (1010) & ~(0001 ^ 1001) bssid_mask = (1010) & ~(1000)
bssid_mask = (1010) & (0111) bssid_mask = 0010
A bssid_mask of 0010 means "only pay attention to the second least significant bit". This is because its the only bit common amongst the MAC and all BSSIDs we support. To findout what the real common bit is we can simply "&" the bssid_mask now with any BSSID we have or our MAC address (we assume the hardware uses the MAC address). periodt. π
Now, suppose there's an incoming frame for BSSID-03:
IFRAME-01: 0110
An easy eye-inspeciton of this already should tell you that this frame will not pass our check. This is because the bssid_mask tells the hardware to only look at the second least significant bit and the common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB as 1, which does not match 0. sorry bestie, blocked π«
So with IFRAME-01 we assume the hardware will do:
allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0; --> allow = (0010) == 0000 ? 1 : 0; --> allow = 0
Lets now test a frame that should work:
IFRAME-02: 0001 (we should allow)
allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; --> allow = (0000) == (0000) --> allow = 1
Other examples:
IFRAME-03: 0100 --> allowed IFRAME-04: 1001 --> allowed IFRAME-05: 1101 --> allowed but its not for us!!!
that last one is literally the mask being a little too accepting π see the NOTE above, it's not a bug, it's just the vibe of a simple filter.
π₯ SEE ALSO π₯
- Kernel file
./drivers/net/wireless/ath/hw.c ath_hw_cycle_counters_update(9)
and that's the whole page, bestie π§ ngl this one came from ./drivers/net/wireless/ath and it's dated October 2026 β go forth and mask those bssids πβ¨π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms