aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ieee80211.h6
-rw-r--r--net/mac80211/mlme.c31
-rw-r--r--net/mac80211/rx.c16
3 files changed, 49 insertions, 4 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 95621528436c..ce07161c8735 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -866,6 +866,11 @@ struct ieee80211_mgmt {
866 } __packed chan_switch; 866 } __packed chan_switch;
867 struct{ 867 struct{
868 u8 action_code; 868 u8 action_code;
869 struct ieee80211_ext_chansw_ie data;
870 u8 variable[0];
871 } __packed ext_chan_switch;
872 struct{
873 u8 action_code;
869 u8 dialog_token; 874 u8 dialog_token;
870 u8 element_id; 875 u8 element_id;
871 u8 length; 876 u8 length;
@@ -1816,6 +1821,7 @@ enum ieee80211_key_len {
1816 1821
1817/* Public action codes */ 1822/* Public action codes */
1818enum ieee80211_pub_actioncode { 1823enum ieee80211_pub_actioncode {
1824 WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
1819 WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14, 1825 WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14,
1820}; 1826};
1821 1827
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 }
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e9825f15c14c..643fcf7c9dcd 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2424,6 +2424,22 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2424 } 2424 }
2425 2425
2426 break; 2426 break;
2427 case WLAN_CATEGORY_PUBLIC:
2428 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2429 goto invalid;
2430 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2431 break;
2432 if (!rx->sta)
2433 break;
2434 if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid))
2435 break;
2436 if (mgmt->u.action.u.ext_chan_switch.action_code !=
2437 WLAN_PUB_ACTION_EXT_CHANSW_ANN)
2438 break;
2439 if (len < offsetof(struct ieee80211_mgmt,
2440 u.action.u.ext_chan_switch.variable))
2441 goto invalid;
2442 goto queue;
2427 case WLAN_CATEGORY_VHT: 2443 case WLAN_CATEGORY_VHT:
2428 if (sdata->vif.type != NL80211_IFTYPE_STATION && 2444 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
2429 sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 2445 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&