aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2014-06-11 10:18:22 -0400
committerJohannes Berg <johannes.berg@intel.com>2014-06-23 08:24:55 -0400
commit2fb6b9b8e5f08df31bc4081b4d9f38701c59cfd3 (patch)
treeec373267cf6f234c4697d6c6c4b2323184b4547a /net/mac80211
parent31fa97c5defca3895dc6c823096d7ba59df76125 (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.c40
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
193ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, 193ieee80211_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