Change handling of probe response frames. Previously we always dropped the

refcnt on the node but left it in the node table.  This allows the node table
to hold the results of scanned ap's but for ibss scans left nodes w/o any
driver-private state setup and/or a bad refcnt (when the nodes were timed
out they were prematurely discarded).  Now we treat nodes identified for ap
scanning as before but force nodes discovered when scanning for ibss neighbors
to have complete/proper state and hold the refcnt on the node.  Any other
nodes created because of these frames are discarded directly (need to optimize
this case to eliminate various work that's immediately discarded).
This commit is contained in:
sam 2004-04-02 23:35:24 +00:00
parent da8204db05
commit 0a58f658fe

View File

@ -714,6 +714,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni->ni_esslen = ssid[1];
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
allocbs = 1;
} else if (ssid[1] != 0 && isprobe) {
/*
* Update ESSID at probe response to adopt hidden AP by
@ -722,7 +723,9 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni->ni_esslen = ssid[1];
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
}
allocbs = 0;
} else
allocbs = 0;
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
ni->ni_rssi = rssi;
ni->ni_rstamp = rstamp;
@ -736,7 +739,29 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni->ni_erp = erp;
/* NB: must be after ni_chan is setup */
ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
ieee80211_unref_node(&ni);
/*
* When scanning we record results (nodes) with a zero
* refcnt. Otherwise we want to hold the reference for
* ibss neighbors so the nodes don't get released prematurely.
* Anything else can be discarded (XXX and should be handled
* above so we don't do so much work).
*/
if (ic->ic_state == IEEE80211_S_SCAN)
ieee80211_unref_node(&ni); /* NB: do not free */
else if (ic->ic_opmode == IEEE80211_M_IBSS &&
allocbs && isprobe) {
/*
* Fake an association so the driver can setup it's
* private state. The rate set has been setup above;
* there is no handshake as in ap/station operation.
*/
if (ic->ic_newassoc)
(*ic->ic_newassoc)(ic, ni, 1);
/* NB: hold reference */
} else {
/* XXX optimize to avoid work done above */
ieee80211_free_node(ic, ni);
}
break;
}