13f3f4cdbSBruce M Simpson.\" 23f3f4cdbSBruce M Simpson.\" Copyright (c) 2004 Bruce M. Simpson <bms@spc.org> 33f3f4cdbSBruce M Simpson.\" Copyright (c) 2004 Darron Broad <darron@kewl.org> 43f3f4cdbSBruce M Simpson.\" All rights reserved. 53f3f4cdbSBruce M Simpson.\" 63f3f4cdbSBruce M Simpson.\" Redistribution and use in source and binary forms, with or without 73f3f4cdbSBruce M Simpson.\" modification, are permitted provided that the following conditions 83f3f4cdbSBruce M Simpson.\" are met: 93f3f4cdbSBruce M Simpson.\" 1. Redistributions of source code must retain the above copyright 103f3f4cdbSBruce M Simpson.\" notice, this list of conditions and the following disclaimer. 113f3f4cdbSBruce M Simpson.\" 2. Redistributions in binary form must reproduce the above copyright 123f3f4cdbSBruce M Simpson.\" notice, this list of conditions and the following disclaimer in the 133f3f4cdbSBruce M Simpson.\" documentation and/or other materials provided with the distribution. 143f3f4cdbSBruce M Simpson.\" 153f3f4cdbSBruce M Simpson.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 163f3f4cdbSBruce M Simpson.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 173f3f4cdbSBruce M Simpson.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 183f3f4cdbSBruce M Simpson.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 193f3f4cdbSBruce M Simpson.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 203f3f4cdbSBruce M Simpson.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 213f3f4cdbSBruce M Simpson.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 223f3f4cdbSBruce M Simpson.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 233f3f4cdbSBruce M Simpson.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 243f3f4cdbSBruce M Simpson.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 253f3f4cdbSBruce M Simpson.\" SUCH DAMAGE. 263f3f4cdbSBruce M Simpson.\" 27*1137943bSBjoern A. Zeeb.Dd October 2, 2023 282e777780SRuslan Ermilov.Dt IEEE80211_NODE 9 293f3f4cdbSBruce M Simpson.Os 303f3f4cdbSBruce M Simpson.Sh NAME 31692eebe0SSam Leffler.Nm ieee80211_node 323f3f4cdbSBruce M Simpson.Nd software 802.11 stack node management functions 333f3f4cdbSBruce M Simpson.Sh SYNOPSIS 343f3f4cdbSBruce M Simpson.In net80211/ieee80211_var.h 35692eebe0SSam Leffler.\" 36692eebe0SSam Leffler.Ft struct ieee80211_node * 37692eebe0SSam Leffler.Fo ieee80211_find_rxnode 38692eebe0SSam Leffler.Fa "struct ieee80211com *" 39692eebe0SSam Leffler.Fa "const struct ieee80211_frame_min *" 402e777780SRuslan Ermilov.Fc 41692eebe0SSam Leffler.\" 423f3f4cdbSBruce M Simpson.Ft struct ieee80211_node * 43692eebe0SSam Leffler.Fo ieee80211_find_rxnode_withkey 44692eebe0SSam Leffler.Fa "struct ieee80211com *" 45692eebe0SSam Leffler.Fa "const struct ieee80211_frame_min *" 46692eebe0SSam Leffler.Fa "ieee80211_keyix" 472e777780SRuslan Ermilov.Fc 48692eebe0SSam Leffler.\" 49692eebe0SSam Leffler.Ft struct ieee80211_node * 50692eebe0SSam Leffler.Fn ieee80211_ref_node "struct ieee80211_node *" 51692eebe0SSam Leffler.\" 523f3f4cdbSBruce M Simpson.Ft void 53692eebe0SSam Leffler.Fn ieee80211_free_node "struct ieee80211_node *" 54692eebe0SSam Leffler.\" 553f3f4cdbSBruce M Simpson.Ft void 562e777780SRuslan Ermilov.Fo ieee80211_iterate_nodes 57692eebe0SSam Leffler.Fa "struct ieee80211_node_table *" 58692eebe0SSam Leffler.Fa "ieee80211_iter_func *f" 59692eebe0SSam Leffler.Fa "void *arg" 60692eebe0SSam Leffler.Fc 61692eebe0SSam Leffler.\" 62692eebe0SSam Leffler.Ft void 63692eebe0SSam Leffler.Fo ieee80211_dump_nodes 64692eebe0SSam Leffler.Fa "struct ieee80211_node_table *" 65692eebe0SSam Leffler.Fc 66692eebe0SSam Leffler.\" 67692eebe0SSam Leffler.Ft void 68692eebe0SSam Leffler.Fo ieee80211_dump_node 69692eebe0SSam Leffler.Fa "struct ieee80211_node *" 702e777780SRuslan Ermilov.Fc 713f3f4cdbSBruce M Simpson.Sh DESCRIPTION 72692eebe0SSam LefflerThe 73692eebe0SSam Leffler.Nm net80211 74692eebe0SSam Lefflerlayer that supports 802.11 device drivers maintains a database of 75692eebe0SSam Lefflerpeer stations called the 76692eebe0SSam Leffler.Dq node table 77692eebe0SSam Lefflerin the 78692eebe0SSam Leffler.Vt ic_sta 79692eebe0SSam Lefflerentry of the 80692eebe0SSam Leffler.Vt ieee80211com 81692eebe0SSam Lefflerstructure. 82692eebe0SSam LefflerStation mode vaps create an entry for the access point 83692eebe0SSam Lefflerthe station is associated to. 84692eebe0SSam LefflerAP mode vaps create entries for associated stations. 85692eebe0SSam LefflerAdhoc and mesh mode vaps create entries for neighbor stations. 86692eebe0SSam LefflerWDS mode vaps create an entry for the peer station. 87692eebe0SSam LefflerStations for all vaps reside in the same table; each node 88692eebe0SSam Lefflerentry has a 89692eebe0SSam Leffler.Vt ni_vap 90692eebe0SSam Lefflerfield that identifies the vap that created it. 91692eebe0SSam LefflerIn some instances an entry is used by multiple vaps (e.g. for 92692eebe0SSam Lefflerdynamic WDS a station associated to an ap vap may also be the peer 93692eebe0SSam Lefflerof a WDS vap). 94df550d32SBruce M Simpson.Pp 95692eebe0SSam LefflerNode table entries are reference counted. 96692eebe0SSam LefflerThat is, there is a count of all long term references that determines 97692eebe0SSam Lefflerwhen an entry may be reclaimed. 98692eebe0SSam LefflerReferences are held by every in-flight frame sent to a station to 99e7f8dd75SRebecca Cranensure the entry is not reclaimed while the frame is queued or otherwise 100692eebe0SSam Lefflerheld by a driver. 101692eebe0SSam LefflerRoutines that lookup a table entry return a 102692eebe0SSam Leffler.Dq held reference 103692eebe0SSam Leffler(i.e. a pointer to a table entry with the reference count incremented). 104df550d32SBruce M SimpsonThe 105692eebe0SSam Leffler.Fn ieee80211_ref_node 106*1137943bSBjoern A. Zeebcall explicitly increments the reference count of a node. 107692eebe0SSam Leffler.Fn ieee80211_free_node 108*1137943bSBjoern A. Zeebdecrements the reference count of a node and if the count goes to zero 109*1137943bSBjoern A. Zeebreclaims the table entry. 110692eebe0SSam Leffler.Pp 111692eebe0SSam LefflerThe station table and its entries are exposed to drivers in several ways. 112692eebe0SSam LefflerEach frame transmitted to a station includes a reference to the 113692eebe0SSam Lefflerassociated node in the 114692eebe0SSam Leffler.Vt m_pkthdr.rcvif 115692eebe0SSam Lefflerfield. 116692eebe0SSam LefflerThis reference must be reclaimed by the driver when transmit processing 117692eebe0SSam Leffleris done. 118692eebe0SSam LefflerFor each frame received the driver must lookup the table entry to 119692eebe0SSam Leffleruse in dispatching the frame 120692eebe0SSam Leffler.Dq up the stack . 121692eebe0SSam LefflerThis lookup implicitly obtains a reference to the table entry and 122692eebe0SSam Lefflerthe driver must reclaim the reference when frame processing is completed. 123692eebe0SSam LefflerOtherwise drivers frequently inspect the contents of the 124692eebe0SSam Leffler.Vt iv_bss 125692eebe0SSam Lefflernode when handling state machine changes as important information 126692eebe0SSam Leffleris maintained in the data structure. 127692eebe0SSam Leffler.Pp 128692eebe0SSam LefflerThe node table is opaque to drivers. 129692eebe0SSam LefflerEntries may be looked up using one of the pre-defined API's or the 130692eebe0SSam Leffler.Fn ieee80211_iterate_nodes 131692eebe0SSam Lefflercall may be used to iterate through all entries to do per-node 132692eebe0SSam Lefflerprocessing or implement some non-standard search mechanism. 133692eebe0SSam LefflerNote that 134692eebe0SSam Leffler.Fn ieee80211_iterate_nodes 135692eebe0SSam Leffleris single-threaded per-device 136692eebe0SSam Lefflerand the effort processing involved is fairly 137692eebe0SSam Lefflersubstantial so it should be used carefully. 138692eebe0SSam Leffler.Pp 139692eebe0SSam LefflerTwo routines are provided to print the contents of nodes to the console 140692eebe0SSam Lefflerfor debugging: 141692eebe0SSam Leffler.Fn ieee80211_dump_node 142692eebe0SSam Lefflerdisplays the contents of a single node while 143692eebe0SSam Leffler.Fn ieee80211_dump_nodes 144692eebe0SSam Lefflerdisplays the contents of the specified node table. 145692eebe0SSam LefflerNodes may also be displayed using 14654862540SRui Paulo.Xr ddb 4 147692eebe0SSam Lefflerwith the 148692eebe0SSam Leffler.Dq show node 149692eebe0SSam Lefflerdirective and the station node table can be displayed with 150692eebe0SSam Leffler.Dq show statab . 151692eebe0SSam Leffler.Sh DRIVER PRIVATE STATE 152692eebe0SSam LefflerNode data structures may be extended by the driver to include 153692eebe0SSam Lefflerdriver-private state. 154692eebe0SSam LefflerThis is done by overriding the 155692eebe0SSam Leffler.Vt ic_node_alloc 156692eebe0SSam Lefflermethod used to allocate a node table entry. 157692eebe0SSam LefflerThe driver method must allocate a structure that is an extension 158692eebe0SSam Lefflerof the 159692eebe0SSam Leffler.Vt ieee80211_node 160692eebe0SSam Lefflerstructure. 161692eebe0SSam LefflerFor example the 162692eebe0SSam Leffler.Xr iwi 4 163692eebe0SSam Lefflerdriver defines a private node structure as: 164692eebe0SSam Leffler.Bd -literal -offset indent 165692eebe0SSam Lefflerstruct iwi_node { 166692eebe0SSam Leffler struct ieee80211_node in_node; 167692eebe0SSam Leffler int in_station; 168692eebe0SSam Leffler}; 169692eebe0SSam Leffler.Ed 170692eebe0SSam Leffler.Pp 171692eebe0SSam Lefflerand then provides a private allocation routine that does this: 172692eebe0SSam Leffler.Bd -literal -offset indent 173692eebe0SSam Lefflerstatic struct ieee80211_node * 174692eebe0SSam Leffleriwi_node_alloc(struct ieee80211vap *vap, 175692eebe0SSam Leffler const uint8_t mac[IEEE80211_ADDR_LEN]) 176692eebe0SSam Leffler{ 177692eebe0SSam Leffler struct iwi_node *in; 178692eebe0SSam Leffler 179692eebe0SSam Leffler in = malloc(sizeof(struct iwi_node), M_80211_NODE, 180692eebe0SSam Leffler M_NOWAIT | M_ZERO); 181692eebe0SSam Leffler if (in == NULL) 182692eebe0SSam Leffler return NULL; 183692eebe0SSam Leffler in->in_station = -1; 184692eebe0SSam Leffler return &in->in_node; 185692eebe0SSam Leffler} 186692eebe0SSam Leffler.Ed 187692eebe0SSam Leffler.Pp 188692eebe0SSam LefflerNote that when reclaiming a node allocated by the driver the 189692eebe0SSam Leffler.Dq parent method 190692eebe0SSam Lefflermust be called to ensure 191692eebe0SSam Leffler.Nm net80211 192692eebe0SSam Lefflerstate is reclaimed; for example: 193692eebe0SSam Leffler.Bd -literal -offset indent 194692eebe0SSam Lefflerstatic void 195692eebe0SSam Leffleriwi_node_free(struct ieee80211_node *ni) 196692eebe0SSam Leffler{ 197692eebe0SSam Leffler struct ieee80211com *ic = ni->ni_ic; 198692eebe0SSam Leffler struct iwi_softc *sc = ic->ic_ifp->if_softc; 199692eebe0SSam Leffler struct iwi_node *in = (struct iwi_node *)ni; 200692eebe0SSam Leffler 201692eebe0SSam Leffler if (in->in_station != -1) 202692eebe0SSam Leffler free_unr(sc->sc_unr, in->in_station); 203692eebe0SSam Leffler sc->sc_node_free(ni); /* invoke net80211 free handler */ 204692eebe0SSam Leffler} 205692eebe0SSam Leffler.Ed 206692eebe0SSam Leffler.Pp 207692eebe0SSam LefflerBeware that care must be taken to avoid holding references that 208692eebe0SSam Lefflermight cause nodes from being reclaimed. 209692eebe0SSam Leffler.Nm net80211 210692eebe0SSam Lefflerwill reclaim a node when the last reference is reclaimed in 211692eebe0SSam Lefflerits data structures. 212692eebe0SSam LefflerHowever if a driver holds additional references then 213692eebe0SSam Leffler.Nm net80211 214692eebe0SSam Lefflerwill not recognize this and table entries will not be reclaimed. 215692eebe0SSam LefflerSuch references should not be needed if the driver overrides the 216692eebe0SSam Leffler.Vt ic_node_cleanup 217692eebe0SSam Lefflerand/or 218692eebe0SSam Leffler.Vt ic_node_free 219692eebe0SSam Lefflermethods. 220692eebe0SSam Leffler.Sh KEY TABLE SUPPORT 221692eebe0SSam LefflerNode table lookups are typically done using a hash of the stations' 222692eebe0SSam Lefflermac address. 223692eebe0SSam LefflerWhen receiving frames this is sufficient to find the node table entry 224692eebe0SSam Lefflerfor the transmitter. 225692eebe0SSam LefflerBut some devices also identify the sending station in the device 226692eebe0SSam Lefflerstate received with each frame and this data can be used to optimize 227692eebe0SSam Lefflerlookups on receive using a companion table called the 228692eebe0SSam Leffler.Dq keytab . 229692eebe0SSam LefflerThis table records a separate node table reference that can be fetched 230692eebe0SSam Lefflerwithout any locking using the table index. 231692eebe0SSam LefflerThis logic is handled with the 232692eebe0SSam Leffler.Fn ieee80211_find_rxnode_withkey 233692eebe0SSam Lefflercall: if a keytab entry is found using the specified index then it is 234692eebe0SSam Lefflerreturned directly; otherwise a normal lookup is done and the keytab 235692eebe0SSam Lefflerentry is written using the specified index. 236692eebe0SSam LefflerIf the specified index is 237692eebe0SSam Leffler.Dv IEEE80211_KEYIX_NONE 238692eebe0SSam Lefflerthen a normal lookup is done without a table update. 239692eebe0SSam Leffler.Sh SEE ALSO 2404dfbd8ffSEdward Tomasz Napierala.Xr ddb 4 , 241692eebe0SSam Leffler.Xr ieee80211 9 , 242ace02a6dSChristian Brueffer.Xr ieee80211_proto 9 243