statically allocate the station/neighbor node table; the deferred
allocation scheme introduced a race condition during device state transitions
This commit is contained in:
parent
945d03f417
commit
459bcc3dba
@ -361,8 +361,7 @@ ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
|
||||
* For any other operating mode we want to reset the
|
||||
* tx rate state of each node.
|
||||
*/
|
||||
if (ic->ic_sta != NULL)
|
||||
ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0);
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, 0);
|
||||
ath_rate_update(sc, ic->ic_bss, 0);
|
||||
}
|
||||
if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
|
||||
@ -467,8 +466,8 @@ ath_ratectl(void *arg)
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */
|
||||
else if (ic->ic_sta != NULL)
|
||||
ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc);
|
||||
else
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
|
||||
}
|
||||
interval = ath_rateinterval;
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
|
@ -345,8 +345,7 @@ ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
|
||||
* For any other operating mode we want to reset the
|
||||
* tx rate state of each node.
|
||||
*/
|
||||
if (ic->ic_sta != NULL)
|
||||
ieee80211_iterate_nodes(ic->ic_sta, ath_rate_cb, 0);
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, 0);
|
||||
ath_rate_update(sc, ic->ic_bss, 0);
|
||||
}
|
||||
if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
|
||||
@ -448,8 +447,8 @@ ath_ratectl(void *arg)
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */
|
||||
else if (ic->ic_sta != NULL)
|
||||
ieee80211_iterate_nodes(ic->ic_sta, ath_rate_ctl, sc);
|
||||
else
|
||||
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
|
||||
}
|
||||
interval = ath_rateinterval;
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
|
@ -714,8 +714,8 @@ ieee80211_watchdog(struct ieee80211com *ic)
|
||||
nt->nt_timeout(nt);
|
||||
need_inact_timer += nt->nt_inact_timer;
|
||||
}
|
||||
nt = ic->ic_sta;
|
||||
if (nt != NULL && nt->nt_inact_timer) {
|
||||
nt = &ic->ic_sta;
|
||||
if (nt->nt_inact_timer) {
|
||||
if (--nt->nt_inact_timer == 0)
|
||||
nt->nt_timeout(nt);
|
||||
need_inact_timer += nt->nt_inact_timer;
|
||||
|
@ -235,7 +235,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
|
||||
* Fake up a node for this newly
|
||||
* discovered member of the IBSS.
|
||||
*/
|
||||
ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
|
||||
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
|
||||
type == IEEE80211_FC0_TYPE_CTL ?
|
||||
wh->i_addr1 : wh->i_addr2);
|
||||
if (ni == NULL) {
|
||||
@ -349,7 +349,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
|
||||
IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
|
||||
wh, "data", "%s", "unknown src");
|
||||
/* NB: caller deals with reference */
|
||||
ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
|
||||
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
|
||||
if (ni != NULL) {
|
||||
IEEE80211_SEND_MGMT(ic, ni,
|
||||
IEEE80211_FC0_SUBTYPE_DEAUTH,
|
||||
@ -507,7 +507,7 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
|
||||
/* XXX this dups work done in ieee80211_encap */
|
||||
/* check if destination is associated */
|
||||
struct ieee80211_node *ni1 =
|
||||
ieee80211_find_node(ic->ic_sta,
|
||||
ieee80211_find_node(&ic->ic_sta,
|
||||
eh->ether_dhost);
|
||||
if (ni1 != NULL) {
|
||||
/* XXX check if authorized */
|
||||
@ -873,7 +873,7 @@ ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh,
|
||||
}
|
||||
/* always accept open authentication requests */
|
||||
if (ni == ic->ic_bss) {
|
||||
ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
|
||||
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
|
||||
if (ni == NULL)
|
||||
return;
|
||||
} else
|
||||
@ -1020,7 +1020,7 @@ ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh,
|
||||
switch (seq) {
|
||||
case IEEE80211_AUTH_SHARED_REQUEST:
|
||||
if (ni == ic->ic_bss) {
|
||||
ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
|
||||
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
|
||||
if (ni == NULL) {
|
||||
/* NB: no way to return an error */
|
||||
return;
|
||||
@ -1890,7 +1890,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
|
||||
if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0)
|
||||
return;
|
||||
ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
|
||||
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
|
||||
wh->i_addr2);
|
||||
} else
|
||||
ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
|
||||
@ -2003,10 +2003,10 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
* send the response so blindly add them to the
|
||||
* neighbor table.
|
||||
*/
|
||||
ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
|
||||
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
|
||||
wh->i_addr2);
|
||||
} else
|
||||
ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
|
||||
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
|
||||
if (ni == NULL)
|
||||
return;
|
||||
allocbs = 1;
|
||||
@ -2172,7 +2172,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
"[%s] deny %s request, sta not authenticated\n",
|
||||
ether_sprintf(wh->i_addr2),
|
||||
reassoc ? "reassoc" : "assoc");
|
||||
ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
|
||||
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
|
||||
if (ni != NULL) {
|
||||
IEEE80211_SEND_MGMT(ic, ni,
|
||||
IEEE80211_FC0_SUBTYPE_DEAUTH,
|
||||
|
@ -868,9 +868,7 @@ ieee80211_ioctl_getkey(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
return error;
|
||||
kid = ik.ik_keyix;
|
||||
if (kid == IEEE80211_KEYIX_NONE) {
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, ik.ik_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
wk = &ni->ni_ucastkey;
|
||||
@ -958,9 +956,7 @@ ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
error = copyin(ireq->i_data, wpaie.wpa_macaddr, IEEE80211_ADDR_LEN);
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, wpaie.wpa_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, wpaie.wpa_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
memset(wpaie.wpa_ie, 0, sizeof(wpaie.wpa_ie));
|
||||
@ -989,9 +985,7 @@ ieee80211_ioctl_getstastats(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
if (ireq->i_len > sizeof(struct ieee80211req_sta_stats))
|
||||
@ -1137,9 +1131,7 @@ ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
int error, space;
|
||||
u_int8_t *p, *cp;
|
||||
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL)
|
||||
return EINVAL;
|
||||
nt = &ic->ic_sta;
|
||||
p = ireq->i_data;
|
||||
space = ireq->i_len;
|
||||
error = 0;
|
||||
@ -1181,9 +1173,7 @@ ieee80211_ioctl_getstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
error = copyin(ireq->i_data, &txpow, sizeof(txpow));
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, txpow.it_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
txpow.it_txpow = ni->ni_txpower;
|
||||
@ -1506,9 +1496,7 @@ ieee80211_ioctl_setkey(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
if (!IEEE80211_ADDR_EQ(ik.ik_macaddr, ni->ni_bssid))
|
||||
return EADDRNOTAVAIL;
|
||||
} else {
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, ik.ik_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, ik.ik_macaddr);
|
||||
if (ni == NULL)
|
||||
return ENOENT;
|
||||
}
|
||||
@ -1561,9 +1549,7 @@ ieee80211_ioctl_delkey(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
if (dk.idk_keyix == (u_int8_t) IEEE80211_KEYIX_NONE) {
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, dk.idk_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, dk.idk_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
/* XXX error return */
|
||||
@ -1644,15 +1630,13 @@ ieee80211_ioctl_setmlme(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
case IEEE80211_M_HOSTAP:
|
||||
/* NB: the broadcast address means do 'em all */
|
||||
if (!IEEE80211_ADDR_EQ(mlme.im_macaddr, ic->ic_ifp->if_broadcastaddr)) {
|
||||
if (ic->ic_sta == NULL ||
|
||||
(ni = ieee80211_find_node(ic->ic_sta,
|
||||
if ((ni = ieee80211_find_node(&ic->ic_sta,
|
||||
mlme.im_macaddr)) == NULL)
|
||||
return EINVAL;
|
||||
domlme(&mlme, ni);
|
||||
ieee80211_free_node(ni);
|
||||
} else {
|
||||
if (ic->ic_sta != NULL)
|
||||
ieee80211_iterate_nodes(ic->ic_sta,
|
||||
ieee80211_iterate_nodes(&ic->ic_sta,
|
||||
domlme, &mlme);
|
||||
}
|
||||
break;
|
||||
@ -1664,9 +1648,7 @@ ieee80211_ioctl_setmlme(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
case IEEE80211_MLME_UNAUTHORIZE:
|
||||
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
|
||||
return EINVAL;
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, mlme.im_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, mlme.im_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL;
|
||||
if (mlme.im_op == IEEE80211_MLME_AUTHORIZE)
|
||||
@ -1799,9 +1781,7 @@ ieee80211_ioctl_setstatxpow(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
error = copyin(ireq->i_data, &txpow, sizeof(txpow));
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (ic->ic_sta == NULL)
|
||||
return EINVAL;
|
||||
ni = ieee80211_find_node(ic->ic_sta, txpow.it_macaddr);
|
||||
ni = ieee80211_find_node(&ic->ic_sta, txpow.it_macaddr);
|
||||
if (ni == NULL)
|
||||
return EINVAL; /* XXX */
|
||||
ni->ni_txpower = txpow.it_txpow;
|
||||
|
@ -68,9 +68,6 @@ static void ieee80211_set_tim(struct ieee80211com *,
|
||||
static void ieee80211_node_table_init(struct ieee80211com *ic,
|
||||
struct ieee80211_node_table *nt, const char *name, int inact,
|
||||
void (*timeout)(struct ieee80211_node_table *));
|
||||
static struct ieee80211_node_table *ieee80211_node_table_alloc(
|
||||
struct ieee80211com *ic, const char *name, int inact,
|
||||
void (*timeout)(struct ieee80211_node_table *));
|
||||
static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt);
|
||||
|
||||
MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
|
||||
@ -79,7 +76,8 @@ void
|
||||
ieee80211_node_attach(struct ieee80211com *ic)
|
||||
{
|
||||
|
||||
ic->ic_sta = NULL; /* defer to when we need it */
|
||||
ieee80211_node_table_init(ic, &ic->ic_sta, "station",
|
||||
IEEE80211_INACT_INIT, ieee80211_timeout_stations);
|
||||
ieee80211_node_table_init(ic, &ic->ic_scan, "scan",
|
||||
IEEE80211_INACT_SCAN, ieee80211_timeout_scan_candidates);
|
||||
|
||||
@ -176,10 +174,7 @@ ieee80211_node_detach(struct ieee80211com *ic)
|
||||
ic->ic_bss = NULL;
|
||||
}
|
||||
ieee80211_node_table_cleanup(&ic->ic_scan);
|
||||
if (ic->ic_sta != NULL) {
|
||||
ieee80211_node_table_free(ic->ic_sta);
|
||||
ic->ic_sta = NULL;
|
||||
}
|
||||
ieee80211_node_table_cleanup(&ic->ic_sta);
|
||||
if (ic->ic_aid_bitmap != NULL) {
|
||||
FREE(ic->ic_aid_bitmap, M_DEVBUF);
|
||||
ic->ic_aid_bitmap = NULL;
|
||||
@ -355,6 +350,7 @@ ieee80211_next_scan(struct ieee80211com *ic)
|
||||
void
|
||||
ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
|
||||
{
|
||||
struct ieee80211_node_table *nt;
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
|
||||
@ -366,33 +362,26 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
|
||||
* we create nodes only through discovery and they typically
|
||||
* are long-lived associations.
|
||||
*/
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP)
|
||||
ic->ic_sta = ieee80211_node_table_alloc(ic,
|
||||
"station", ic->ic_inact_init,
|
||||
ieee80211_timeout_stations);
|
||||
else
|
||||
ic->ic_sta = ieee80211_node_table_alloc(ic,
|
||||
"neighbor", ic->ic_inact_run,
|
||||
ieee80211_timeout_stations);
|
||||
if (ic->ic_sta == NULL) {
|
||||
/*
|
||||
* Should remain in SCAN state and retry.
|
||||
*/
|
||||
/* XXX stat+msg */
|
||||
nt = &ic->ic_sta;
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
|
||||
nt->nt_name = "station";
|
||||
nt->nt_inact_init = ic->ic_inact_init;
|
||||
} else {
|
||||
nt->nt_name = "neighbor";
|
||||
nt->nt_inact_init = ic->ic_inact_run;
|
||||
}
|
||||
IEEE80211_NODE_UNLOCK(nt);
|
||||
|
||||
ni = ieee80211_alloc_node(nt, ic->ic_myaddr);
|
||||
if (ni == NULL) {
|
||||
/* XXX recovery? */
|
||||
return;
|
||||
}
|
||||
|
||||
ni = ic->ic_bss;
|
||||
IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
|
||||
IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
|
||||
ni->ni_esslen = ic->ic_des_esslen;
|
||||
memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
|
||||
ni->ni_rssi = 0;
|
||||
ni->ni_rstamp = 0;
|
||||
ni->ni_tstamp.tsf = 0;
|
||||
ni->ni_intval = ic->ic_lintval;
|
||||
ni->ni_capinfo = 0;
|
||||
ni->ni_erp = 0;
|
||||
if (ic->ic_flags & IEEE80211_F_PRIVACY)
|
||||
ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
|
||||
if (ic->ic_phytype == IEEE80211_T_FH) {
|
||||
@ -423,15 +412,8 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
|
||||
*/
|
||||
ieee80211_set11gbasicrates(&ni->ni_rates, IEEE80211_MODE_11B);
|
||||
}
|
||||
/*
|
||||
* Set the erp state (mostly the slot time) to deal with
|
||||
* the auto-select case; this should be redundant if the
|
||||
* mode is locked.
|
||||
*/
|
||||
ieee80211_reset_erp(ic);
|
||||
ieee80211_wme_initparams(ic);
|
||||
|
||||
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
|
||||
(void) ieee80211_sta_join(ic, ieee80211_ref_node(ni));
|
||||
}
|
||||
|
||||
void
|
||||
@ -440,16 +422,14 @@ ieee80211_reset_bss(struct ieee80211com *ic)
|
||||
struct ieee80211_node *ni, *obss;
|
||||
|
||||
ieee80211_node_table_reset(&ic->ic_scan);
|
||||
ieee80211_node_table_reset(&ic->ic_sta);
|
||||
|
||||
ni = ieee80211_alloc_node(&ic->ic_scan, ic->ic_myaddr);
|
||||
KASSERT(ni != NULL, ("unable to setup inital BSS node"));
|
||||
obss = ic->ic_bss;
|
||||
ic->ic_bss = ieee80211_ref_node(ni);
|
||||
if (obss != NULL)
|
||||
ieee80211_free_node(obss);
|
||||
if (ic->ic_sta != NULL) {
|
||||
ieee80211_node_table_free(ic->ic_sta);
|
||||
ic->ic_sta = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -604,7 +584,7 @@ ieee80211_end_scan(struct ieee80211com *ic)
|
||||
* The passive scan to look for existing AP's completed,
|
||||
* select a channel to camp on. Identify the channels
|
||||
* that already have one or more AP's and try to locate
|
||||
* an unnoccupied one. If that fails, pick a channel that
|
||||
* an unoccupied one. If that fails, pick a channel that
|
||||
* looks to be quietest.
|
||||
*/
|
||||
memset(maxrssi, 0, sizeof(maxrssi));
|
||||
@ -745,7 +725,7 @@ ieee80211_ibss_merge(struct ieee80211com *ic, struct ieee80211_node *ni)
|
||||
ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
|
||||
ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : ""
|
||||
);
|
||||
return ieee80211_sta_join(ic, ni);
|
||||
return ieee80211_sta_join(ic, ieee80211_ref_node(ni));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -758,34 +738,29 @@ ieee80211_sta_join(struct ieee80211com *ic, struct ieee80211_node *selbs)
|
||||
struct ieee80211_node *obss;
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_IBSS) {
|
||||
struct ieee80211_node_table *nt;
|
||||
/*
|
||||
* Delete unusable rates; we've already checked
|
||||
* that the negotiated rate set is acceptable.
|
||||
*/
|
||||
ieee80211_fix_rate(ic, selbs, IEEE80211_F_DODEL);
|
||||
/*
|
||||
* Create the neighbor table; it will already
|
||||
* Fillin the neighbor table; it will already
|
||||
* exist if we are simply switching mastership.
|
||||
* XXX ic_sta always setup so this is unnecessary?
|
||||
*/
|
||||
if (ic->ic_sta == NULL) {
|
||||
ic->ic_sta = ieee80211_node_table_alloc(ic,
|
||||
"neighbor", ic->ic_inact_run,
|
||||
ieee80211_timeout_stations);
|
||||
if (ic->ic_sta == NULL) {
|
||||
/*
|
||||
* Should remain in SCAN state and retry.
|
||||
*/
|
||||
/* XXX stat+msg */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
nt = &ic->ic_sta;
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
nt->nt_name = "neighbor";
|
||||
nt->nt_inact_init = ic->ic_inact_run;
|
||||
IEEE80211_NODE_UNLOCK(nt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Committed to selbs, setup state.
|
||||
*/
|
||||
obss = ic->ic_bss;
|
||||
ic->ic_bss = selbs;
|
||||
ic->ic_bss = selbs; /* NB: caller assumed to bump refcnt */
|
||||
if (obss != NULL)
|
||||
ieee80211_free_node(obss);
|
||||
/*
|
||||
@ -796,10 +771,11 @@ ieee80211_sta_join(struct ieee80211com *ic, struct ieee80211_node *selbs)
|
||||
ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
|
||||
ieee80211_reset_erp(ic);
|
||||
ieee80211_wme_initparams(ic);
|
||||
if (ic->ic_opmode == IEEE80211_M_IBSS)
|
||||
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
|
||||
else
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_STA)
|
||||
ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
|
||||
else
|
||||
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1071,7 +1047,7 @@ ieee80211_find_rxnode(struct ieee80211com *ic,
|
||||
(ic->ic_flags & IEEE80211_F_SCAN))
|
||||
nt = &ic->ic_scan;
|
||||
else
|
||||
nt = ic->ic_sta;
|
||||
nt = &ic->ic_sta;
|
||||
/* XXX check ic_bss first in station mode */
|
||||
/* XXX 4-address frames? */
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
@ -1098,7 +1074,7 @@ ieee80211_find_txnode_debug(struct ieee80211com *ic, const u_int8_t *macaddr,
|
||||
ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
|
||||
#endif
|
||||
{
|
||||
struct ieee80211_node_table *nt = ic->ic_sta;
|
||||
struct ieee80211_node_table *nt = &ic->ic_sta;
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
/*
|
||||
@ -1106,7 +1082,7 @@ ieee80211_find_txnode(struct ieee80211com *ic, const u_int8_t *macaddr)
|
||||
* unless we are operating in station mode or this is a
|
||||
* multicast/broadcast frame.
|
||||
*/
|
||||
if (nt == NULL || IEEE80211_IS_MULTICAST(macaddr))
|
||||
if (ic->ic_opmode == IEEE80211_M_STA || IEEE80211_IS_MULTICAST(macaddr))
|
||||
return ieee80211_ref_node(ic->ic_bss);
|
||||
|
||||
/* XXX can't hold lock across dup_bss 'cuz of recursive locking */
|
||||
@ -1274,7 +1250,7 @@ node_reclaim(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
|
||||
* Other references are present, just remove the
|
||||
* node from the table so it cannot be found. When
|
||||
* the references are dropped storage will be
|
||||
* reclaimed. This normally only happens for ic_bss.
|
||||
* reclaimed.
|
||||
*/
|
||||
TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
|
||||
LIST_REMOVE(ni, ni_hash);
|
||||
@ -1771,7 +1747,7 @@ u_int8_t
|
||||
ieee80211_getrssi(struct ieee80211com *ic)
|
||||
{
|
||||
#define NZ(x) ((x) == 0 ? 1 : (x))
|
||||
struct ieee80211_node_table *nt = ic->ic_sta;
|
||||
struct ieee80211_node_table *nt = &ic->ic_sta;
|
||||
u_int32_t rssi_samples, rssi_total;
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
@ -1779,32 +1755,23 @@ ieee80211_getrssi(struct ieee80211com *ic)
|
||||
rssi_samples = 0;
|
||||
switch (ic->ic_opmode) {
|
||||
case IEEE80211_M_IBSS: /* average of all ibss neighbors */
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL)
|
||||
break;
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list)
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list)
|
||||
if (ni->ni_capinfo & IEEE80211_CAPINFO_IBSS) {
|
||||
rssi_samples++;
|
||||
rssi_total += ic->ic_node_getrssi(ni);
|
||||
}
|
||||
break;
|
||||
case IEEE80211_M_AHDEMO: /* average of all neighbors */
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL)
|
||||
break;
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list) {
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
|
||||
rssi_samples++;
|
||||
rssi_total += ic->ic_node_getrssi(ni);
|
||||
}
|
||||
break;
|
||||
case IEEE80211_M_HOSTAP: /* average of all associated stations */
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL)
|
||||
break;
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(ni, &ic->ic_sta->nt_node, ni_list)
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list)
|
||||
if (IEEE80211_AID(ni->ni_associd) != 0) {
|
||||
rssi_samples++;
|
||||
rssi_total += ic->ic_node_getrssi(ni);
|
||||
@ -1877,24 +1844,6 @@ ieee80211_node_table_init(struct ieee80211com *ic,
|
||||
nt->nt_timeout = timeout;
|
||||
}
|
||||
|
||||
static struct ieee80211_node_table *
|
||||
ieee80211_node_table_alloc(struct ieee80211com *ic,
|
||||
const char *name, int inact,
|
||||
void (*timeout)(struct ieee80211_node_table *))
|
||||
{
|
||||
struct ieee80211_node_table *nt;
|
||||
|
||||
MALLOC(nt, struct ieee80211_node_table *,
|
||||
sizeof(struct ieee80211_node_table),
|
||||
M_DEVBUF, M_NOWAIT | M_ZERO);
|
||||
if (nt == NULL) {
|
||||
printf("%s: no memory node table!\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
ieee80211_node_table_init(ic, nt, name, inact, timeout);
|
||||
return nt;
|
||||
}
|
||||
|
||||
void
|
||||
ieee80211_node_table_reset(struct ieee80211_node_table *nt)
|
||||
{
|
||||
@ -1919,19 +1868,3 @@ ieee80211_node_table_cleanup(struct ieee80211_node_table *nt)
|
||||
IEEE80211_SCAN_LOCK_DESTROY(nt);
|
||||
IEEE80211_NODE_LOCK_DESTROY(nt);
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: public for use in ieee80211_proto.c
|
||||
*/
|
||||
void
|
||||
ieee80211_node_table_free(struct ieee80211_node_table *nt)
|
||||
{
|
||||
|
||||
IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE,
|
||||
"%s %s table\n", __func__, nt->nt_name);
|
||||
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
nt->nt_inact_timer = 0;
|
||||
ieee80211_node_table_cleanup(nt);
|
||||
FREE(nt, M_DEVBUF);
|
||||
}
|
||||
|
@ -218,7 +218,6 @@ struct ieee80211_node_table {
|
||||
void (*nt_timeout)(struct ieee80211_node_table *);
|
||||
};
|
||||
extern void ieee80211_node_table_reset(struct ieee80211_node_table *);
|
||||
extern void ieee80211_node_table_free(struct ieee80211_node_table *);
|
||||
|
||||
extern struct ieee80211_node *ieee80211_alloc_node(
|
||||
struct ieee80211_node_table *, const u_int8_t *);
|
||||
|
@ -845,11 +845,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
|
||||
ieee80211_sta_leave(ic, ni);
|
||||
break;
|
||||
case IEEE80211_M_HOSTAP:
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL) { /* XXX cannot happen */
|
||||
if_printf(ifp, "no sta table (run)\n");
|
||||
break;
|
||||
}
|
||||
nt = &ic->ic_sta;
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
|
||||
if (ni->ni_associd == 0)
|
||||
@ -872,11 +868,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
|
||||
IEEE80211_REASON_AUTH_LEAVE);
|
||||
break;
|
||||
case IEEE80211_M_HOSTAP:
|
||||
nt = ic->ic_sta;
|
||||
if (nt == NULL) { /* XXX cannot happen */
|
||||
if_printf(ifp, "no sta table (assoc)\n");
|
||||
break;
|
||||
}
|
||||
nt = &ic->ic_sta;
|
||||
IEEE80211_NODE_LOCK(nt);
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
|
||||
IEEE80211_SEND_MGMT(ic, ni,
|
||||
@ -1072,8 +1064,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
|
||||
* XXX
|
||||
*/
|
||||
ic->ic_scan.nt_inact_timer = IEEE80211_INACT_WAIT;
|
||||
if (ic->ic_sta != NULL)
|
||||
ic->ic_sta->nt_inact_timer = IEEE80211_INACT_WAIT;
|
||||
ic->ic_sta.nt_inact_timer = IEEE80211_INACT_WAIT;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -114,7 +114,7 @@ struct ieee80211com {
|
||||
enum ieee80211_state ic_state; /* 802.11 state */
|
||||
enum ieee80211_protmode ic_protmode; /* 802.11g protection mode */
|
||||
enum ieee80211_roamingmode ic_roaming; /* roaming mode */
|
||||
struct ieee80211_node_table *ic_sta; /* stations/neighbors */
|
||||
struct ieee80211_node_table ic_sta; /* stations/neighbors */
|
||||
u_int32_t *ic_aid_bitmap; /* association id map */
|
||||
u_int16_t ic_max_aid;
|
||||
u_int16_t ic_sta_assoc; /* stations associated */
|
||||
|
Loading…
x
Reference in New Issue
Block a user