summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/ieee80211_node.9 3.html
blob: 5f8c677e988d738fef07486055b77a60904e24a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<table class="head">
  <tr>
    <td class="head-ltitle">IEEE80211_NODE(9)</td>
    <td class="head-vol">Kernel Developer's Manual</td>
    <td class="head-rtitle">IEEE80211_NODE(9)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">ieee80211_node</code> &#x2014;
    <span class="Nd">software 802.11 stack node management functions</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">net80211/ieee80211_var.h</a>&gt;</code></p>
<p class="Pp"><var class="Ft">struct ieee80211_node *</var>
  <br/>
  <code class="Fn">ieee80211_find_rxnode</code>(<var class="Fa">struct
    ieee80211com *</var>, <var class="Fa">const struct ieee80211_frame_min
    *</var>);</p>
<p class="Pp"><var class="Ft">struct ieee80211_node *</var>
  <br/>
  <code class="Fn">ieee80211_find_rxnode_withkey</code>(<var class="Fa">struct
    ieee80211com *</var>, <var class="Fa">const struct ieee80211_frame_min
    *</var>, <var class="Fa">ieee80211_keyix</var>);</p>
<p class="Pp"><var class="Ft">struct ieee80211_node *</var>
  <br/>
  <code class="Fn">ieee80211_ref_node</code>(<var class="Fa" style="white-space: nowrap;">struct
    ieee80211_node *</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">ieee80211_free_node</code>(<var class="Fa" style="white-space: nowrap;">struct
    ieee80211_node *</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">ieee80211_iterate_nodes</code>(<var class="Fa">struct
    ieee80211_node_table *</var>, <var class="Fa">ieee80211_iter_func *f</var>,
    <var class="Fa">void *arg</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">ieee80211_dump_nodes</code>(<var class="Fa">struct
    ieee80211_node_table *</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">ieee80211_dump_node</code>(<var class="Fa">struct
    ieee80211_node *</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">net80211</code> layer that supports 802.11
    device drivers maintains a database of peer stations called the &#x201C;node
    table&#x201D; in the <var class="Vt">ic_sta</var> entry of the
    <var class="Vt">ieee80211com</var> structure. Station mode vaps create an
    entry for the access point the station is associated to. AP mode vaps create
    entries for associated stations. Adhoc and mesh mode vaps create entries for
    neighbor stations. WDS mode vaps create an entry for the peer station.
    Stations for all vaps reside in the same table; each node entry has a
    <var class="Vt">ni_vap</var> field that identifies the vap that created it.
    In some instances an entry is used by multiple vaps (e.g. for dynamic WDS a
    station associated to an ap vap may also be the peer of a WDS vap).</p>
<p class="Pp" id="ieee80211_ref_node">Node table entries are reference counted.
    That is, there is a count of all long term references that determines when
    an entry may be reclaimed. References are held by every in-flight frame sent
    to a station to ensure the entry is not reclaimed while the frame is queued
    or otherwise held by a driver. Routines that lookup a table entry return a
    &#x201C;held reference&#x201D; (i.e. a pointer to a table entry with the
    reference count incremented). The
    <a class="permalink" href="#ieee80211_ref_node"><code class="Fn">ieee80211_ref_node</code></a>()
    call explicitly increments the reference count of a node.
    <a class="permalink" href="#ieee80211_free_node"><code class="Fn" id="ieee80211_free_node">ieee80211_free_node</code></a>()
    decrements the reference count of a node and if the count goes to zero
    reclaims the table entry.</p>
<p class="Pp">The station table and its entries are exposed to drivers in
    several ways. Each frame transmitted to a station includes a reference to
    the associated node in the <var class="Vt">m_pkthdr.rcvif</var> field. This
    reference must be reclaimed by the driver when transmit processing is done.
    For each frame received the driver must lookup the table entry to use in
    dispatching the frame &#x201C;up the stack&#x201D;. This lookup implicitly
    obtains a reference to the table entry and the driver must reclaim the
    reference when frame processing is completed. Otherwise drivers frequently
    inspect the contents of the <var class="Vt">iv_bss</var> node when handling
    state machine changes as important information is maintained in the data
    structure.</p>
<p class="Pp" id="ieee80211_iterate_nodes">The node table is opaque to drivers.
    Entries may be looked up using one of the pre-defined API's or the
    <a class="permalink" href="#ieee80211_iterate_nodes"><code class="Fn">ieee80211_iterate_nodes</code></a>()
    call may be used to iterate through all entries to do per-node processing or
    implement some non-standard search mechanism. Note that
    <code class="Fn">ieee80211_iterate_nodes</code>() is single-threaded
    per-device and the effort processing involved is fairly substantial so it
    should be used carefully.</p>
