diff options
author | Arik Nemtsov <arik@wizery.com> | 2014-06-11 10:18:22 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-06-23 08:24:55 -0400 |
commit | 2fb6b9b8e5f08df31bc4081b4d9f38701c59cfd3 (patch) | |
tree | ec373267cf6f234c4697d6c6c4b2323184b4547a /net/mac80211 | |
parent | 31fa97c5defca3895dc6c823096d7ba59df76125 (diff) |
mac80211: use TDLS initiator in tdls_mgmt operations
The TDLS initiator is set once during link setup. If determines the
address ordering in the link identifier IE.
Use the value from userspace in order to have a correct teardown packet.
With the current code, a teardown from the responder side fails the TDLS
MIC check because of a bad link identifier IE.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/tdls.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 0b3ca2ce7ea4..c4a9af3b75e5 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -193,13 +193,14 @@ static int | |||
193 | ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | 193 | ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, |
194 | const u8 *peer, u8 action_code, | 194 | const u8 *peer, u8 action_code, |
195 | u8 dialog_token, u16 status_code, | 195 | u8 dialog_token, u16 status_code, |
196 | u32 peer_capability, const u8 *extra_ies, | 196 | u32 peer_capability, bool initiator, |
197 | size_t extra_ies_len) | 197 | const u8 *extra_ies, size_t extra_ies_len) |
198 | { | 198 | { |
199 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 199 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
200 | struct ieee80211_local *local = sdata->local; | 200 | struct ieee80211_local *local = sdata->local; |
201 | struct sk_buff *skb = NULL; | 201 | struct sk_buff *skb = NULL; |
202 | bool send_direct; | 202 | bool send_direct; |
203 | const u8 *init_addr, *rsp_addr; | ||
203 | int ret; | 204 | int ret; |
204 | 205 | ||
205 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 206 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
@@ -242,27 +243,42 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
242 | if (extra_ies_len) | 243 | if (extra_ies_len) |
243 | memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); | 244 | memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); |
244 | 245 | ||
245 | /* the TDLS link IE is always added last */ | 246 | /* sanity check for initiator */ |
246 | switch (action_code) { | 247 | switch (action_code) { |
247 | case WLAN_TDLS_SETUP_REQUEST: | 248 | case WLAN_TDLS_SETUP_REQUEST: |
248 | case WLAN_TDLS_SETUP_CONFIRM: | 249 | case WLAN_TDLS_SETUP_CONFIRM: |
249 | case WLAN_TDLS_TEARDOWN: | ||
250 | case WLAN_TDLS_DISCOVERY_REQUEST: | 250 | case WLAN_TDLS_DISCOVERY_REQUEST: |
251 | /* we are the initiator */ | 251 | if (!initiator) { |
252 | ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, | 252 | ret = -EINVAL; |
253 | sdata->u.mgd.bssid); | 253 | goto fail; |
254 | } | ||
254 | break; | 255 | break; |
255 | case WLAN_TDLS_SETUP_RESPONSE: | 256 | case WLAN_TDLS_SETUP_RESPONSE: |
256 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: | 257 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: |
257 | /* we are the responder */ | 258 | if (initiator) { |
258 | ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, | 259 | ret = -EINVAL; |
259 | sdata->u.mgd.bssid); | 260 | goto fail; |
261 | } | ||
262 | break; | ||
263 | case WLAN_TDLS_TEARDOWN: | ||
264 | /* any value is ok */ | ||
260 | break; | 265 | break; |
261 | default: | 266 | default: |
262 | ret = -ENOTSUPP; | 267 | ret = -ENOTSUPP; |
263 | goto fail; | 268 | goto fail; |
264 | } | 269 | } |
265 | 270 | ||
271 | if (initiator) { | ||
272 | init_addr = sdata->vif.addr; | ||
273 | rsp_addr = peer; | ||
274 | } else { | ||
275 | init_addr = peer; | ||
276 | rsp_addr = sdata->vif.addr; | ||
277 | } | ||
278 | |||
279 | ieee80211_tdls_add_link_ie(skb, init_addr, rsp_addr, | ||
280 | sdata->u.mgd.bssid); | ||
281 | |||
266 | if (send_direct) { | 282 | if (send_direct) { |
267 | ieee80211_tx_skb(sdata, skb); | 283 | ieee80211_tx_skb(sdata, skb); |
268 | return 0; | 284 | return 0; |
@@ -327,8 +343,8 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
327 | 343 | ||
328 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 344 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
329 | dialog_token, status_code, | 345 | dialog_token, status_code, |
330 | peer_capability, extra_ies, | 346 | peer_capability, initiator, |
331 | extra_ies_len); | 347 | extra_ies, extra_ies_len); |
332 | if (ret < 0) | 348 | if (ret < 0) |
333 | goto exit; | 349 | goto exit; |
334 | 350 | ||