ecific beacon handling routines. + +Raw frames differ from data frames in a couple of ways: + + * Transmit parameters are typically sent from userland or the caller + (struct ieee80211_bpf_params \*), and + * The input path into the driver is via ic->ic_raw_xmit(), not ic->ic_transmit(). + +The driver can combine the data and non-data paths into a single path. +The main reason for keeping these separate is to cleanly support drivers +and firmware which allow 802.3 frames to be sent and received, but still +need a side channel to send and receive management frames for various other +functions. + +The raw frame output path is used by: + + * The BPF output path - ieee80211_output() ; + * The management frame output path - ieee80211_mgmt_output() ; + * The NULL data output path - ieee80211_send_nulldata() ; + * Sending probe requests - ieee80211_send_probereq() ; + * Sending probe responses - ieee80211_send_proberesp() ; + * Sending 802.11n BAR frames - ieee80211_send_bar() ; + * .. and anywhere where the individual protocol (eg 802.11s) wishes to send raw + non-data frames. + +This path is not REALLY designed for high speed data - for example, +it should work for basic packet injection, but it does not pass through +the normal functions for encryption, power save, TX aggregation and other +data specific operations. It expects to be handed a raw, already encapsulated +802.11 frame. + +Note this is not an 802.11 MPDU - this is an 802.11 frame. For example, +non-data frames may not have sequence numbers. NULL data frames have a sequence +number but that sequence number must be 0. + +Once the driver ic->ic_raw_xmit() call is made, the driver can handle the +802.11 frame in any way it sees fit. Again, it can't assume it's an 802.11 +data frame. + +### BPF path + +Control frames are injected from userland and net80211 via a raw transmit path, +separate from the data path. This dates back to the earliest Orinoco/WaveLAN +cards, where the earlier firmware only allowed 802.3 frames to be sent/received, +but later firmware introduced raw packet transmit to allow wpa_supplicant +operation. + +Packet injection begins via the BPF/radiotap input path. The code in +ieee80211_radiotap.c attaches a BPF operator to the VAP during the +call to ieee80211_radiotap_vattach(). + +Raw frames start in BPF and are queued via bpf_ieee80211_write(), which will +send the frame into the driver via a call to the VAP ifp->if_output() and then +if provided, a copy of the feedback mbuf via the VAP ifp->if_input(). + +The ifp->if_output() method by default is ieee80211_output(). The driver +can override this. This takes care of validating that it is an 802.11 +frame, extracts the (struct ieee80211_bpf_params \*) header from the +destination sockaddr passed in via BPF, finds the relevant +struct ieee80211_node \*) tx node, grabs a reference, some further sanity +checks and then calls ieee80211_raw_output(). The rest of the raw output +path is the same as net80211 sourced raw frames. + +### Power Save Management + +By default, net80211 will track legacy power-save state between IBSS nodes +and STA <-> AP nodes (ie, full node buffering via the power management bit +in the 802.11 header; TIM/ATIM bitmaps in beacons, NULL data frames to wake up) +and PS-POLL frames being sent by stations to request individual frames. + +The transmit path will pass frames destined to asleep stations to the power +save queue via a call to ieee80211_pwrsave(). + +There are a number of VAP methods for the driver to tie into if it needs to be +informed about this state (vap->iv_set_tim, vap->iv_recv_pspoll, vap->iv_node_ps). +These allow the driver to keep its own internal state in sync with net80211 +and allows it to better maintain its own transmit queue state. + +See the ath(4) driver for a comprehensive example of how these methods are used +to correctly transmit and buffer frames from an AP to STA device without packet +loss. + +### Transmit path encryption + +The net80211 stack needs to handle a variety of transmit encryption schemes +based on all the combinations that driver and firmware interfaces may require. + +In general, the transmit encryption is done in two phases: + + * In ieee80211_encap(), the transmit key is chosen via a call + to ieee80211_crypto_getucastkey() or ieee80211_crypto_getmcastkey() - the + key index is added to the 802.11 header and space is reserved between + the 802.11 header/payload and at the end for the encryption key data to be + added; + * Then when the driver transmits the frame, it calls ieee80211_crypto_encap() + to actually do the encryption. + +Some hardware will completely offload encryption, so although the key choice +is made, various driver configuration options are set to inform net80211 not +to add all the padding. Others will offload encryption but require the +space to be provided in the frame for the hardware/firmware to add the +encryption information into. + +### What is IEEE80211_F_DATAPAD ? + +This is actually to support hardware such as the Atheros 802.11abgn chips, +which have a 4 byte alignment requirement between the 802.11 header and +the data payload (including the encryption parts.) + +Yes, it likely should be a more generic option. + +### Future work + + * It would be nice to more formally define and enforce what drivers should be + doing with mbufs during the whole transmit lifecycle of an mbuf. + * Perhaps add a function or two for the drivers to use to + query whether a given mbuf has a TX notification attached (rather + than drivers querying M_TXCB) so they can individually + register for explicit notifications so they can provide more + accurate completion information. + * The fast frames age / flush routines should really be expanded to + be required functionality in net80211 drivers rather than optional + when IEEE80211_SUPPORT_SUPERG is enabled, so further software transmit + queue management is possible in net80211. + diff --git a/sys/net80211/DEBUG.md b/sys/net80211/DEBUG.md new file mode 100644 index 000000000000..2231a0992fe6 --- /dev/null +++ b/sys/net80211/DEBUG.md @@ -0,0 +1,101 @@ +# Debugging in net80211 + +This document describes how debugging is implemented in net80211. + +## Overview + +net80211 has run-time configurable debugging available. It is configured +per-VAP. It is implemented as a bitmask which can be controlled via a +sysctl at runtime. + +Debugging is compiled in when IEEE80211_DEBUG is defined. + +There is currently no global debugging API available; top-level net80211 +code is typically using printf() or some wrapper around it (eg +net80211_printf). + +The debug API is defined in (ieee80211_var.h). This includes the +debug field definitions and exported debugging API. The actual implementation +of the debugging routines is currently in (ieee80211_input.c) - see +(ieee80211_note) for an example. + +The bitmap of available debugging sections is in (ieee80211_var.h), prefixed +with IEEE80211_MSG . See (IEEE80211_MSG_DEBUG) for an example. + +## Usage + +Calls to the debugging APIs should not include a terminating '\n' character. +This will be added by the debug call. + +The simplest example is a call to IEEE80211_DPRINTF(). This takes a vap +pointer, which debug option to log to, then the format string and optional +arguments. For example: + +``` +IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N, "%s: called!", __func__); +``` + +The debug flags can be combined together using bitwise OR so they are +emitted if one or more debug options are set, for example: + +``` +IEEE80211_DPRINTF(vap, IEEE80211_MSG_11N | IEEE80211_MSG_ASSOC, + "%s: called!", __func__); +``` + +There are a number of different debugging calls that are designed to be +used in different contexts. Although they all currently end up printing +to the same debug output, keeping them separate allows for future +behavioural changes whilst minimising rototilling the whole codebase (eg +allowing non-DPRINTF to turn into event tracing.) + + * Straight up debugging should be done through IEEE80211_DPRINTF() . + * Debugging that's related to a specific ieee80211_node (eg a state + change for a specific node) should be done via a call to IEEE80211_NOTE() . + * Debugging that's related to a specific ethernet MAC address (eg + scan results) should be done via a call to IEEE80211_NOTE_MAC() . + * Debugging that should include a frame header should be done via + a call to IEEE80211_NOTE_FRAME(). Note this takes a (struct ieee80211_frame \*) + pointer. + * Debugging involving discarding frames (eg invalid frames) should be + done via a call to IEEE80211_DISCARD() . + * Debugging involving discarding frames due to an invalid / bad IE should + be done via a call to IEEE80211_DISCARD_IE(). + * Debugging involving discarding frames due to a MAC address (eg ACL failure) + should be done via a call to IEEE80211_DISCARD_MAC(). + +## Usage Notes + + * It is required that the debugging be compiled in/out purely by defining or not + defining IEEE80211_DEBUG. This can often trip up unused variable warnings + when debugging is disabled, so just double-check both configurations. + + * It is important to ensure calls to the debugging (and any other logging API) + do not change any state/variables. For example, do not call a function that + updates some counter or some state variable inside a call to IEEE80211_DPRINTF(). + It won't be called at best and it will just be compiled out entirely at worst. + +## Configuration + + * The 'vap->iv_debug' field is controlled by the OS specific module. + * In FreeBSD (ieee80211_freebsd.c) it is assigned a sysctl (net.wlan.X.debug) + during (ieee80211_sysctl_vattach). + * FreeBSD ships the wlandebug(8) tool to query and set this at runtime. + +## Implementation Details + +* The debug API goes out of its way to do the debug flag check before evaluating + function parameters and potentially assembling the logging output. See + (IEEE80211_DPRINTF) for an example. + +## Future work + + * Top-level net80211 debugging APIs and control would be nice (for things + that are not specific to a VAP.) + * Drivers end up having to implement their own debugging API; it may be nice + to provide drivers a net80211 API to do their own driver specific logging. + * The debug macros should likely be refactored out to a new header file, + separate from ieee80211_var.h, so they can be more easily referenced. + * The debug fields should likely be refactored out into a new separate header + file that is designed to be consumed both by the kernel and by userland + utilities wishing to query/set the debug bitmask. diff --git a/sys/net80211/PROTOCOL.md b/sys/net80211/PROTOCOL.md new file mode 100644 index 000000000000..6d7c128bfc89 --- /dev/null +++ b/sys/net80211/PROTOCOL.md @@ -0,0 +1,563 @@ +# 802.11 protocol overview + +This is a quick overview of the 802.11 protocol and where it intersects with +net80211. It is not intended as a comprehensive deep dive into all of 802.11. + +TODO: link to appropriate sections in 802.11-2016 / 802.11-2020 depending upon +which PDF is freely available. + +## 802.11 overview + +The 802.11 protocol / specification is a very large document which covers +everything from the raw signals going out over the air up to how devices +need to behave in different operating modes. + +The IEEE specification documents and amendments describe what devices should +and must do in order to interoperate. It's important to note that the +intersection of "what the standard says" and "what devices do" is not always +fully aligned. The 802.11 specification has evolved over twenty-five years +and for the most part this allows interoperability between the original 802.11b +hardware and modern multi-band 802.11ax devices. + +It's also important to note that 802.11 is not just limited to the IEEE +specifications. 802.11 devices are almost exclusively RF devices (if you +read the specification you may find the old infrared / IR protocol definition!) +and so need to operate inside of the radio regulatory rules defined by each +country. These define a wide variety of RF environmental behaviours +including frequencies can be used, when devices can transmit, what transmit +power is allowed, interoperability with other devices (802.11 and non-802.11) +and radar interoperability. For the purposes of this document these will +be called "regulatory concerns" and will be covered elsewhere. + +The 802.11 specification breaks things up into a handful of top level areas: + + * the PHY layer - how the device interfaces with the RF environment and + encodes/decodes RF transmissions into data streams. + * the MAC layer - defines how data is packetized into individual data frames, + exchanged with the upper layer (ethernet/bridge), deciding when and what + to transmit via the PHY layer. + * MLME - (MAC layer management entities) - defines all of the state methods + and transitions that underpin the 802.11 MAC state machine. + * Security - the cipher and key management components. + * PHY specifications - the specific implementations of PHYs - 2GHz DSSS + (spread spectrum), 2GHZ CCK, OFDM, ERP, 802.11n / HT, 802.11ac / VHT, etc. + +Most 802.11 implementations do not implement a 1:1 definition of each of these +layers - notably implementing every single MLME state would be a huge amount +of work. + +## 802.11 revisions + +There have been many revisions of the 802.11 specification. The specifications +can be found online at https://www.ieee802.org/11/. + +The latest specification being implemented in net80211 is 802.11-2020, however +net80211 is far from completely compliant. Generally new code which implements +802.11 features / protocol handling should identify the specification and +section which it is referencing. + +## 802.11 protocol and frame definitions + +net80211 keeps most 802.11 frame and protocol definitions in a single location +(ieee80211.h). +This contains descriptions of the 802.11 frame and field definitions, ranging +from the lowest definition of the frame itself up through frame types/subtypes, +individual field definitions, information elements, action frames, and +anything else that can be found in the 802.11 specifications. + +The PHY definitions can be found in (ieee80211_phy.c) and (ieee80211_phy.h). +Notably those include the frame timing information useful for rate control +and frame duration calculations. + +## 802.11 Revisions + +(TBD) + +### Legacy 802.11 + +The earliest 802.11 devices implement 1Mbit/s and 2Mbit/s direct spread spectrum +frames. These include the earliest Wavelan devices. These are grandfathered +into 802.11b. The PHY specification can be found in 802.11-2020 Section 15.) + +### 802.11b + +802.11b devices implement Section 15 (1Mbit/2Mbit) PHYs as well as the high +rate DSSS specification (802.11-2020 Section 16) to provide 5.5Mbit and 11Mbit +CCK rates. They interoperate with legacy 802.11 devices by using compatible +PHY encodings and will limit their performance if said legacy devices are +detected. + +### 802.11a + +802.11a devices implement OFDM rates from 6Mbit/s to 54Mbit/s on the 5GHz +band. Among other features, it also defines 5MHz and 10MHz wide channel +behaviour. This is covered in the OFDM PHY specification (802.11-2020 +Section 17.) + +### 802.11g + +802.11g devices implement OFDM rates from 802.11a, the CCK rates from 802.11b +and the DSSS rates from legacy 802.11. These are covered in the ERP +specification (802.11-2020 Section 18.) There are some MAC extensions for +negotiating 802.11b / 802.11g interoperability and these are documented +throughout the MAC specification. This also specifies support for 5MHz and +10MHz wide channels. + +### 802.11n (HT) + +802.11n introduced a variety of high throughput rates and feature support +(hence why it's called HT - high throughput). It introduces higher density +OFDM rate encodings, 20 and 40MHz wide channels with interoperability for +earlier devices, packet aggregation via A-MPDU and A-MSDU, MIMO (multiple input, +multiple output spatial streams), some initial beamforming support, power +saving extensions and more. + +The physical layer support is covered in the HT PHY specification (802.11-2020 +Section 19.) The rest of the MAC extensions are documented throughout the +rest of the specification. + +### 802.11ac (VHT) + +802.11ac extends the 802.11n specification (hence why it's VHT - Very +High Throughput) and boosts performance by adding higher density OFDM QAM +encoding (256-QAM), wider channels (80MHz, 160MHz), split 80+80MHz channel +support, much larger A-MSDU / A-MPDU frame sizes, support for MU-MIMO +(multi-user MIMO) allowing APs to transmit to multiple STAs at the same time +and various other extensions. + +It builds on top of the 802.11n MAC and PHY specification, so a lot of +802.11n feature and MAC negotiation happens as part of 802.11ac negotiation. + +The PHY layer is covered in the VHT PHY Specification (802.11-2020 Section +21.) Again, the rest of the MAC extensions are documented throughout the +rest of the specification. + +### Greenfield versus backwards compatibility + +The various protocols supported by 802.11 build on top of earlier protocols. +So typically you're not building a single implementation for each protocol - +for example, you can't handle 802.11ac support without implementing a large +amount of 802.11n support. + +(As a side note, the 802.11 frame has a protocol version field, and +that actually changed in 802.11ah (900MHz and longer distance bands) - +which changes a lot of what the fields do. No, net80211 currently does not +support 802.11ah and will drop frames whose 802.11 protocol ID is not +supported.) + +At the PHY layer, later model hardware can transmit data encodings which +earlier model hardware just won't recognise. All they'll see is an increase +in RF power on the channel at best and signals that will confuse the +RX decoder / cause hardware issues at worst.) + +So each of the PHY specifications will lay out a few things: + + * How frames should be encoded in the air in a way that earlier + hardware can decode them enough to know it's not for them; + * How devices can identify that earlier protocol devices are around and + change the configuration (eg STA changing its own configuration, + AP changing the configuration of the network it controls, etc) + to provide backwards compatibility. + +These come at a performance cost. For example, an 802.11g AP which +supports 802.11b and 802.11 devices needs to notice that an 802.11b +device wishes to associate, and when it sees this, change some of +its configuration (notably "long preamble" so 802.11b devices can +decode frames that are being transmitted, whether destined to it or not.) + +Various devices allow backwards compatbility to be configured. +For example, an 802.11n AP may be configured to deny non-802.11n clients. +This may improve performance but then earlier clients can't connect. + +In 802.11n deployments this was known as a "greenfield deployment". +This typically disables any and all pre-11n interoperability at both +a MAC and PHY layer. net80211 has some flags for this to specifically +inform devices that they can configure the hardware for such a setup. +Not all drivers implement it however, and in a lot of cases they will +still handle pre-11n framing, even if the net80211 code will deny +association. + +There are other components to backwards compatibility which are worth +keeping in mind when reading through the 802.11 specification and +net80211 stack / driver code. These include: + + * short/long preamble - (vap_update_preamble) + * short/long slot time configuration - (vap_update_slot) + * 802.11g protection mode (vap_update_erp_protmode) - + whether to use CTS-to-self around each transmission + * 802.11n protection mode (vap_update_ht_protmode) - + whether to use RTS/CTS around each transmission + * 802.11n 20/40MHz BSS operation (whether an 802.11n AP sees other APs that + overlap its frequency range and need to reconfigure how to protect + transmissions) + +## How 802.11 (very briefly) works over the air + +This is a very brief and not at all comprehensive overview of how 802.11 +works over the air. The goal of this section is to provide enough background +information to help de-mystify reading the net80211 stack and wireless +driver source. + +### Why there's timing requirements in the first place + +Each of the PHY sections in the 802.11 specification describe what +the PHY needs to do in order to transmit and receive data. It's not +anywhere as easy as "toggle some bits on a wire". + +An important thing to understand is that hardware isn't immediate. +All the state machines in your 802.11 devices take non-zero time +to make decisions about when to transmit, when to receive, locking +onto a signal, deciding it can be decoded, getting reset for the next +frame, etc. + +So a lot of what you'll see in 802.11 negotiation and feature support +is linked to the underlying hardware implementations and limitations +of the time. For example the 802.11b specification defines the slot time +as 20uS, but the 802.11g specification lowers it to 9uS. The "slot time" +value defines the unit of time used for contention management / backoff, and +it's defined partly by what the speed of light dictates (ie how big +of a physical area you want to be able to "hear" in determining if the +area is busy) and how quickly the hardware can guarantee to respond. +It dropped to 9uS because hardware got better, but to interoperate +with older devices without starting to transmit before they're +ready to react, 802.11g devices will fall back to 20uS slot time when +they detect an 802.11b device. + +This carries through everywhere in odd places that you're not necessarily +aware of. For example, the 802.11n A-MPDU definition includes negotiated +padding between frames and limits encryption ciphers (typically CCMP or +GCMP.) This is due to hardware support - the MAC may be able to support +much less padding when no encryption is used, but setting up / resetting +the encryption / decryption blocks may take more time and thus larger +A-MPDU padding values are negotiated. + +### Wait, the speed of light? + +Yes. The speed of light is roughly 300 metres for each microsecond of +travel time. + +### Preambles, SIGs, PLCP, sending actual data and waiting / slot times + +There are a few things that are worth understanding at a high level. + + * The first thing that a device needs to do is determine + whether the air is busy or free. There'll be some hardware + to determine the signal level versus noise floor and provide + a signal to the transmit hardware that the air is free, + and to the receiver that it may want to try start decoding + something. + + * The receiver needs to get in synchronisation with the transmitter. + This is a one way operation - the transmitter needs to transmit + enough of a signal that the receiver can "lock onto" and get itself + ready for further data. This is called the "preamble" - it's + typically a low bitrate repeating pattern of data that gives + the receiver hardware time to lock onto, figure out the signal + level and be ready for the next phase. + + * Note that the receiver may pick up the preamble at any point in its + transmission so it can't guarantee it will see exactly "x" bits of some + repeating pattern. + + * Then there's other bits and pieces - eg look for L-SIG, HT-SIG + in the PHY documentation - which is used to further synchronise + what's about to happen. + + * Finally it will start transmitting the PHY framing bits needed to + identify what the upcoming transmit rate and configuration is + (all the stuff leading up to the PLCP header, then the PLCP header.) + +Things get more complicated with MIMO, MU-MIMO, 802.11ax OFDM-A, etc but +don't worry about those for now - they build on top of all of these +ideas. + +Once the data is transmitted, there's some quiet time between frames +before the receiver can ACK (and then a period of time where an ACK +is expected.) The transmitter needs to finish transmitting, then +reset its internal state back to idle to be ready to receive - and +there's the pesky speed of light speed of 300m per microsecond - +so there's some MAC (interframe spacing) and PHY (slot time) enforcing +quiet so everyone has a chance to receive the frame and the reciver *** 442 LINES SKIPPED ***