diff options
author | Sam Leffler <sam@FreeBSD.org> | 2009-06-03 23:33:09 +0000 |
---|---|---|
committer | Sam Leffler <sam@FreeBSD.org> | 2009-06-03 23:33:09 +0000 |
commit | 7131987ded7cb7a84d8d99f417732f22d2527739 (patch) | |
tree | 44f62b68ce9fe0c15e1bb21fc9f6d584807443ee /sys/net80211/ieee80211_hostap.c | |
parent | 4e15098821360ed9e09ee9fb518c4a101b4191c0 (diff) | |
download | src-7131987ded7cb7a84d8d99f417732f22d2527739.tar.gz src-7131987ded7cb7a84d8d99f417732f22d2527739.zip |
When a channel switch is done to a channel with different operating
characteristics force the stations to re-associate so protocol state
is re-initialized. Note that for 11h/DFS this is irrelevant as channel
changes are never cross-band.
Reviewed by: ctlaw
Notes
Notes:
svn path=/head/; revision=193414
Diffstat (limited to 'sys/net80211/ieee80211_hostap.c')
-rw-r--r-- | sys/net80211/ieee80211_hostap.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 5d9c8e455102..625ee98cce03 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -127,6 +127,28 @@ sta_csa(void *arg, struct ieee80211_node *ni) } } +static void +sta_drop(void *arg, struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = arg; + + if (ni->ni_vap == vap && ni->ni_associd != 0) + ieee80211_node_leave(ni); +} + +/* + * Does a channel change require associated stations to re-associate + * so protocol state is correct. This is used when doing CSA across + * bands or similar (e.g. HT -> legacy). + */ +static int +isbandchange(struct ieee80211com *ic) +{ + return ((ic->ic_bsschan->ic_flags ^ ic->ic_csa_newchan->ic_flags) & + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_HALF | + IEEE80211_CHAN_QUARTER | IEEE80211_CHAN_HT)) != 0; +} + /* * IEEE80211_M_HOSTAP vap state machine handler. */ @@ -307,6 +329,18 @@ hostap_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) } ieee80211_node_authorize(vap->iv_bss); break; + case IEEE80211_S_CSA: + if (ostate == IEEE80211_S_RUN && isbandchange(ic)) { + /* + * On a ``band change'' silently drop associated + * stations as they must re-associate before they + * can pass traffic (as otherwise protocol state + * such as capabilities and the negotiated rate + * set may/will be wrong). + */ + ieee80211_iterate_nodes(&ic->ic_sta, sta_drop, vap); + } + break; default: break; } |