diff options
author | sam <sam@FreeBSD.org> | 2004-04-02 23:35:24 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2004-04-02 23:35:24 +0000 |
commit | 0a58f658fe814a5f8d328c8b40fb24f0300a6878 (patch) | |
tree | d8b1cfc2865de97907e8c23ac0bfa1cb8b719fb2 /sys | |
parent | da8204db05d94e4c8b1c528ca58309754394bd43 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/net80211/ieee80211_input.c | 29 |
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; } |