Patch adapted from ubnt madwifi patchset --- a/net80211/ieee80211_node.c +++ b/net80211/ieee80211_node.c @@ -659,7 +659,7 @@ ieee80211_sta_join1(struct ieee80211_nod */ if (canreassoc) { vap->iv_nsparams.newstate = IEEE80211_S_ASSOC; - vap->iv_nsparams.arg = 0; + vap->iv_nsparams.arg = IEEE80211_FC0_SUBTYPE_REASSOC_REQ; IEEE80211_SCHEDULE_TQUEUE(&vap->iv_stajoin1tq); } else { vap->iv_nsparams.newstate = IEEE80211_S_AUTH; --- a/net80211/ieee80211_scan_sta.c +++ b/net80211/ieee80211_scan_sta.c @@ -748,14 +748,17 @@ notfound: * a reference to an entry w/o holding the lock on the table. */ static struct sta_entry * -sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN]) +sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_scan_ssid* essid) { struct sta_entry *se; int hash = STA_HASH(macaddr); SCAN_STA_LOCK_IRQ(st); LIST_FOREACH(se, &st->st_hash[hash], se_hash) - if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) + if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) && + (essid->len == se->base.se_ssid[1] && + !memcmp(se->base.se_ssid+2, essid->ssid, + se->base.se_ssid[1]))) break; SCAN_STA_UNLOCK_IRQ(st); @@ -772,7 +775,7 @@ sta_roam_check(struct ieee80211_scan_sta u_int8_t roamRate, curRate; int8_t roamRssi, curRssi; - se = sta_lookup(st, ni->ni_macaddr); + se = sta_lookup(st, ni->ni_macaddr, ss->ss_ssid); if (se == NULL) { /* XXX something is wrong */ return; @@ -866,8 +869,8 @@ sta_age(struct ieee80211_scan_state *ss) */ KASSERT(vap->iv_opmode == IEEE80211_M_STA, ("wrong mode %u", vap->iv_opmode)); - /* XXX turn this off until the ap release is cut */ - if (0 && vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO && + if (vap->iv_opmode == IEEE80211_M_STA && + vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO && vap->iv_state >= IEEE80211_S_RUN) /* XXX vap is implicit */ sta_roam_check(ss, vap); @@ -922,7 +925,11 @@ sta_assoc_fail(struct ieee80211_scan_sta struct sta_table *st = ss->ss_priv; struct sta_entry *se; - se = sta_lookup(st, macaddr); + /* Let outside apps to decide what peer is blacklisted */ + if (ss->ss_vap->iv_ic->ic_roaming == IEEE80211_ROAMING_MANUAL) + return; + + se = sta_lookup(st, macaddr, ss->ss_ssid); if (se != NULL) { se->se_fails++; se->se_lastfail = jiffies; @@ -939,7 +946,7 @@ sta_assoc_success(struct ieee80211_scan_ struct sta_table *st = ss->ss_priv; struct sta_entry *se; - se = sta_lookup(st, macaddr); + se = sta_lookup(st, macaddr, ss->ss_ssid); if (se != NULL) { #if 0 se->se_fails = 0;