RSSADAPT(9)
πΈ RSSADAPT(9) β the rssadapt page, but make it group-chat πΈ
okay so this is the rssadapt(9) page from the Kernel Developer's Manual, and we are gonna get into it. It's giving kernel networking, it's giving rate adaptation, and honestly it's kinda iconic. bestie, grab a strawberry π and let's go.
β¨ NAME β¨
rssadapt, ieee80211_rssadapt_choose, ieee80211_rssadapt_input, ieee80211_rssadapt_lower_rate, ieee80211_rssadapt_raise_rate, ieee80211_rssadapt_updatestats β all of these are the same bestie squad, and their whole thing is rate adaptation based on received signal strength π
π§ SYNOPSIS π§
Include these, no cap:
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_rssadapt.h>
void
ieee80211_rssadapt_input(struct ieee80211com *ic,
struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi);
void
ieee80211_rssadapt_lower_rate(struct ieee80211com *ic,
struct ieee80211_node *ni, struct ieee80211_rssadapt *ra,
struct ieee80211_rssdesc *id);
void
ieee80211_rssadapt_raise_rate(struct ieee80211com *ic,
struct ieee80211_rssadapt *ra, struct ieee80211_rssdesc *id);
void
ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *ra);
int
ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra,
struct ieee80211_rateset *rs, struct ieee80211_frame *wh, u_int len,
int fixed_rate, const char *dvname, int do_not_adapt);
π DESCRIPTION π
So the rssadapt module gives 802.11 device drivers rapid adaptation of transmission data rate based on received-signal strength (RSS). A driver literally only has to hand rssadapt two things: indications of RSS, and failure/success info for transmissions, for each 802.11 client or peer. That's it. That's the whole situationship π«Ά
For each transmit packet, rssadapt chooses the transmission data rate that offers the best expected throughput, given the packet's length and where it's going.
rssadapt models an 802.11 channel very simply β see also the βBUGSβ section, bestie, I'm just the messenger π. It assumes the packet-error rate (PER) is determined by the signal-to-noise ratio (S/N) at the receiver, the transmission data rate, and the packet length. The S/N determines the choice of data rate that yields the lowest PER for all packets of a certain length. slay, honestly.
π₯ FUNCTIONS π₯
π ieee80211_rssadapt_choose(ra, rs, wh, len, fixed_rate, dvname, do_not_adapt)
This one chooses the transmission data rate for a packet. main character energy, fr fr. The arguments are:
raβ ordinarily, therssadaptstate object belonging to the node which is the packet destination. BUT if the destination is a broadcast/multicast address, thenrabelongs to the BSS node,ic->ic_bss. plot twist πrsβ a list of eligible data rates for the node; for example, the rates negotiated when the node associated with the network.lenβ the packet length in bytes, including the 802.11 header and frame check sequence (FCS).fixed_rateβ if the operator has set the data rate using, for example,ifconfig wi0 media ds1, thenfixed_ratetells the index of that rate inrs.rssadaptobeys a fixed data rate whenever the 802.11 standard allows it: sometimes the standard requires multicast/broadcast packets to be transmitted at a so-called βbasic rateβ.dvnameβ the device driver usesdvnameto indicate the name of the interface for the purpose of diagnostic and debug messages. The driver setsdvnametoNULLwhen no messages are desired.do_not_adaptβ ifdo_not_adaptis non-zero, thenieee80211_rssadapt_choose()will choose the highest rate inrsthat suits the destination, regardless of the RSS.
The return value of ieee80211_rssadapt_choose() is an index into rs, indicating its choice of transmit data rate. cute, concise, correct π
the signature also has wh β the original page doesn't give it its own little bullet here, so I'm not out here inventing lore β¨
π¦ ieee80211_rssadapt_input(ic, ni, ra, rssi)
The RSS serves as a rough estimate of the S/N at each node. A driver provides RSS updates using ieee80211_rssadapt_input(), whose arguments are:
icβ the wireless interface's 802.11 state object.niβ the 802.11 node whose RSS the driver is updating.raβ the node'srssadaptstate object.rssiβ the node's received signal strength indication. The range ofrssiis from0to255.
π«Ά ieee80211_rssadapt_lower_rate(ic, ni, ra, id) + ieee80211_rssadapt_raise_rate(ic, ra, id)
Drivers call ieee80211_rssadapt_raise_rate() and ieee80211_rssadapt_lower_rate() to indicate transmit successes and failures, respectively. yes bestie, raise = success, lower = failure, keep that straight π
icβ the 802.11 state object.niβ the neighbor to whom the driver transmitted.raβ the neighbor'srssadaptstate object.idβ displays statistics on the transmission attempt. (the original literally says βDIsplaysβ with a capital I and I respect the chaos π)
π ieee80211_rssadapt_updatestats(ra)
An 802.11 node is eligible for its RSS thresholds to decay every 1/10 to 10 seconds. It is eligible more often β every 1/10 second β at high packet rates, and less often β every 10 seconds β at low packet rates. A driver assists rssadapt in tracking the exponential-average packet rate by calling ieee80211_rssadapt_updatestats() every 1/10th second for each node's ieee80211_rssadapt object.
raβ the neighbor'srssadaptstate object.
π ALGORITHM π
rssadapt monitors the RSS from neighboring 802.11 nodes, recording the exponential average RSS in each neighbor's ieee80211_rssadapt structure. It uses transmit success/failure feedback from the device driver to fill a table of RSS thresholds. The table is indexed by packet size, L, and a data rate, R, to find out the minimum exponential-average RSS that a node must show before rssadapt will indicate that a packet L bytes long can be transmitted R bits per second with optimal expected throughput. the way this table is doing the most π
When the driver indicates a unicast packet is transmitted unsuccessfully β that is, the NIC received no ACK for the packet β rssadapt will move the corresponding RSS threshold toward the exponential average RSSI at the time of transmission. Thus several consecutive transmit failures for the same β¨L, Rβ© tuple will ensure that the RSS threshold rises high enough that rate R is abandoned for packets L bytes long. it's giving consequences π
When the driver indicates a successful transmission, the RSS threshold corresponding to the same packet length, but the next higher data rate, is lowered slightly. The RSS threshold is said to βdecayβ. This ensures that occasionally rssadapt indicates the driver should try the next higher data rate, just in case conditions at the receiver have changed β for example, noise levels have fallen β and a higher data rate can be supported at the same RSS level. periodt, we love a little optimism β¨
The rate of decay is controlled. In an interval of 1/10th second to 10 seconds, only one RSS threshold per neighbor may decay. The interval is connected to the exponential-average rate that packets are being transmitted. At high packet rates, the interval is shortest. It is longest at low packet rates. The rationale for this is that RSS thresholds should not decay rapidly if there is no information from packet transmissions to counteract their decay. like, if nobody's talking, maybe don't spiral? self-care π§
π DATA STRUCTURES π
πΈ struct ieee80211_rssdesc
An ieee80211_rssdesc describes a transmission attempt. here's the layout, verbatim:
struct ieee80211_rssdesc {
u_int id_len;
u_int id_rateidx;
struct ieee80211_node *id_node;
u_int8_t id_rssi;
};
id_lenis the length, in bytes, of the transmitted packet.id_nodepoints to the neighbor'sieee8021_nodeβ yes, that's the spelling in the original, I'm not fixing it, I'm just reporting π«‘ β andid_rssiis the exponential-average RSS at the time the packet was transmitted.id_rateidxis an index into the destination-neighbor's rate-set,id_node->ni_rates, indicating the transmit data rate for the packet.
π struct ieee80211_rssadapt
An ieee80211_rssadapt contains the rate-adaptation state for a neighboring 802.11 node. Ordinarily a driver will βsubclassβ ieee80211_node. The ieee80211_rssadapt structure will be a subclass member. In this way, every node's rssadapt condition is independently tracked and stored in its node object. cute little per-node diary π
struct ieee80211_rssadapt {
u_int16_t ra_avg_rssi;
u_int32_t ra_nfail;
u_int32_t ra_nok;
u_int32_t ra_pktrate;
u_int16_t ra_rate_thresh[IEEE80211_RSSADAPT_BKTS]
[IEEE80211_RATE_SIZE];
struct timeval ra_last_raise;
struct timeval ra_raise_interval;
};
ra_avg_rssiis the exponential-average RSS, shifted left8bits.ra_nfailtells the number of transmit failures in the current update interval.ra_noktells the number of transmit successes in the current update interval.ra_pktratetells the exponential average number of transmit failure/success indications over past update intervals. This approximates the rate of packet-transmission.ra_rate_threshcontains RSS thresholds that are indexed byβ¨packet length, data rateβ©tuples. When this node's exponential-average RSS exceedsra_rate_thresh[i][j], then packets at most128 x 8^ibytes long are eligible to be transmitted at the rate indexed byj.ra_last_raiseandra_raise_intervalare used to control the rate that RSS thresholds βdecayβ.ra_last_raiseindicates whenieee80211_rssadapt_raise_rate()was last called.ra_raise_intervaltells the minimum period between consecutive calls toieee80211_rssadapt_raise_rate(). Ifieee80211_rssadapt_raise_rate()is called more than once in any period, the second and subsequent calls are ignored. not me being ignored but okay π
π¦ CODE REFERENCES π¦
- The code for
rssadaptis in the filesys/net80211/ieee80211_rssadapt.c. wi(4)contains a reference implementation. Seesys/dev/ic/wi.c.
β¨ and that's part 1, bestie β part 2 is coming, so don't touch that dial β¨
π SEE ALSO π
wi(4)β the driver bestie that hangs out with this whole system π«Ά
Also, if you wanna go straight to the source (literally), there's this paper and it is academic but it's also iconic:
Javier del Prado Pavon and Sunghyun Choi, βLink Adaptation Strategy for IEEE 802.11 WLAN via Received Signal Strength Measurementβ, ICC'03, pp. 1108-1113, Anchorage, Alaska, May 2003.
Like, that's the whole receipts situation right there. Go read it if you want the β¨ lore β¨. π
πΈ HISTORY πΈ
So when did this queen first show up? rssadapt first appeared in NetBSD 3.0. Like, she's been serving since way back. Not me getting emotional about a kernel subsystem ππ
π AUTHORS π
This whole thing was brought to you by:
- David Young
<dyoung@NetBSD.org>
That's the person to thank. Absolute main character energy. π
π BUGS π
okay bestie, sit down, because we gotta talk about the things that are not slaying yet. These are known issues, not vibes I made up, so listen up:
- To cope with interference from microwave ovens, frequency-hopping radios, and other sources of RF pulse-trains and bursts,
rssadaptshould adapt the fragmentation threshold as well as the data rate. - For improved throughput,
rssadaptshould indicate to drivers when they should use the 802.11b short-preamble. - The constants in
ieee80211_rssadapt_updatestats()should be configurable.
Not the microwave oven catching strays π like fr, your lunch reheating is out here causing RF pulse-trains and bursts and this thing currently only adapts the data rate, not the fragmentation threshold. The short-preamble thing? Also not indicated to drivers yet, so throughput stays a little mid. And those constants in ieee80211_rssadapt_updatestats()? Hardcoded vibes only β they should be configurable. So basically: these are the "should" list, not the "does" list. No cap. π
So yeah, she's not perfect yet. But she's ours. π₯Ή
And that's the whole page, bestie! This one's from Debian, dated March 23, 2004 β genuinely a vintage drop, and honestly she still ate. πβ¨ Go forth and adapt those rates. π¦πβ
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2004 David Young. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms