| 1 | Patch adapted from ubnt madwifi patchset |
| 2 | |
| 3 | --- a/net80211/ieee80211_node.c |
| 4 | +++ b/net80211/ieee80211_node.c |
| 5 | @@ -659,7 +659,7 @@ ieee80211_sta_join1(struct ieee80211_nod |
| 6 | */ |
| 7 | if (canreassoc) { |
| 8 | vap->iv_nsparams.newstate = IEEE80211_S_ASSOC; |
| 9 | - vap->iv_nsparams.arg = 0; |
| 10 | + vap->iv_nsparams.arg = IEEE80211_FC0_SUBTYPE_REASSOC_REQ; |
| 11 | IEEE80211_SCHEDULE_TQUEUE(&vap->iv_stajoin1tq); |
| 12 | } else { |
| 13 | vap->iv_nsparams.newstate = IEEE80211_S_AUTH; |
| 14 | --- a/net80211/ieee80211_scan_sta.c |
| 15 | +++ b/net80211/ieee80211_scan_sta.c |
| 16 | @@ -748,14 +748,17 @@ notfound: |
| 17 | * a reference to an entry w/o holding the lock on the table. |
| 18 | */ |
| 19 | static struct sta_entry * |
| 20 | -sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN]) |
| 21 | +sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_scan_ssid* essid) |
| 22 | { |
| 23 | struct sta_entry *se; |
| 24 | int hash = STA_HASH(macaddr); |
| 25 | |
| 26 | SCAN_STA_LOCK_IRQ(st); |
| 27 | LIST_FOREACH(se, &st->st_hash[hash], se_hash) |
| 28 | - if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) |
| 29 | + if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) && |
| 30 | + (essid->len == se->base.se_ssid[1] && |
| 31 | + !memcmp(se->base.se_ssid+2, essid->ssid, |
| 32 | + se->base.se_ssid[1]))) |
| 33 | break; |
| 34 | SCAN_STA_UNLOCK_IRQ(st); |
| 35 | |
| 36 | @@ -772,7 +775,7 @@ sta_roam_check(struct ieee80211_scan_sta |
| 37 | u_int8_t roamRate, curRate; |
| 38 | int8_t roamRssi, curRssi; |
| 39 | |
| 40 | - se = sta_lookup(st, ni->ni_macaddr); |
| 41 | + se = sta_lookup(st, ni->ni_macaddr, ss->ss_ssid); |
| 42 | if (se == NULL) { |
| 43 | /* XXX something is wrong */ |
| 44 | return; |
| 45 | @@ -866,8 +869,8 @@ sta_age(struct ieee80211_scan_state *ss) |
| 46 | */ |
| 47 | KASSERT(vap->iv_opmode == IEEE80211_M_STA, |
| 48 | ("wrong mode %u", vap->iv_opmode)); |
| 49 | - /* XXX turn this off until the ap release is cut */ |
| 50 | - if (0 && vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO && |
| 51 | + if (vap->iv_opmode == IEEE80211_M_STA && |
| 52 | + vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO && |
| 53 | vap->iv_state >= IEEE80211_S_RUN) |
| 54 | /* XXX vap is implicit */ |
| 55 | sta_roam_check(ss, vap); |
| 56 | @@ -922,7 +925,11 @@ sta_assoc_fail(struct ieee80211_scan_sta |
| 57 | struct sta_table *st = ss->ss_priv; |
| 58 | struct sta_entry *se; |
| 59 | |
| 60 | - se = sta_lookup(st, macaddr); |
| 61 | + /* Let outside apps to decide what peer is blacklisted */ |
| 62 | + if (ss->ss_vap->iv_ic->ic_roaming == IEEE80211_ROAMING_MANUAL) |
| 63 | + return; |
| 64 | + |
| 65 | + se = sta_lookup(st, macaddr, ss->ss_ssid); |
| 66 | if (se != NULL) { |
| 67 | se->se_fails++; |
| 68 | se->se_lastfail = jiffies; |
| 69 | @@ -939,7 +946,7 @@ sta_assoc_success(struct ieee80211_scan_ |
| 70 | struct sta_table *st = ss->ss_priv; |
| 71 | struct sta_entry *se; |
| 72 | |
| 73 | - se = sta_lookup(st, macaddr); |
| 74 | + se = sta_lookup(st, macaddr, ss->ss_ssid); |
| 75 | if (se != NULL) { |
| 76 | #if 0 |
| 77 | se->se_fails = 0; |
| 78 | |