Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: Do not disconnect on invalid operating class

Some APs include a non global operating class in their extended channel
switch information element. In such a case, as the operating class is not
known, mac80211 would decide to disconnect.

However the specification states that the operating class needs to be
taken from Annex E, but it does not specify from which table it should be
taken, so it is valid for an AP to use a non global operating class.

To avoid possibly unneeded disconnection, in such a case ignore the
operating class and assume that the current band is used, and if the
resulting channel and band configuration is invalid disconnect.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Ilan Peer and committed by
Johannes Berg
191da271 3027a8e7

+3 -4
+3 -4
net/mac80211/spectmgmt.c
··· 8 8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 9 9 * Copyright 2007-2008, Intel Corporation 10 10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 11 + * Copyright (C) 2018 Intel Corporation 11 12 * 12 13 * This program is free software; you can redistribute it and/or modify 13 14 * it under the terms of the GNU General Public License version 2 as ··· 28 27 u32 sta_flags, u8 *bssid, 29 28 struct ieee80211_csa_ie *csa_ie) 30 29 { 31 - enum nl80211_band new_band; 30 + enum nl80211_band new_band = current_band; 32 31 int new_freq; 33 32 u8 new_chan_no; 34 33 struct ieee80211_channel *new_chan; ··· 56 55 elems->ext_chansw_ie->new_operating_class, 57 56 &new_band)) { 58 57 sdata_info(sdata, 59 - "cannot understand ECSA IE operating class %d, disconnecting\n", 58 + "cannot understand ECSA IE operating class, %d, ignoring\n", 60 59 elems->ext_chansw_ie->new_operating_class); 61 - return -EINVAL; 62 60 } 63 61 new_chan_no = elems->ext_chansw_ie->new_ch_num; 64 62 csa_ie->count = elems->ext_chansw_ie->count; 65 63 csa_ie->mode = elems->ext_chansw_ie->mode; 66 64 } else if (elems->ch_switch_ie) { 67 - new_band = current_band; 68 65 new_chan_no = elems->ch_switch_ie->new_ch_num; 69 66 csa_ie->count = elems->ch_switch_ie->count; 70 67 csa_ie->mode = elems->ch_switch_ie->mode;