xref: /titanic_50/usr/src/uts/common/io/net80211/net80211_node.c (revision ab4a9beb2e4d596be0b3288c7d92919e27781b57)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2001 Atsushi Onoe
8  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * Alternatively, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") version 2 as published by the Free
24  * Software Foundation.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #pragma ident	"%Z%%M%	%I%	%E% SMI"
39 
40 /*
41  * Node management routines
42  */
43 
44 #include "net80211_impl.h"
45 
46 static ieee80211_node_t *ieee80211_node_alloc(ieee80211com_t *);
47 static void ieee80211_node_cleanup(ieee80211_node_t *);
48 static void ieee80211_node_free(ieee80211_node_t *);
49 static uint8_t ieee80211_node_getrssi(const ieee80211_node_t *);
50 static void ieee80211_setup_node(ieee80211com_t *, ieee80211_node_table_t *,
51     ieee80211_node_t *, const uint8_t *);
52 static void ieee80211_node_reclaim(ieee80211_node_table_t *,
53     ieee80211_node_t *);
54 static void ieee80211_free_node_locked(ieee80211_node_t *);
55 static void ieee80211_free_allnodes(ieee80211_node_table_t *);
56 static void ieee80211_node_leave(ieee80211com_t *, ieee80211_node_t *);
57 static void ieee80211_timeout_scan_candidates(ieee80211_node_table_t *);
58 static void ieee80211_timeout_stations(ieee80211_node_table_t *);
59 static void ieee80211_node_table_init(ieee80211com_t *,
60     ieee80211_node_table_t *, const char *, int, int,
61     void (*timeout)(ieee80211_node_table_t *));
62 static void ieee80211_node_table_cleanup(ieee80211_node_table_t *);
63 
64 /*
65  * association failures before ignored
66  * The failure may be caused by the response frame is lost for
67  * environmental reason. So Try associate more than once before
68  * ignore the node
69  */
70 #define	IEEE80211_STA_FAILS_MAX	2
71 
72 /*
73  * Initialize node database management callbacks for the interface.
74  * This function is called by ieee80211_attach(). These callback
75  * functions may be overridden in special circumstances, as long as
76  * as this is done after calling ieee80211_attach() and prior to any
77  * other call which may allocate a node
78  */
79 void
80 ieee80211_node_attach(ieee80211com_t *ic)
81 {
82 	struct ieee80211_impl *im = ic->ic_private;
83 
84 	ic->ic_node_alloc = ieee80211_node_alloc;
85 	ic->ic_node_free = ieee80211_node_free;
86 	ic->ic_node_cleanup = ieee80211_node_cleanup;
87 	ic->ic_node_getrssi = ieee80211_node_getrssi;
88 
89 	/* default station inactivity timer setings */
90 	im->im_inact_init = IEEE80211_INACT_INIT;
91 	im->im_inact_assoc = IEEE80211_INACT_ASSOC;
92 	im->im_inact_run = IEEE80211_INACT_RUN;
93 	im->im_inact_probe = IEEE80211_INACT_PROBE;
94 }
95 
96 /*
97  * Initialize node databases and the ic_bss node element.
98  */
99 void
100 ieee80211_node_lateattach(ieee80211com_t *ic)
101 {
102 	/*
103 	 * Calculate ic_tim_bitmap size in bytes
104 	 * IEEE80211_AID_MAX defines maximum bits in ic_tim_bitmap
105 	 */
106 	ic->ic_tim_len = howmany(IEEE80211_AID_MAX, 8) * sizeof (uint8_t);
107 
108 	ieee80211_node_table_init(ic, &ic->ic_sta, "station",
109 	    IEEE80211_INACT_INIT, IEEE80211_WEP_NKID,
110 	    ieee80211_timeout_stations);
111 	ieee80211_node_table_init(ic, &ic->ic_scan, "scan",
112 	    IEEE80211_INACT_SCAN, 0, ieee80211_timeout_scan_candidates);
113 
114 	ieee80211_reset_bss(ic);
115 }
116 
117 /*
118  * Destroy all node databases and is usually called during device detach
119  */
120 void
121 ieee80211_node_detach(ieee80211com_t *ic)
122 {
123 	/* Node Detach */
124 	if (ic->ic_bss != NULL) {
125 		ieee80211_free_node(ic->ic_bss);
126 		ic->ic_bss = NULL;
127 	}
128 	ieee80211_node_table_cleanup(&ic->ic_scan);
129 	ieee80211_node_table_cleanup(&ic->ic_sta);
130 }
131 
132 /*
133  * Increase a node's reference count
134  *
135  * Return pointer to the node
136  */
137 ieee80211_node_t *
138 ieee80211_ref_node(ieee80211_node_t *in)
139 {
140 	ieee80211_node_incref(in);
141 	return (in);
142 }
143 
144 /*
145  * Dexrease a node's reference count
146  */
147 void
148 ieee80211_unref_node(ieee80211_node_t **in)
149 {
150 	ieee80211_node_decref(*in);
151 	*in = NULL;			/* guard against use */
152 }
153 
154 /*
155  * Mark ports authorized for data traffic. This function is usually
156  * used by 802.1x authenticator.
157  */
158 void
159 ieee80211_node_authorize(ieee80211_node_t *in)
160 {
161 	ieee80211_impl_t *im = in->in_ic->ic_private;
162 
163 	in->in_flags |= IEEE80211_NODE_AUTH;
164 	in->in_inact_reload = im->im_inact_run;
165 }
166 
167 /*
168  * Mark ports unauthorized for data traffic. This function is usually
169  * used by 802.1x authenticator.
170  */
171 void
172 ieee80211_node_unauthorize(ieee80211_node_t *in)
173 {
174 	in->in_flags &= ~IEEE80211_NODE_AUTH;
175 }
176 
177 /*
178  * Set/change the channel.  The rate set is also updated as
179  * to insure a consistent view by drivers.
180  */
181 static void
182 ieee80211_node_setchan(ieee80211com_t *ic, ieee80211_node_t *in,
183     struct ieee80211_channel *chan)
184 {
185 	if (chan == IEEE80211_CHAN_ANYC)
186 		chan = ic->ic_curchan;
187 	in->in_chan = chan;
188 	in->in_rates = ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
189 }
190 
191 /*
192  * Initialize the channel set to scan based on the available channels
193  * and the current PHY mode.
194  */
195 static void
196 ieee80211_reset_scan(ieee80211com_t *ic)
197 {
198 	ieee80211_impl_t	*im = ic->ic_private;
199 
200 	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
201 		(void) memset(im->im_chan_scan, 0, sizeof (im->im_chan_scan));
202 		ieee80211_setbit(im->im_chan_scan,
203 		    ieee80211_chan2ieee(ic, ic->ic_des_chan));
204 	} else {
205 		bcopy(ic->ic_chan_active, im->im_chan_scan,
206 		    sizeof (ic->ic_chan_active));
207 	}
208 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_reset_scan(): "
209 	    "start chan %u\n", ieee80211_chan2ieee(ic, ic->ic_curchan));
210 }
211 
212 /*
213  * Begin an active scan. Initialize the node cache. The scan
214  * begins on the next radio channel by calling ieee80211_next_scan().
215  * The actual scanning is not automated. The driver itself
216  * only handles setting the radio frequency and stepping through
217  * the channels.
218  */
219 void
220 ieee80211_begin_scan(ieee80211com_t *ic, boolean_t reset)
221 {
222 	IEEE80211_LOCK(ic);
223 
224 	if (ic->ic_opmode != IEEE80211_M_HOSTAP)
225 		ic->ic_flags |= IEEE80211_F_ASCAN;
226 	ieee80211_dbg(IEEE80211_MSG_SCAN,
227 	    "begin %s scan in %s mode on channel %u\n",
228 	    (ic->ic_flags & IEEE80211_F_ASCAN) ?  "active" : "passive",
229 	    ieee80211_phymode_name[ic->ic_curmode],
230 	    ieee80211_chan2ieee(ic, ic->ic_curchan));
231 
232 	/*
233 	 * Clear scan state and flush any previously seen AP's.
234 	 */
235 	ieee80211_reset_scan(ic);
236 	if (reset)
237 		ieee80211_free_allnodes(&ic->ic_scan);
238 
239 	ic->ic_flags |= IEEE80211_F_SCAN;
240 	IEEE80211_UNLOCK(ic);
241 
242 	/* Scan the next channel. */
243 	ieee80211_next_scan(ic);
244 }
245 
246 /*
247  * Switch to the next channel marked for scanning.
248  * A driver is expected to first call ieee80211_begin_scan(),
249  * to initialize the node cache, then set the radio channel
250  * on the device. And then after a certain time has elapsed,
251  * call ieee80211_next_scan() to move to the next channel.
252  * Typically, a timeout routine is used to automate this process.
253  */
254 void
255 ieee80211_next_scan(ieee80211com_t *ic)
256 {
257 	ieee80211_impl_t *im = ic->ic_private;
258 	struct ieee80211_channel *chan;
259 
260 	IEEE80211_LOCK(ic);
261 	/*
262 	 * Insure any previous mgt frame timeouts don't fire.
263 	 * This assumes the driver does the right thing in
264 	 * flushing anything queued in the driver and below.
265 	 */
266 	im->im_mgt_timer = 0;
267 
268 	chan = ic->ic_curchan;
269 	do {
270 		if (++chan > &ic->ic_sup_channels[IEEE80211_CHAN_MAX])
271 			chan = &ic->ic_sup_channels[0];
272 		if (ieee80211_isset(im->im_chan_scan,
273 		    ieee80211_chan2ieee(ic, chan))) {
274 			ieee80211_clrbit(im->im_chan_scan,
275 			    ieee80211_chan2ieee(ic, chan));
276 			ieee80211_dbg(IEEE80211_MSG_SCAN,
277 			    "ieee80211_next_scan: chan %d->%d\n",
278 			    ieee80211_chan2ieee(ic, ic->ic_curchan),
279 			    ieee80211_chan2ieee(ic, chan));
280 			ic->ic_curchan = chan;
281 			/*
282 			 * drivers should do this as needed,
283 			 * for now maintain compatibility
284 			 */
285 			ic->ic_bss->in_rates =
286 			    ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
287 			IEEE80211_UNLOCK(ic);
288 			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
289 			return;
290 		}
291 	} while (chan != ic->ic_curchan);
292 	IEEE80211_UNLOCK(ic);
293 	ieee80211_end_scan(ic);
294 }
295 
296 /*
297  * Copy useful state from node obss into nbss.
298  */
299 static void
300 ieee80211_copy_bss(ieee80211_node_t *nbss, const ieee80211_node_t *obss)
301 {
302 	/* propagate useful state */
303 	nbss->in_authmode = obss->in_authmode;
304 	nbss->in_txpower = obss->in_txpower;
305 	nbss->in_vlan = obss->in_vlan;
306 }
307 
308 /*
309  * Setup the net80211 specific portion of an interface's softc, ic,
310  * for use in IBSS mode
311  */
312 void
313 ieee80211_create_ibss(ieee80211com_t *ic, struct ieee80211_channel *chan)
314 {
315 	ieee80211_impl_t *im = ic->ic_private;
316 	ieee80211_node_table_t *nt;
317 	ieee80211_node_t *in;
318 
319 	IEEE80211_LOCK_ASSERT(ic);
320 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_create_ibss: "
321 	    "creating ibss\n");
322 
323 	/*
324 	 * Create the station/neighbor table.  Note that for adhoc
325 	 * mode we make the initial inactivity timer longer since
326 	 * we create nodes only through discovery and they typically
327 	 * are long-lived associations.
328 	 */
329 	nt = &ic->ic_sta;
330 	IEEE80211_NODE_LOCK(nt);
331 	nt->nt_name = "neighbor";
332 	nt->nt_inact_init = im->im_inact_run;
333 	IEEE80211_NODE_UNLOCK(nt);
334 
335 	in = ieee80211_alloc_node(ic, &ic->ic_sta, ic->ic_macaddr);
336 	if (in == NULL) {
337 		ieee80211_err("ieee80211_create_ibss(): alloc node failed\n");
338 		return;
339 	}
340 	IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_macaddr);
341 	in->in_esslen = ic->ic_des_esslen;
342 	(void) memcpy(in->in_essid, ic->ic_des_essid, in->in_esslen);
343 	ieee80211_copy_bss(in, ic->ic_bss);
344 	in->in_intval = ic->ic_bintval;
345 	if (ic->ic_flags & IEEE80211_F_PRIVACY)
346 		in->in_capinfo |= IEEE80211_CAPINFO_PRIVACY;
347 	if (ic->ic_phytype == IEEE80211_T_FH) {
348 		in->in_fhdwell = 200;
349 		in->in_fhindex = 1;
350 	}
351 	switch (ic->ic_opmode) {
352 	case IEEE80211_M_IBSS:
353 		ic->ic_flags |= IEEE80211_F_SIBSS;
354 		in->in_capinfo |= IEEE80211_CAPINFO_IBSS;
355 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
356 			IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_des_bssid);
357 		else
358 			in->in_bssid[0] |= 0x02;	/* local bit for IBSS */
359 		break;
360 	case IEEE80211_M_AHDEMO:
361 		if (ic->ic_flags & IEEE80211_F_DESBSSID)
362 			IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_des_bssid);
363 		else
364 			(void) memset(in->in_bssid, 0, IEEE80211_ADDR_LEN);
365 		break;
366 	default:
367 		ieee80211_err("ieee80211_create_ibss(): "
368 		    "wrong opmode %u to creat IBSS, abort\n",
369 		    ic->ic_opmode);
370 		ieee80211_free_node(in);
371 		return;
372 	}
373 
374 	/*
375 	 * Fix the channel and related attributes.
376 	 */
377 	ieee80211_node_setchan(ic, in, chan);
378 	ic->ic_curchan = chan;
379 	ic->ic_curmode = ieee80211_chan2mode(ic, chan);
380 	/*
381 	 * Do mode-specific rate setup.
382 	 */
383 	ieee80211_setbasicrates(&in->in_rates, ic->ic_curmode);
384 	IEEE80211_UNLOCK(ic);
385 	ieee80211_sta_join(ic, ieee80211_ref_node(in));
386 	IEEE80211_LOCK(ic);
387 }
388 
389 void
390 ieee80211_reset_bss(ieee80211com_t *ic)
391 {
392 	ieee80211_node_t *in;
393 	ieee80211_node_t *obss;
394 
395 	in = ieee80211_alloc_node(ic, &ic->ic_scan, ic->ic_macaddr);
396 	ASSERT(in != NULL);
397 	obss = ic->ic_bss;
398 	ic->ic_bss = ieee80211_ref_node(in);
399 	if (obss != NULL) {
400 		ieee80211_copy_bss(in, obss);
401 		in->in_intval = ic->ic_bintval;
402 		ieee80211_free_node(obss);
403 	}
404 }
405 
406 static int
407 ieee80211_match_bss(ieee80211com_t *ic, ieee80211_node_t *in)
408 {
409 	uint8_t rate;
410 	int fail;
411 
412 	fail = 0;
413 	if (ieee80211_isclr(ic->ic_chan_active,
414 	    ieee80211_chan2ieee(ic, in->in_chan))) {
415 		fail |= IEEE80211_BADCHAN;
416 	}
417 	if (ic->ic_des_chan != IEEE80211_CHAN_ANYC &&
418 	    in->in_chan != ic->ic_des_chan) {
419 		fail |= IEEE80211_BADCHAN;
420 	}
421 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
422 		if (!(in->in_capinfo & IEEE80211_CAPINFO_IBSS))
423 			fail |= IEEE80211_BADOPMODE;
424 	} else {
425 		if (!(in->in_capinfo & IEEE80211_CAPINFO_ESS))
426 			fail |= IEEE80211_BADOPMODE;
427 	}
428 	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
429 		if (!(in->in_capinfo & IEEE80211_CAPINFO_PRIVACY))
430 			fail |= IEEE80211_BADPRIVACY;
431 	} else {
432 		if (in->in_capinfo & IEEE80211_CAPINFO_PRIVACY)
433 			fail |= IEEE80211_BADPRIVACY;
434 	}
435 	rate = ieee80211_fix_rate(in, IEEE80211_F_DONEGO | IEEE80211_F_DOFRATE);
436 	if (rate & IEEE80211_RATE_BASIC)
437 		fail |= IEEE80211_BADRATE;
438 	if (ic->ic_des_esslen != 0 &&
439 	    (in->in_esslen != ic->ic_des_esslen ||
440 	    memcmp(in->in_essid, ic->ic_des_essid, ic->ic_des_esslen) != 0)) {
441 		fail |= IEEE80211_BADESSID;
442 	}
443 	if ((ic->ic_flags & IEEE80211_F_DESBSSID) &&
444 	    !IEEE80211_ADDR_EQ(ic->ic_des_bssid, in->in_bssid)) {
445 		fail |= IEEE80211_BADBSSID;
446 	}
447 	if (in->in_fails >= IEEE80211_STA_FAILS_MAX)
448 		fail |= IEEE80211_NODEFAIL;
449 
450 	return (fail);
451 }
452 
453 #define	IEEE80211_MAXRATE(_rs) \
454 	((_rs).ir_rates[(_rs).ir_nrates - 1] & IEEE80211_RATE_VAL)
455 
456 /*
457  * Compare the capabilities of node a with node b and decide which is
458  * more desirable (return b if b is considered better than a).  Note
459  * that we assume compatibility/usability has already been checked
460  * so we don't need to (e.g. validate whether privacy is supported).
461  * Used to select the best scan candidate for association in a BSS.
462  *
463  * Return desired node
464  */
465 static ieee80211_node_t *
466 ieee80211_node_compare(ieee80211com_t *ic, ieee80211_node_t *a,
467     ieee80211_node_t *b)
468 {
469 	uint8_t maxa;
470 	uint8_t maxb;
471 	uint8_t rssia;
472 	uint8_t rssib;
473 
474 	/* privacy support preferred */
475 	if ((a->in_capinfo & IEEE80211_CAPINFO_PRIVACY) &&
476 	    !(b->in_capinfo & IEEE80211_CAPINFO_PRIVACY)) {
477 		return (a);
478 	}
479 	if (!(a->in_capinfo & IEEE80211_CAPINFO_PRIVACY) &&
480 	    (b->in_capinfo & IEEE80211_CAPINFO_PRIVACY)) {
481 		return (b);
482 	}
483 
484 	/* compare count of previous failures */
485 	if (b->in_fails != a->in_fails)
486 		return ((a->in_fails > b->in_fails) ? b : a);
487 
488 	rssia = ic->ic_node_getrssi(a);
489 	rssib = ic->ic_node_getrssi(b);
490 	if (ABS(rssib - rssia) < IEEE80211_RSSI_CMP_THRESHOLD) {
491 		/* best/max rate preferred if signal level close enough */
492 		maxa = IEEE80211_MAXRATE(a->in_rates);
493 		maxb = IEEE80211_MAXRATE(b->in_rates);
494 		if (maxa != maxb)
495 			return ((maxb > maxa) ? b : a);
496 		/* for now just prefer 5Ghz band to all other bands */
497 		if (IEEE80211_IS_CHAN_5GHZ(a->in_chan) &&
498 		    !IEEE80211_IS_CHAN_5GHZ(b->in_chan)) {
499 			return (a);
500 		}
501 		if (!IEEE80211_IS_CHAN_5GHZ(a->in_chan) &&
502 		    IEEE80211_IS_CHAN_5GHZ(b->in_chan)) {
503 			return (b);
504 		}
505 	}
506 	/* all things being equal, compare signal level */
507 	return ((rssib > rssia) ? b : a);
508 }
509 
510 /*
511  * Mark an ongoing scan stopped.
512  */
513 void
514 ieee80211_cancel_scan(ieee80211com_t *ic)
515 {
516 	IEEE80211_LOCK(ic);
517 	ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_cancel_scan()"
518 	    "end %s scan\n",
519 	    (ic->ic_flags & IEEE80211_F_ASCAN) ?  "active" : "passive");
520 	ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN);
521 	cv_broadcast(&((ieee80211_impl_t *)ic->ic_private)->im_scan_cv);
522 	IEEE80211_UNLOCK(ic);
523 }
524 
525 /*
526  * Complete a scan of potential channels. It is called by
527  * ieee80211_next_scan() when the state machine has performed
528  * a full cycle of scaning on all available radio channels.
529  * ieee80211_end_scan() will inspect the node cache for suitable
530  * APs found during scaning, and associate with one, should
531  * the parameters of the node match those of the configuration
532  * requested from userland.
533  */
534 void
535 ieee80211_end_scan(ieee80211com_t *ic)
536 {
537 	ieee80211_node_table_t *nt = &ic->ic_scan;
538 	ieee80211_node_t *in;
539 	ieee80211_node_t *selbs;
540 
541 	ieee80211_cancel_scan(ic);
542 	/* notify SCAN done */
543 	ieee80211_notify(ic, EVENT_SCAN_RESULTS);
544 	IEEE80211_LOCK(ic);
545 
546 	/*
547 	 * Automatic sequencing; look for a candidate and
548 	 * if found join the network.
549 	 */
550 	/* NB: unlocked read should be ok */
551 	in = list_head(&nt->nt_node);
552 	if (in == NULL && (ic->ic_flags & IEEE80211_F_WPA) == 0) {
553 		ieee80211_dbg(IEEE80211_MSG_SCAN, "ieee80211_end_scan: "
554 		    "no scan candidate\n");
555 	notfound:
556 		if (ic->ic_opmode == IEEE80211_M_IBSS &&
557 		    (ic->ic_flags & IEEE80211_F_IBSSON) &&
558 		    ic->ic_des_esslen != 0) {
559 			ieee80211_create_ibss(ic, ic->ic_ibss_chan);
560 			IEEE80211_UNLOCK(ic);
561 			return;
562 		}
563 
564 		/*
565 		 * Reset the list of channels to scan and start again.
566 		 */
567 		ieee80211_reset_scan(ic);
568 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
569 		IEEE80211_UNLOCK(ic);
570 
571 		ieee80211_next_scan(ic);
572 		return;
573 	}
574 
575 	if (ic->ic_flags & IEEE80211_F_SCANONLY ||
576 	    ic->ic_flags & IEEE80211_F_WPA) {	/* scan only */
577 		ic->ic_flags &= ~IEEE80211_F_SCANONLY;
578 		IEEE80211_UNLOCK(ic);
579 		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
580 		return;
581 	}
582 
583 	selbs = NULL;
584 	IEEE80211_NODE_LOCK(nt);
585 	while (in != NULL) {
586 		if (in->in_fails >= IEEE80211_STA_FAILS_MAX) {
587 			ieee80211_node_t *tmpin = in;
588 
589 			/*
590 			 * The configuration of the access points may change
591 			 * during my scan.  So delete the entry for the AP
592 			 * and retry to associate if there is another beacon.
593 			 */
594 			in = list_next(&nt->nt_node, tmpin);
595 			ieee80211_node_reclaim(nt, tmpin);
596 			continue;
597 		}
598 		/*
599 		 * It's possible at some special moments, the in_chan will
600 		 * be none. Need to skip the null node.
601 		 */
602 		if (in->in_chan == IEEE80211_CHAN_ANYC) {
603 			in = list_next(&nt->nt_node, in);
604 			continue;
605 		}
606 		if (ieee80211_match_bss(ic, in) == 0) {
607 			if (selbs == NULL)
608 				selbs = in;
609 			else
610 				selbs = ieee80211_node_compare(ic, selbs, in);
611 		}
612 		in = list_next(&nt->nt_node, in);
613 	}
614 	if (selbs != NULL)	/* grab ref while dropping lock */
615 		(void) ieee80211_ref_node(selbs);
616 	IEEE80211_NODE_UNLOCK(nt);
617 	if (selbs == NULL)
618 		goto notfound;
619 	IEEE80211_UNLOCK(ic);
620 	ieee80211_sta_join(ic, selbs);
621 }
622 
623 
624 /*
625  * Handle 802.11 ad hoc network merge.  The convention, set by the
626  * Wireless Ethernet Compatibility Alliance (WECA), is that an 802.11
627  * station will change its BSSID to match the "oldest" 802.11 ad hoc
628  * network, on the same channel, that has the station's desired SSID.
629  * The "oldest" 802.11 network sends beacons with the greatest TSF
630  * timestamp.
631  * The caller is assumed to validate TSF's before attempting a merge.
632  *
633  * Return B_TRUE if the BSSID changed, B_FALSE otherwise.
634  */
635 boolean_t
636 ieee80211_ibss_merge(ieee80211_node_t *in)
637 {
638 	ieee80211com_t *ic = in->in_ic;
639 
640 	if (in == ic->ic_bss ||
641 	    IEEE80211_ADDR_EQ(in->in_bssid, ic->ic_bss->in_bssid)) {
642 		/* unchanged, nothing to do */
643 		return (B_FALSE);
644 	}
645 	if (ieee80211_match_bss(ic, in) != 0) {	/* capabilities mismatch */
646 		ieee80211_dbg(IEEE80211_MSG_ASSOC, "ieee80211_ibss_merge: "
647 		    " merge failed, capabilities mismatch\n");
648 		return (B_FALSE);
649 	}
650 	ieee80211_dbg(IEEE80211_MSG_ASSOC, "ieee80211_ibss_merge: "
651 	    "new bssid %s: %s preamble, %s slot time%s\n",
652 	    ieee80211_macaddr_sprintf(in->in_bssid),
653 	    (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long",
654 	    (ic->ic_flags & IEEE80211_F_SHSLOT) ? "short" : "long",
655 	    (ic->ic_flags&IEEE80211_F_USEPROT) ? ", protection" : "");
656 	ieee80211_sta_join(ic, ieee80211_ref_node(in));
657 	return (B_TRUE);
658 }
659 
660 /*
661  * Join the specified IBSS/BSS network.  The node is assumed to
662  * be passed in with a held reference.
663  */
664 void
665 ieee80211_sta_join(ieee80211com_t *ic, ieee80211_node_t *selbs)
666 {
667 	ieee80211_impl_t *im = ic->ic_private;
668 	ieee80211_node_t *obss;
669 
670 	IEEE80211_LOCK(ic);
671 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
672 		ieee80211_node_table_t *nt;
673 
674 		/*
675 		 * Delete unusable rates; we've already checked
676 		 * that the negotiated rate set is acceptable.
677 		 */
678 		(void) ieee80211_fix_rate(selbs, IEEE80211_F_DODEL);
679 		/*
680 		 * Fillin the neighbor table
681 		 */
682 		nt = &ic->ic_sta;
683 		IEEE80211_NODE_LOCK(nt);
684 		nt->nt_name = "neighbor";
685 		nt->nt_inact_init = im->im_inact_run;
686 		IEEE80211_NODE_UNLOCK(nt);
687 	}
688 
689 	/*
690 	 * Committed to selbs, setup state.
691 	 */
692 	obss = ic->ic_bss;
693 	ic->ic_bss = selbs;	/* caller assumed to bump refcnt */
694 	if (obss != NULL) {
695 		ieee80211_copy_bss(selbs, obss);
696 		ieee80211_free_node(obss);
697 	}
698 	ic->ic_curmode = ieee80211_chan2mode(ic, selbs->in_chan);
699 	ic->ic_curchan = selbs->in_chan;
700 	ic->ic_phytype = selbs->in_phytype;
701 	/*
702 	 * Set the erp state (mostly the slot time) to deal with
703 	 * the auto-select case; this should be redundant if the
704 	 * mode is locked.
705 	 */
706 	ieee80211_reset_erp(ic);
707 
708 	IEEE80211_UNLOCK(ic);
709 	if (ic->ic_opmode == IEEE80211_M_STA)
710 		ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
711 	else
712 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
713 }
714 
715 /*
716  * Leave the specified IBSS/BSS network.  The node is assumed to
717  * be passed in with a held reference.
718  */
719 void
720 ieee80211_sta_leave(ieee80211com_t *ic, ieee80211_node_t *in)
721 {
722 	IEEE80211_LOCK(ic);
723 	ic->ic_node_cleanup(in);
724 	ieee80211_notify_node_leave(ic, in);
725 	IEEE80211_UNLOCK(ic);
726 }
727 
728 /*
729  * Allocate a node. This is the default callback function for
730  * ic_node_alloc. This function may be overridden by the driver
731  * to allocate device specific node structure.
732  */
733 /* ARGSUSED */
734 static ieee80211_node_t *
735 ieee80211_node_alloc(ieee80211com_t *ic)
736 {
737 	return (kmem_zalloc(sizeof (ieee80211_node_t), KM_SLEEP));
738 }
739 
740 /*
741  * Cleanup a node, free any memory associated with the node.
742  * This is the default callback function for ic_node_cleanup
743  * and may be overridden by the driver.
744  */
745 static void
746 ieee80211_node_cleanup(ieee80211_node_t *in)
747 {
748 	in->in_associd = 0;
749 	in->in_rssi = 0;
750 	in->in_rstamp = 0;
751 	if (in->in_challenge != NULL) {
752 		kmem_free(in->in_challenge, IEEE80211_CHALLENGE_LEN);
753 		in->in_challenge = NULL;
754 	}
755 	if (in->in_rxfrag != NULL) {
756 		freemsg(in->in_rxfrag);
757 		in->in_rxfrag = NULL;
758 	}
759 }
760 
761 /*
762  * Free a node. This is the default callback function for ic_node_free
763  * and may be overridden by the driver to free memory used by device
764  * specific node structure
765  */
766 static void
767 ieee80211_node_free(ieee80211_node_t *in)
768 {
769 	ieee80211com_t *ic = in->in_ic;
770 
771 	ic->ic_node_cleanup(in);
772 	if (in->in_wpa_ie != NULL)
773 		ieee80211_free(in->in_wpa_ie);
774 	kmem_free(in, sizeof (ieee80211_node_t));
775 }
776 
777 /*
778  * Get a node current RSSI value. This is the default callback function
779  * for ic_node_getrssi and may be overridden by the driver to provide
780  * device specific RSSI calculation algorithm.
781  */
782 static uint8_t
783 ieee80211_node_getrssi(const ieee80211_node_t *in)
784 {
785 	return (in->in_rssi);
786 }
787 
788 /* Free fragment if not needed anymore */
789 static void
790 node_cleanfrag(ieee80211_node_t *in)
791 {
792 	clock_t ticks;
793 
794 	ticks = ddi_get_lbolt();
795 	if (in->in_rxfrag != NULL && ticks > (in->in_rxfragstamp + hz)) {
796 		freemsg(in->in_rxfrag);
797 		in->in_rxfrag = NULL;
798 	}
799 }
800 
801 /*
802  * Setup a node. Initialize the node with specified macaddr. Associate
803  * with the interface softc, ic, and add it to the specified node
804  * database.
805  */
806 static void
807 ieee80211_setup_node(ieee80211com_t *ic, ieee80211_node_table_t *nt,
808     ieee80211_node_t *in, const uint8_t *macaddr)
809 {
810 	int32_t hash;
811 
812 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_setup_node(): "
813 	    "%p<%s> in %s table\n", in,
814 	    ieee80211_macaddr_sprintf(macaddr),
815 	    (nt != NULL) ? nt->nt_name : "NULL");
816 
817 	in->in_ic = ic;
818 	IEEE80211_ADDR_COPY(in->in_macaddr, macaddr);
819 	hash = ieee80211_node_hash(macaddr);
820 	ieee80211_node_initref(in);		/* mark referenced */
821 	in->in_authmode = IEEE80211_AUTH_OPEN;
822 	in->in_txpower = ic->ic_txpowlimit;	/* max power */
823 	in->in_chan = IEEE80211_CHAN_ANYC;
824 	in->in_inact_reload = IEEE80211_INACT_INIT;
825 	in->in_inact = in->in_inact_reload;
826 	ieee80211_crypto_resetkey(ic, &in->in_ucastkey, IEEE80211_KEYIX_NONE);
827 
828 	if (nt != NULL) {
829 		IEEE80211_NODE_LOCK(nt);
830 		list_insert_tail(&nt->nt_node, in);
831 		list_insert_tail(&nt->nt_hash[hash], in);
832 		in->in_table = nt;
833 		in->in_inact_reload = nt->nt_inact_init;
834 		IEEE80211_NODE_UNLOCK(nt);
835 	}
836 }
837 
838 /*
839  * Allocates and initialize a node with specified MAC address.
840  * Associate the node with the interface ic. If the allocation
841  * is successful, the node structure is initialized by
842  * ieee80211_setup_node(); otherwise, NULL is returned
843  */
844 ieee80211_node_t *
845 ieee80211_alloc_node(ieee80211com_t *ic, ieee80211_node_table_t *nt,
846     const uint8_t *macaddr)
847 {
848 	ieee80211_node_t *in;
849 
850 	in = ic->ic_node_alloc(ic);
851 	if (in != NULL)
852 		ieee80211_setup_node(ic, nt, in, macaddr);
853 	return (in);
854 }
855 
856 /*
857  * Craft a temporary node suitable for sending a management frame
858  * to the specified station.  We craft only as much state as we
859  * need to do the work since the node will be immediately reclaimed
860  * once the send completes.
861  */
862 ieee80211_node_t *
863 ieee80211_tmp_node(ieee80211com_t *ic, const uint8_t *macaddr)
864 {
865 	ieee80211_node_t *in;
866 
867 	in = ic->ic_node_alloc(ic);
868 	if (in != NULL) {
869 		ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_tmp_node: "
870 		    "%p<%s>\n", in, ieee80211_macaddr_sprintf(macaddr));
871 
872 		IEEE80211_ADDR_COPY(in->in_macaddr, macaddr);
873 		IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_bss->in_bssid);
874 		ieee80211_node_initref(in);		/* mark referenced */
875 		in->in_txpower = ic->ic_bss->in_txpower;
876 		/* NB: required by ieee80211_fix_rate */
877 		ieee80211_node_setchan(ic, in, ic->ic_bss->in_chan);
878 		ieee80211_crypto_resetkey(ic, &in->in_ucastkey,
879 		    IEEE80211_KEYIX_NONE);
880 
881 		in->in_table = NULL;		/* NB: pedantic */
882 		in->in_ic = ic;
883 	}
884 
885 	return (in);
886 }
887 
888 /*
889  * ieee80211_dup_bss() is similar to ieee80211_alloc_node(),
890  * but is instead used to create a node database entry for
891  * the specified BSSID. If the allocation is successful, the
892  * node is initialized,  otherwise, NULL is returned.
893  */
894 ieee80211_node_t *
895 ieee80211_dup_bss(ieee80211_node_table_t *nt, const uint8_t *macaddr)
896 {
897 	ieee80211com_t *ic = nt->nt_ic;
898 	ieee80211_node_t *in;
899 
900 	in = ieee80211_alloc_node(ic, nt, macaddr);
901 	if (in != NULL) {
902 		/*
903 		 * Inherit from ic_bss.
904 		 */
905 		ieee80211_copy_bss(in, ic->ic_bss);
906 		IEEE80211_ADDR_COPY(in->in_bssid, ic->ic_bss->in_bssid);
907 		ieee80211_node_setchan(ic, in, ic->ic_bss->in_chan);
908 	}
909 
910 	return (in);
911 }
912 
913 /*
914  * Iterate through the node table, searching for a node entry which
915  * matches macaddr. If the entry is found, its reference count is
916  * incremented, and a pointer to the node is returned; otherwise,
917  * NULL will be returned.
918  * The node table lock is acquired by the caller.
919  */
920 static ieee80211_node_t *
921 ieee80211_find_node_locked(ieee80211_node_table_t *nt, const uint8_t *macaddr)
922 {
923 	ieee80211_node_t *in;
924 	int hash;
925 
926 	ASSERT(IEEE80211_NODE_IS_LOCKED(nt));
927 
928 	hash = ieee80211_node_hash(macaddr);
929 	in = list_head(&nt->nt_hash[hash]);
930 	while (in != NULL) {
931 		if (IEEE80211_ADDR_EQ(in->in_macaddr, macaddr))
932 			return (ieee80211_ref_node(in)); /* mark referenced */
933 		in = list_next(&nt->nt_hash[hash], in);
934 	}
935 	return (NULL);
936 }
937 
938 /*
939  * Iterate through the node table, searching for a node entry
940  * which match specified mac address.
941  * Return NULL if no matching node found.
942  */
943 ieee80211_node_t *
944 ieee80211_find_node(ieee80211_node_table_t *nt, const uint8_t *macaddr)
945 {
946 	ieee80211_node_t *in;
947 
948 	IEEE80211_NODE_LOCK(nt);
949 	in = ieee80211_find_node_locked(nt, macaddr);
950 	IEEE80211_NODE_UNLOCK(nt);
951 	return (in);
952 }
953 
954 /*
955  * Like find but search based on the ssid too.
956  */
957 ieee80211_node_t *
958 ieee80211_find_node_with_ssid(ieee80211_node_table_t *nt,
959 	const uint8_t *macaddr, uint32_t ssidlen, const uint8_t *ssid)
960 {
961 	ieee80211_node_t *in;
962 	int hash;
963 
964 	IEEE80211_NODE_LOCK(nt);
965 
966 	hash = ieee80211_node_hash(macaddr);
967 	in = list_head(&nt->nt_hash[hash]);
968 	while (in != NULL) {
969 		if (IEEE80211_ADDR_EQ(in->in_macaddr, macaddr) &&
970 		    in->in_esslen == ssidlen &&
971 		    memcmp(in->in_essid, ssid, ssidlen) == 0)
972 			break;
973 		in = list_next(&nt->nt_hash[hash], in);
974 	}
975 	if (in != NULL) {
976 		(void) ieee80211_ref_node(in); /* mark referenced */
977 	}
978 	IEEE80211_NODE_UNLOCK(nt);
979 
980 	return (in);
981 }
982 
983 /*
984  * Fake up a node; this handles node discovery in adhoc mode.
985  * Note that for the driver's benefit we treat this like an
986  * association so the driver has an opportunity to setup it's
987  * private state.
988  */
989 ieee80211_node_t *
990 ieee80211_fakeup_adhoc_node(ieee80211_node_table_t *nt, const uint8_t *macaddr)
991 {
992 	ieee80211com_t *ic = nt->nt_ic;
993 	ieee80211_node_t *in;
994 
995 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_fakeup_adhoc_node: "
996 	    "mac<%s>\n", ieee80211_macaddr_sprintf(macaddr));
997 	in = ieee80211_dup_bss(nt, macaddr);
998 	if (in != NULL) {
999 		/* no rate negotiation; just dup */
1000 		in->in_rates = ic->ic_bss->in_rates;
1001 		if (ic->ic_node_newassoc != NULL)
1002 			ic->ic_node_newassoc(in, 1);
1003 		ieee80211_node_authorize(in);
1004 	}
1005 	return (in);
1006 }
1007 
1008 static void
1009 ieee80211_saveie(uint8_t **iep, const uint8_t *ie)
1010 {
1011 	uint_t ielen = ie[1]+2;
1012 	/*
1013 	 * Record information element for later use.
1014 	 */
1015 	if (*iep == NULL || (*iep)[1] != ie[1]) {
1016 		if (*iep != NULL)
1017 			ieee80211_free(*iep);
1018 		*iep = ieee80211_malloc(ielen);
1019 	}
1020 	if (*iep != NULL)
1021 		(void) memcpy(*iep, ie, ielen);
1022 }
1023 
1024 static void
1025 saveie(uint8_t **iep, const uint8_t *ie)
1026 {
1027 	if (ie == NULL) {
1028 		if (*iep != NULL)
1029 			ieee80211_free(*iep);
1030 		*iep = NULL;
1031 	}
1032 	else
1033 		ieee80211_saveie(iep, ie);
1034 }
1035 
1036 /*
1037  * Process a beacon or probe response frame.
1038  */
1039 void
1040 ieee80211_add_scan(ieee80211com_t *ic, const struct ieee80211_scanparams *sp,
1041     const struct ieee80211_frame *wh, int subtype, int rssi, int rstamp)
1042 {
1043 	ieee80211_node_table_t *nt = &ic->ic_scan;
1044 	ieee80211_node_t *in;
1045 	boolean_t newnode = B_FALSE;
1046 
1047 	in = ieee80211_find_node(nt, wh->i_addr3);
1048 	if (in == NULL) {
1049 		/*
1050 		 * Create a new entry.
1051 		 */
1052 		in = ieee80211_alloc_node(ic, nt, wh->i_addr3);
1053 		if (in == NULL) {
1054 			ieee80211_dbg(IEEE80211_MSG_ANY, "ieee80211_add_scan: "
1055 			    "alloc node failed\n");
1056 			return;
1057 		}
1058 		/*
1059 		 * inherit from ic_bss.
1060 		 */
1061 		ieee80211_copy_bss(in, ic->ic_bss);
1062 		ieee80211_node_setchan(ic, in, ic->ic_curchan);
1063 		newnode = B_TRUE;
1064 	}
1065 
1066 	/* ap beaconing multiple ssid w/ same bssid */
1067 
1068 	/*
1069 	 * sp->ssid[0] - element ID
1070 	 * sp->ssid[1] - length
1071 	 * sp->ssid[2]... - ssid
1072 	 */
1073 	if (sp->ssid[1] != 0 &&
1074 	    subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP ||
1075 	    in->in_esslen == 0) {
1076 		in->in_esslen = sp->ssid[1];
1077 		bzero(in->in_essid, sizeof (in->in_essid));
1078 		bcopy(sp->ssid + 2, in->in_essid, sp->ssid[1]);
1079 	}
1080 	IEEE80211_ADDR_COPY(in->in_bssid, wh->i_addr3);
1081 	in->in_rssi = (uint8_t)rssi;
1082 	in->in_rstamp = rstamp;
1083 	bcopy(sp->tstamp, in->in_tstamp.data, sizeof (in->in_tstamp));
1084 	in->in_intval = sp->bintval;
1085 	in->in_capinfo = sp->capinfo;
1086 	in->in_chan = &ic->ic_sup_channels[sp->chan];
1087 	in->in_phytype = sp->phytype;
1088 	in->in_fhdwell = sp->fhdwell;
1089 	in->in_fhindex = sp->fhindex;
1090 	in->in_erp = sp->erp;
1091 	if (sp->tim != NULL) {
1092 		struct ieee80211_tim_ie *ie;
1093 
1094 		ie = (struct ieee80211_tim_ie *)sp->tim;
1095 		in->in_dtim_count = ie->tim_count;
1096 		in->in_dtim_period = ie->tim_period;
1097 	}
1098 	/*
1099 	 * Record the byte offset from the mac header to
1100 	 * the start of the TIM information element for
1101 	 * use by hardware and/or to speedup software
1102 	 * processing of beacon frames.
1103 	 */
1104 	in->in_tim_off = sp->timoff;
1105 	/*
1106 	 * Record optional information elements that might be
1107 	 * used by applications or drivers.
1108 	 */
1109 	saveie(&in->in_wpa_ie, sp->wpa);
1110 
1111 	/* NB: must be after in_chan is setup */
1112 	(void) ieee80211_setup_rates(in, sp->rates, sp->xrates,
1113 	    IEEE80211_F_DOSORT);
1114 
1115 	if (!newnode)
1116 		ieee80211_free_node(in);
1117 }
1118 
1119 /*
1120  * Initialize/update an ad-hoc node with contents from a received
1121  * beacon frame.
1122  */
1123 void
1124 ieee80211_init_neighbor(ieee80211_node_t *in, const struct ieee80211_frame *wh,
1125     const struct ieee80211_scanparams *sp)
1126 {
1127 	in->in_esslen = sp->ssid[1];
1128 	(void) memcpy(in->in_essid, sp->ssid + 2, sp->ssid[1]);
1129 	IEEE80211_ADDR_COPY(in->in_bssid, wh->i_addr3);
1130 	(void) memcpy(in->in_tstamp.data, sp->tstamp, sizeof (in->in_tstamp));
1131 	in->in_intval = sp->bintval;
1132 	in->in_capinfo = sp->capinfo;
1133 	in->in_chan = in->in_ic->ic_curchan;
1134 	in->in_fhdwell = sp->fhdwell;
1135 	in->in_fhindex = sp->fhindex;
1136 	in->in_erp = sp->erp;
1137 	in->in_tim_off = sp->timoff;
1138 
1139 	/* NB: must be after in_chan is setup */
1140 	(void) ieee80211_setup_rates(in, sp->rates, sp->xrates,
1141 	    IEEE80211_F_DOSORT);
1142 }
1143 
1144 /*
1145  * Do node discovery in adhoc mode on receipt of a beacon
1146  * or probe response frame.  Note that for the driver's
1147  * benefit we we treat this like an association so the
1148  * driver has an opportuinty to setup it's private state.
1149  */
1150 ieee80211_node_t *
1151 ieee80211_add_neighbor(ieee80211com_t *ic, const struct ieee80211_frame *wh,
1152     const struct ieee80211_scanparams *sp)
1153 {
1154 	ieee80211_node_t *in;
1155 
1156 	in = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
1157 	if (in != NULL) {
1158 		ieee80211_init_neighbor(in, wh, sp);
1159 		if (ic->ic_node_newassoc != NULL)
1160 			ic->ic_node_newassoc(in, 1);
1161 	}
1162 	return (in);
1163 }
1164 
1165 #define	IEEE80211_IS_CTL(wh) \
1166 	((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
1167 
1168 /*
1169  * Locate the node for sender, track state, and then pass the
1170  * (referenced) node up to the 802.11 layer for its use.  We
1171  * are required to pass some node so we fall back to ic_bss
1172  * when this frame is from an unknown sender.  The 802.11 layer
1173  * knows this means the sender wasn't in the node table and
1174  * acts accordingly.
1175  */
1176 ieee80211_node_t *
1177 ieee80211_find_rxnode(ieee80211com_t *ic, const struct ieee80211_frame *wh)
1178 {
1179 	ieee80211_node_table_t *nt;
1180 	ieee80211_node_t *in;
1181 
1182 	/* may want scanned nodes in the neighbor table for adhoc */
1183 	if (ic->ic_opmode == IEEE80211_M_STA ||
1184 	    (ic->ic_flags & IEEE80211_F_SCAN)) {
1185 		nt = &ic->ic_scan;
1186 	} else {
1187 		nt = &ic->ic_sta;
1188 	}
1189 
1190 	IEEE80211_NODE_LOCK(nt);
1191 	if (IEEE80211_IS_CTL(wh))
1192 		in = ieee80211_find_node_locked(nt, wh->i_addr1);
1193 	else
1194 		in = ieee80211_find_node_locked(nt, wh->i_addr2);
1195 	IEEE80211_NODE_UNLOCK(nt);
1196 
1197 	if (in == NULL)
1198 		in = ieee80211_ref_node(ic->ic_bss);
1199 
1200 	return (in);
1201 }
1202 
1203 /*
1204  * Return a reference to the appropriate node for sending
1205  * a data frame.  This handles node discovery in adhoc networks.
1206  */
1207 ieee80211_node_t *
1208 ieee80211_find_txnode(ieee80211com_t *ic, const uint8_t *daddr)
1209 {
1210 	ieee80211_node_table_t *nt = &ic->ic_sta;
1211 	ieee80211_node_t *in;
1212 
1213 	/*
1214 	 * The destination address should be in the node table
1215 	 * unless this is a multicast/broadcast frame.  We can
1216 	 * also optimize station mode operation, all frames go
1217 	 * to the bss node.
1218 	 */
1219 	IEEE80211_NODE_LOCK(nt);
1220 	if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(daddr))
1221 		in = ieee80211_ref_node(ic->ic_bss);
1222 	else
1223 		in = ieee80211_find_node_locked(nt, daddr);
1224 	IEEE80211_NODE_UNLOCK(nt);
1225 
1226 	if (in == NULL) {
1227 		if (ic->ic_opmode == IEEE80211_M_IBSS) {
1228 			/*
1229 			 * In adhoc mode cons up a node for the destination.
1230 			 * Note that we need an additional reference for the
1231 			 * caller to be consistent with
1232 			 * ieee80211_find_node_locked
1233 			 * can't hold lock across ieee80211_dup_bss 'cuz of
1234 			 * recursive locking
1235 			 */
1236 			in = ieee80211_fakeup_adhoc_node(nt, daddr);
1237 			if (in != NULL)
1238 				(void) ieee80211_ref_node(in);
1239 		} else {
1240 			ieee80211_dbg(IEEE80211_MSG_OUTPUT,
1241 			    "ieee80211_find_txnode: "
1242 			    "[%s] no node, discard frame\n",
1243 			    ieee80211_macaddr_sprintf(daddr));
1244 		}
1245 	}
1246 	return (in);
1247 }
1248 
1249 /*
1250  * Remove a node from the node database entries and free memory
1251  * associated with the node. The node table lock is acquired by
1252  * the caller.
1253  */
1254 static void
1255 ieee80211_free_node_locked(ieee80211_node_t *in)
1256 {
1257 	ieee80211com_t *ic = in->in_ic;
1258 	ieee80211_node_table_t *nt = in->in_table;
1259 	int32_t hash;
1260 
1261 	if (nt != NULL) {
1262 		hash = ieee80211_node_hash(in->in_macaddr);
1263 		list_remove(&nt->nt_hash[hash], in);
1264 		list_remove(&nt->nt_node, in);
1265 	}
1266 	ic->ic_node_free(in);
1267 }
1268 
1269 /*
1270  * Remove a node from the node database entries and free any
1271  * memory associated with the node.
1272  * This method can be overridden in ieee80211_attach()
1273  */
1274 void
1275 ieee80211_free_node(ieee80211_node_t *in)
1276 {
1277 	ieee80211_node_table_t *nt = in->in_table;
1278 
1279 	if (nt != NULL)
1280 		IEEE80211_NODE_LOCK(nt);
1281 	if (ieee80211_node_decref_nv(in) == 0)
1282 		ieee80211_free_node_locked(in);
1283 	if (nt != NULL)
1284 		IEEE80211_NODE_UNLOCK(nt);
1285 }
1286 
1287 /*
1288  * Reclaim a node.  If this is the last reference count then
1289  * do the normal free work.  Otherwise remove it from the node
1290  * table and mark it gone by clearing the back-reference.
1291  */
1292 static void
1293 ieee80211_node_reclaim(ieee80211_node_table_t *nt, ieee80211_node_t *in)
1294 {
1295 	int32_t hash;
1296 
1297 	IEEE80211_NODE_LOCK_ASSERT(nt);
1298 	ieee80211_dbg(IEEE80211_MSG_NODE, "node_reclaim: "
1299 	    " remove %p<%s> from %s table, refcnt %d\n",
1300 	    in, ieee80211_macaddr_sprintf(in->in_macaddr), nt->nt_name,
1301 	    ieee80211_node_refcnt(in));
1302 
1303 	if (ieee80211_node_decref_nv(in) != 0) {
1304 		/*
1305 		 * Clear any entry in the unicast key mapping table.
1306 		 * We need to do it here so rx lookups don't find it
1307 		 * in the mapping table even if it's not in the hash
1308 		 * table.  We cannot depend on the mapping table entry
1309 		 * being cleared because the node may not be free'd.
1310 		 */
1311 		hash = ieee80211_node_hash(in->in_macaddr);
1312 		list_remove(&nt->nt_hash[hash], in);
1313 		list_remove(&nt->nt_node, in);
1314 		in->in_table = NULL;
1315 	} else {
1316 		ieee80211_free_node_locked(in);
1317 	}
1318 }
1319 
1320 /*
1321  * Iterate through the node list and reclaim all node in the node table.
1322  * The node table lock is acquired by the caller
1323  */
1324 static void
1325 ieee80211_free_allnodes_locked(ieee80211_node_table_t *nt)
1326 {
1327 	ieee80211_node_t *in;
1328 
1329 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_free_allnodes_locked(): "
1330 	    "free all nodes in %s table\n", nt->nt_name);
1331 
1332 	in = list_head(&nt->nt_node);
1333 	while (in != NULL) {
1334 		ieee80211_node_reclaim(nt, in);
1335 		in = list_head(&nt->nt_node);
1336 	}
1337 	ieee80211_reset_erp(nt->nt_ic);
1338 }
1339 
1340 /*
1341  * Iterate through the node list, calling ieee80211_node_reclaim() for
1342  * all nodes associated with the interface.
1343  */
1344 static void
1345 ieee80211_free_allnodes(ieee80211_node_table_t *nt)
1346 {
1347 	IEEE80211_NODE_LOCK(nt);
1348 	ieee80211_free_allnodes_locked(nt);
1349 	IEEE80211_NODE_UNLOCK(nt);
1350 }
1351 
1352 /*
1353  * Timeout entries in the scan cache. This is the timeout callback
1354  * function of node table ic_scan which is called when the inactivity
1355  * timer expires.
1356  */
1357 static void
1358 ieee80211_timeout_scan_candidates(ieee80211_node_table_t *nt)
1359 {
1360 	ieee80211com_t *ic = nt->nt_ic;
1361 	ieee80211_node_t *in;
1362 
1363 	IEEE80211_NODE_LOCK(nt);
1364 	in = ic->ic_bss;
1365 	node_cleanfrag(in);	/* Free fragment if not needed */
1366 	nt->nt_inact_timer = IEEE80211_INACT_WAIT;
1367 	IEEE80211_NODE_UNLOCK(nt);
1368 }
1369 
1370 /*
1371  * Timeout inactive stations and do related housekeeping.
1372  * Note that we cannot hold the node lock while sending a
1373  * frame as this would lead to a LOR.  Instead we use a
1374  * generation number to mark nodes that we've scanned and
1375  * drop the lock and restart a scan if we have to time out
1376  * a node.  Since we are single-threaded by virtue of
1377  * controlling the inactivity timer we can be sure this will
1378  * process each node only once.
1379  */
1380 static void
1381 ieee80211_timeout_stations(ieee80211_node_table_t *nt)
1382 {
1383 	ieee80211com_t *ic = nt->nt_ic;
1384 	ieee80211_impl_t *im = ic->ic_private;
1385 	ieee80211_node_t *in = NULL;
1386 	uint32_t gen;
1387 	boolean_t isadhoc;
1388 
1389 	IEEE80211_LOCK_ASSERT(ic);
1390 	isadhoc = (ic->ic_opmode == IEEE80211_M_IBSS ||
1391 	    ic->ic_opmode == IEEE80211_M_AHDEMO);
1392 	IEEE80211_SCAN_LOCK(nt);
1393 	gen = ++nt->nt_scangen;
1394 restart:
1395 	IEEE80211_NODE_LOCK(nt);
1396 	for (in = list_head(&nt->nt_node); in != NULL;
1397 	    in = list_next(&nt->nt_node, in)) {
1398 		if (in->in_scangen == gen)	/* previously handled */
1399 			continue;
1400 		in->in_scangen = gen;
1401 		node_cleanfrag(in);	/* free fragment if not needed */
1402 
1403 		/*
1404 		 * Special case ourself; we may be idle for extended periods
1405 		 * of time and regardless reclaiming our state is wrong.
1406 		 */
1407 		if (in == ic->ic_bss)
1408 			continue;
1409 		in->in_inact--;
1410 		if (in->in_associd != 0 || isadhoc) {
1411 			/*
1412 			 * Probe the station before time it out.  We
1413 			 * send a null data frame which may not be
1414 			 * uinversally supported by drivers (need it
1415 			 * for ps-poll support so it should be...).
1416 			 */
1417 			if (0 < in->in_inact &&
1418 			    in->in_inact <= im->im_inact_probe) {
1419 				ieee80211_dbg(IEEE80211_MSG_NODE, "net80211: "
1420 				    "probe station due to inactivity\n");
1421 				IEEE80211_NODE_UNLOCK(nt);
1422 				IEEE80211_UNLOCK(ic);
1423 				(void) ieee80211_send_nulldata(in);
1424 				IEEE80211_LOCK(ic);
1425 				goto restart;
1426 			}
1427 		}
1428 		if (in->in_inact <= 0) {
1429 			ieee80211_dbg(IEEE80211_MSG_NODE, "net80211: "
1430 			    "station timed out due to inact (refcnt %u)\n",
1431 			    ieee80211_node_refcnt(in));
1432 			/*
1433 			 * Send a deauthenticate frame and drop the station.
1434 			 * This is somewhat complicated due to reference counts
1435 			 * and locking.  At this point a station will typically
1436 			 * have a reference count of 1.  ieee80211_node_leave
1437 			 * will do a "free" of the node which will drop the
1438 			 * reference count.  But in the meantime a reference
1439 			 * wil be held by the deauth frame.  The actual reclaim
1440 			 * of the node will happen either after the tx is
1441 			 * completed or by ieee80211_node_leave.
1442 			 *
1443 			 * Separately we must drop the node lock before sending
1444 			 * in case the driver takes a lock, as this will result
1445 			 * in  LOR between the node lock and the driver lock.
1446 			 */
1447 			IEEE80211_NODE_UNLOCK(nt);
1448 			if (in->in_associd != 0) {
1449 				IEEE80211_UNLOCK(ic);
1450 				IEEE80211_SEND_MGMT(ic, in,
1451 				    IEEE80211_FC0_SUBTYPE_DEAUTH,
1452 				    IEEE80211_REASON_AUTH_EXPIRE);
1453 				IEEE80211_LOCK(ic);
1454 			}
1455 			ieee80211_node_leave(ic, in);
1456 			goto restart;
1457 		}
1458 	}
1459 	IEEE80211_NODE_UNLOCK(nt);
1460 
1461 	IEEE80211_SCAN_UNLOCK(nt);
1462 
1463 	nt->nt_inact_timer = IEEE80211_INACT_WAIT;
1464 }
1465 
1466 /*
1467  * Call the user-defined call back function for all nodes in
1468  * the node cache. The callback is invoked with the user-supplied
1469  * value and a pointer to the current node.
1470  */
1471 void
1472 ieee80211_iterate_nodes(ieee80211_node_table_t *nt, ieee80211_iter_func *f,
1473     void *arg)
1474 {
1475 	ieee80211_node_t *in;
1476 
1477 	IEEE80211_NODE_LOCK(nt);
1478 	in = list_head(&nt->nt_node);
1479 	while (in != NULL) {
1480 		if (in->in_chan == IEEE80211_CHAN_ANYC) {
1481 			in = list_next(&nt->nt_node, in);
1482 			continue;
1483 		}
1484 		(void) ieee80211_ref_node(in);
1485 		IEEE80211_NODE_UNLOCK(nt);
1486 		(*f)(arg, in);
1487 		ieee80211_free_node(in);
1488 		IEEE80211_NODE_LOCK(nt);
1489 		in = list_next(&nt->nt_node, in);
1490 	}
1491 	IEEE80211_NODE_UNLOCK(nt);
1492 }
1493 
1494 /*
1495  * Handle bookkeeping for station deauthentication/disassociation
1496  * when operating as an ap.
1497  */
1498 static void
1499 ieee80211_node_leave(ieee80211com_t *ic, ieee80211_node_t *in)
1500 {
1501 	ieee80211_node_table_t *nt = in->in_table;
1502 
1503 	ASSERT(ic->ic_opmode == IEEE80211_M_IBSS);
1504 
1505 	/*
1506 	 * Remove the node from any table it's recorded in and
1507 	 * drop the caller's reference.  Removal from the table
1508 	 * is important to insure the node is not reprocessed
1509 	 * for inactivity.
1510 	 */
1511 	if (nt != NULL) {
1512 		IEEE80211_NODE_LOCK(nt);
1513 		ieee80211_node_reclaim(nt, in);
1514 		IEEE80211_NODE_UNLOCK(nt);
1515 	} else {
1516 		ieee80211_free_node(in);
1517 	}
1518 }
1519 
1520 /*
1521  * Initialize a node table with specified name, inactivity timer value
1522  * and callback inactivity timeout function. Associate the node table
1523  * with interface softc, ic.
1524  */
1525 static void
1526 ieee80211_node_table_init(ieee80211com_t *ic, ieee80211_node_table_t *nt,
1527     const char *name, int inact, int keyixmax,
1528     void (*timeout)(ieee80211_node_table_t *))
1529 {
1530 	int i;
1531 
1532 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_init():"
1533 	    "%s table, inact %d\n", name, inact);
1534 
1535 	nt->nt_ic = ic;
1536 	nt->nt_name = name;
1537 	nt->nt_inact_timer = 0;
1538 	nt->nt_inact_init = inact;
1539 	nt->nt_timeout = timeout;
1540 	nt->nt_keyixmax = keyixmax;
1541 	nt->nt_scangen = 1;
1542 	mutex_init(&nt->nt_scanlock, NULL, MUTEX_DRIVER, NULL);
1543 	mutex_init(&nt->nt_nodelock, NULL, MUTEX_DRIVER, NULL);
1544 
1545 	list_create(&nt->nt_node, sizeof (ieee80211_node_t),
1546 	    offsetof(ieee80211_node_t, in_node));
1547 	for (i = 0; i < IEEE80211_NODE_HASHSIZE; i++) {
1548 		list_create(&nt->nt_hash[i], sizeof (ieee80211_node_t),
1549 		    offsetof(ieee80211_node_t, in_hash));
1550 	}
1551 }
1552 
1553 /*
1554  * Reset a node table. Clean its inactivity timer and call
1555  * ieee80211_free_allnodes_locked() to free all nodes in the
1556  * node table.
1557  */
1558 void
1559 ieee80211_node_table_reset(ieee80211_node_table_t *nt)
1560 {
1561 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_reset(): "
1562 	    "%s table\n", nt->nt_name);
1563 
1564 	IEEE80211_NODE_LOCK(nt);
1565 	nt->nt_inact_timer = 0;
1566 	ieee80211_free_allnodes_locked(nt);
1567 	IEEE80211_NODE_UNLOCK(nt);
1568 }
1569 
1570 /*
1571  * Destroy a node table. Free all nodes in the node table.
1572  * This function is usually called by node detach function.
1573  */
1574 static void
1575 ieee80211_node_table_cleanup(ieee80211_node_table_t *nt)
1576 {
1577 	ieee80211_dbg(IEEE80211_MSG_NODE, "ieee80211_node_table_cleanup(): "
1578 	    "%s table\n", nt->nt_name);
1579 
1580 	IEEE80211_NODE_LOCK(nt);
1581 	ieee80211_free_allnodes_locked(nt);
1582 	IEEE80211_NODE_UNLOCK(nt);
1583 	mutex_destroy(&nt->nt_nodelock);
1584 	mutex_destroy(&nt->nt_scanlock);
1585 }
1586