summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-26 10:17:18 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-04-16 09:29:45 -0400
commit1b3a2e494bc793445f576c5476e9767cf7621684 (patch)
tree0a42b6e5a98e1e6a686c500661db79ae092f336d /net/mac80211/mlme.c
parent85220d71bf3ca1ba9129e0744247ae5f61bec559 (diff)
mac80211: handle extended channel switch announcement
Handle the (public) extended channel switch announcement action frames. Parts of the data in these frames isn't really in IEs, but put it into the elems struct anyway to simplify the handling. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index bd581a80e4b7..c53aedb47a6a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3100,6 +3100,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3100 enum rx_mgmt_action rma = RX_MGMT_NONE; 3100 enum rx_mgmt_action rma = RX_MGMT_NONE;
3101 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; 3101 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
3102 u16 fc; 3102 u16 fc;
3103 struct ieee802_11_elems elems;
3104 int ies_len;
3103 3105
3104 rx_status = (struct ieee80211_rx_status *) skb->cb; 3106 rx_status = (struct ieee80211_rx_status *) skb->cb;
3105 mgmt = (struct ieee80211_mgmt *) skb->data; 3107 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -3130,10 +3132,9 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3130 break; 3132 break;
3131 case IEEE80211_STYPE_ACTION: 3133 case IEEE80211_STYPE_ACTION:
3132 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { 3134 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
3133 struct ieee802_11_elems elems; 3135 ies_len = skb->len -
3134 int ies_len = skb->len - 3136 offsetof(struct ieee80211_mgmt,
3135 offsetof(struct ieee80211_mgmt, 3137 u.action.u.chan_switch.variable);
3136 u.action.u.chan_switch.variable);
3137 3138
3138 if (ies_len < 0) 3139 if (ies_len < 0)
3139 break; 3140 break;
@@ -3148,6 +3149,28 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3148 ieee80211_sta_process_chanswitch(sdata, 3149 ieee80211_sta_process_chanswitch(sdata,
3149 rx_status->mactime, 3150 rx_status->mactime,
3150 &elems); 3151 &elems);
3152 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
3153 ies_len = skb->len -
3154 offsetof(struct ieee80211_mgmt,
3155 u.action.u.ext_chan_switch.variable);
3156
3157 if (ies_len < 0)
3158 break;
3159
3160 ieee802_11_parse_elems(
3161 mgmt->u.action.u.ext_chan_switch.variable,
3162 ies_len, &elems);
3163
3164 if (elems.parse_error)
3165 break;
3166
3167 /* for the handling code pretend this was also an IE */
3168 elems.ext_chansw_ie =
3169 &mgmt->u.action.u.ext_chan_switch.data;
3170
3171 ieee80211_sta_process_chanswitch(sdata,
3172 rx_status->mactime,
3173 &elems);
3151 } 3174 }
3152 break; 3175 break;
3153 } 3176 }