mac80211: add support for CSA in IBSS mode

This function adds the channel switch announcement implementation for the
IBSS code. It is triggered by userspace (mac80211/cfg) or by external
channel switch announcement, which have to be adopted. Both CSAs in
beacons and action frames are supported. As for AP mode, the channel
switch is applied after some time. However in IBSS mode, the channel
switch IEs are generated in the kernel.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Simon Wunderlich 2013-08-28 13:41:31 +02:00 committed by Johannes Berg
parent 871a4180b8
commit cd7760e62c
6 changed files with 482 additions and 45 deletions

View file

@ -2402,7 +2402,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
return RX_DROP_UNUSABLE;
if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC &&
mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED)
mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED &&
mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT)
return RX_DROP_UNUSABLE;
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
@ -2566,31 +2567,46 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
goto queue;
case WLAN_CATEGORY_SPECTRUM_MGMT:
if (status->band != IEEE80211_BAND_5GHZ)
break;
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
/* verify action_code is present */
if (len < IEEE80211_MIN_ACTION_SIZE + 1)
break;
switch (mgmt->u.action.u.measurement.action_code) {
case WLAN_ACTION_SPCT_MSR_REQ:
if (status->band != IEEE80211_BAND_5GHZ)
break;
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.measurement)))
break;
ieee80211_process_measurement_req(sdata, mgmt, len);
goto handled;
case WLAN_ACTION_SPCT_CHL_SWITCH:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid))
ieee80211_process_measurement_req(sdata, mgmt, len);
goto handled;
case WLAN_ACTION_SPCT_CHL_SWITCH: {
u8 *bssid;
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.chan_switch)))
break;
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_ADHOC)
break;
if (sdata->vif.type == NL80211_IFTYPE_STATION)
bssid = sdata->u.mgd.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
bssid = sdata->u.ibss.bssid;
else
break;
if (!ether_addr_equal(mgmt->bssid, bssid))
break;
goto queue;
}
}
break;
case WLAN_CATEGORY_SA_QUERY: