summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2004-04-02 23:35:24 +0000
committersam <sam@FreeBSD.org>2004-04-02 23:35:24 +0000
commit0a58f658fe814a5f8d328c8b40fb24f0300a6878 (patch)
treed8b1cfc2865de97907e8c23ac0bfa1cb8b719fb2 /sys/net80211
parentda8204db05d94e4c8b1c528ca58309754394bd43 (diff)
downloadFreeBSD-src-0a58f658fe814a5f8d328c8b40fb24f0300a6878.zip
FreeBSD-src-0a58f658fe814a5f8d328c8b40fb24f0300a6878.tar.gz
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).
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_input.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index b638c0e..153a650 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -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;
}
OpenPOWER on IntegriCloud