<p class="Pp" id="ieee80211_dump_node">Two routines are provided to print the
    contents of nodes to the console for debugging:
    <a class="permalink" href="#ieee80211_dump_node"><code class="Fn">ieee80211_dump_node</code></a>()
    displays the contents of a single node while
    <a class="permalink" href="#ieee80211_dump_nodes"><code class="Fn" id="ieee80211_dump_nodes">ieee80211_dump_nodes</code></a>()
    displays the contents of the specified node table. Nodes may also be
    displayed using <a class="Xr">ddb(4)</a> with the &#x201C;show node&#x201D;
    directive and the station node table can be displayed with &#x201C;show
    statab&#x201D;.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DRIVER_PRIVATE_STATE"><a class="permalink" href="#DRIVER_PRIVATE_STATE">DRIVER
  PRIVATE STATE</a></h1>
<p class="Pp">Node data structures may be extended by the driver to include
    driver-private state. This is done by overriding the
    <var class="Vt">ic_node_alloc</var> method used to allocate a node table
    entry. The driver method must allocate a structure that is an extension of
    the <var class="Vt">ieee80211_node</var> structure. For example the
    <a class="Xr">iwi(4)</a> driver defines a private node structure as:</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct iwi_node {
        struct ieee80211_node   in_node;
	int                     in_station;
};</pre>
</div>
<p class="Pp">and then provides a private allocation routine that does this:</p>
<div class="Bd Pp Bd-indent Li">
<pre>static struct ieee80211_node *
iwi_node_alloc(struct ieee80211vap *vap,
    const uint8_t mac[IEEE80211_ADDR_LEN])
{
        struct iwi_node *in;

        in = malloc(sizeof(struct iwi_node), M_80211_NODE,
		M_NOWAIT | M_ZERO);
        if (in == NULL)
                return NULL;
        in-&gt;in_station = -1;
        return &amp;in-&gt;in_node;
}</pre>
</div>
<p class="Pp">Note that when reclaiming a node allocated by the driver the
    &#x201C;parent method&#x201D; must be called to ensure
    <code class="Nm">net80211</code> state is reclaimed; for example:</p>
<div class="Bd Pp Bd-indent Li">
<pre>static void
iwi_node_free(struct ieee80211_node *ni)
{
        struct ieee80211com *ic = ni-&gt;ni_ic;
        struct iwi_softc *sc = ic-&gt;ic_ifp-&gt;if_softc;
        struct iwi_node *in = (struct iwi_node *)ni;

        if (in-&gt;in_station != -1)
                free_unr(sc-&gt;sc_unr, in-&gt;in_station);
        sc-&gt;sc_node_free(ni);	/* invoke net80211 free handler */
}</pre>
</div>
<p class="Pp">Beware that care must be taken to avoid holding references that
    might cause nodes from being reclaimed. <code class="Nm">net80211</code>
    will reclaim a node when the last reference is reclaimed in its data
    structures. However if a driver holds additional references then
    <code class="Nm">net80211</code> will not recognize this and table entries
    will not be reclaimed. Such references should not be needed if the driver
    overrides the <var class="Vt">ic_node_cleanup</var> and/or
    <var class="Vt">ic_node_free</var> methods.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="KEY_TABLE_SUPPORT"><a class="permalink" href="#KEY_TABLE_SUPPORT">KEY
  TABLE SUPPORT</a></h1>
<p class="Pp">Node table lookups are typically done using a hash of the
    stations' mac address. When receiving frames this is sufficient to find the
    node table entry for the transmitter. But some devices also identify the
    sending station in the device state received with each frame and this data
    can be used to optimize lookups on receive using a companion table called
    the &#x201C;keytab&#x201D;. This table records a separate node table
    reference that can be fetched without any locking using the table index.
    This logic is handled with the
    <a class="permalink" href="#ieee80211_find_rxnode_withkey"><code class="Fn" id="ieee80211_find_rxnode_withkey">ieee80211_find_rxnode_withkey</code></a>()
    call: if a keytab entry is found using the specified index then it is
    returned directly; otherwise a normal lookup is done and the keytab entry is
    written using the specified index. If the specified index is
    <code class="Dv">IEEE80211_KEYIX_NONE</code> then a normal lookup is done
    without a table update.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">ddb(4)</a>, <a class="Xr">ieee80211(9)</a>,
    <a class="Xr">ieee80211_proto(9)</a></p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">October 2, 2023</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>