]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/mac80211/tdls.c
mac80211: add parsing of TDLS specific IEs
[mirror_ubuntu-jammy-kernel.git] / net / mac80211 / tdls.c
CommitLineData
95224fe8
AN
1/*
2 * mac80211 TDLS handling code
3 *
4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2014, Intel Corporation
d98ad83e 6 * Copyright 2014 Intel Mobile Communications GmbH
95224fe8
AN
7 *
8 * This file is GPLv2 as found in COPYING.
9 */
10
11#include <linux/ieee80211.h>
6f7eaa47 12#include <linux/log2.h>
c887f0d3 13#include <net/cfg80211.h>
95224fe8 14#include "ieee80211_i.h"
ee10f2c7 15#include "driver-ops.h"
95224fe8 16
17e6a59a
AN
17/* give usermode some time for retries in setting up the TDLS session */
18#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
19
20void ieee80211_tdls_peer_del_work(struct work_struct *wk)
21{
22 struct ieee80211_sub_if_data *sdata;
23 struct ieee80211_local *local;
24
25 sdata = container_of(wk, struct ieee80211_sub_if_data,
81dd2b88 26 u.mgd.tdls_peer_del_work.work);
17e6a59a
AN
27 local = sdata->local;
28
29 mutex_lock(&local->mtx);
81dd2b88
AN
30 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer)) {
31 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->u.mgd.tdls_peer);
32 sta_info_destroy_addr(sdata, sdata->u.mgd.tdls_peer);
33 eth_zero_addr(sdata->u.mgd.tdls_peer);
17e6a59a
AN
34 }
35 mutex_unlock(&local->mtx);
36}
37
78632a17
AN
38static void ieee80211_tdls_add_ext_capab(struct ieee80211_local *local,
39 struct sk_buff *skb)
95224fe8
AN
40{
41 u8 *pos = (void *)skb_put(skb, 7);
78632a17
AN
42 bool chan_switch = local->hw.wiphy->features &
43 NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
95224fe8
AN
44
45 *pos++ = WLAN_EID_EXT_CAPABILITY;
46 *pos++ = 5; /* len */
47 *pos++ = 0x0;
48 *pos++ = 0x0;
49 *pos++ = 0x0;
78632a17 50 *pos++ = chan_switch ? WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH : 0;
95224fe8
AN
51 *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
52}
53
f0d29cb9
AN
54static u8
55ieee80211_tdls_add_subband(struct ieee80211_sub_if_data *sdata,
56 struct sk_buff *skb, u16 start, u16 end,
57 u16 spacing)
58{
59 u8 subband_cnt = 0, ch_cnt = 0;
60 struct ieee80211_channel *ch;
61 struct cfg80211_chan_def chandef;
62 int i, subband_start;
63
64 for (i = start; i <= end; i += spacing) {
65 if (!ch_cnt)
66 subband_start = i;
67
68 ch = ieee80211_get_channel(sdata->local->hw.wiphy, i);
69 if (ch) {
70 /* we will be active on the channel */
71 u32 flags = IEEE80211_CHAN_DISABLED |
72 IEEE80211_CHAN_NO_IR;
73 cfg80211_chandef_create(&chandef, ch,
74 NL80211_CHAN_HT20);
75 if (cfg80211_chandef_usable(sdata->local->hw.wiphy,
76 &chandef, flags)) {
77 ch_cnt++;
78 continue;
79 }
80 }
81
82 if (ch_cnt) {
83 u8 *pos = skb_put(skb, 2);
84 *pos++ = ieee80211_frequency_to_channel(subband_start);
85 *pos++ = ch_cnt;
86
87 subband_cnt++;
88 ch_cnt = 0;
89 }
90 }
91
92 return subband_cnt;
93}
94
95static void
96ieee80211_tdls_add_supp_channels(struct ieee80211_sub_if_data *sdata,
97 struct sk_buff *skb)
98{
99 /*
100 * Add possible channels for TDLS. These are channels that are allowed
101 * to be active.
102 */
103 u8 subband_cnt;
104 u8 *pos = skb_put(skb, 2);
105
106 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
107
108 /*
109 * 5GHz and 2GHz channels numbers can overlap. Ignore this for now, as
110 * this doesn't happen in real world scenarios.
111 */
112
113 /* 2GHz, with 5MHz spacing */
114 subband_cnt = ieee80211_tdls_add_subband(sdata, skb, 2412, 2472, 5);
115
116 /* 5GHz, with 20MHz spacing */
117 subband_cnt += ieee80211_tdls_add_subband(sdata, skb, 5000, 5825, 20);
118
119 /* length */
120 *pos = 2 * subband_cnt;
121}
122
2cedd879
AN
123static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb)
124{
125 u8 *pos = (void *)skb_put(skb, 3);
126
127 *pos++ = WLAN_EID_BSS_COEX_2040;
128 *pos++ = 1; /* len */
129
130 *pos++ = WLAN_BSS_COEX_INFORMATION_REQUEST;
131}
132
dd8c0b03
AN
133static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
134 u16 status_code)
95224fe8
AN
135{
136 struct ieee80211_local *local = sdata->local;
137 u16 capab;
138
dd8c0b03
AN
139 /* The capability will be 0 when sending a failure code */
140 if (status_code != 0)
141 return 0;
142
95224fe8
AN
143 capab = 0;
144 if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ)
145 return capab;
146
147 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
148 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
149 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
150 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
151
152 return capab;
153}
154
1606ef4a
AN
155static void ieee80211_tdls_add_link_ie(struct ieee80211_sub_if_data *sdata,
156 struct sk_buff *skb, const u8 *peer,
157 bool initiator)
95224fe8
AN
158{
159 struct ieee80211_tdls_lnkie *lnkid;
1606ef4a
AN
160 const u8 *init_addr, *rsp_addr;
161
162 if (initiator) {
163 init_addr = sdata->vif.addr;
164 rsp_addr = peer;
165 } else {
166 init_addr = peer;
167 rsp_addr = sdata->vif.addr;
168 }
95224fe8
AN
169
170 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
171
172 lnkid->ie_type = WLAN_EID_LINK_ID;
173 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
174
1606ef4a
AN
175 memcpy(lnkid->bssid, sdata->u.mgd.bssid, ETH_ALEN);
176 memcpy(lnkid->init_sta, init_addr, ETH_ALEN);
177 memcpy(lnkid->resp_sta, rsp_addr, ETH_ALEN);
95224fe8
AN
178}
179
6f7eaa47
AN
180/* translate numbering in the WMM parameter IE to the mac80211 notation */
181static enum ieee80211_ac_numbers ieee80211_ac_from_wmm(int ac)
182{
183 switch (ac) {
184 default:
185 WARN_ON_ONCE(1);
186 case 0:
187 return IEEE80211_AC_BE;
188 case 1:
189 return IEEE80211_AC_BK;
190 case 2:
191 return IEEE80211_AC_VI;
192 case 3:
193 return IEEE80211_AC_VO;
194 }
195}
196
197static u8 ieee80211_wmm_aci_aifsn(int aifsn, bool acm, int aci)
198{
199 u8 ret;
200
201 ret = aifsn & 0x0f;
202 if (acm)
203 ret |= 0x10;
204 ret |= (aci << 5) & 0x60;
205 return ret;
206}
207
208static u8 ieee80211_wmm_ecw(u16 cw_min, u16 cw_max)
209{
210 return ((ilog2(cw_min + 1) << 0x0) & 0x0f) |
211 ((ilog2(cw_max + 1) << 0x4) & 0xf0);
212}
213
214static void ieee80211_tdls_add_wmm_param_ie(struct ieee80211_sub_if_data *sdata,
215 struct sk_buff *skb)
216{
217 struct ieee80211_wmm_param_ie *wmm;
218 struct ieee80211_tx_queue_params *txq;
219 int i;
220
221 wmm = (void *)skb_put(skb, sizeof(*wmm));
222 memset(wmm, 0, sizeof(*wmm));
223
224 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
225 wmm->len = sizeof(*wmm) - 2;
226
227 wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
228 wmm->oui[1] = 0x50;
229 wmm->oui[2] = 0xf2;
230 wmm->oui_type = 2; /* WME */
231 wmm->oui_subtype = 1; /* WME param */
232 wmm->version = 1; /* WME ver */
233 wmm->qos_info = 0; /* U-APSD not in use */
234
235 /*
236 * Use the EDCA parameters defined for the BSS, or default if the AP
237 * doesn't support it, as mandated by 802.11-2012 section 10.22.4
238 */
239 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
240 txq = &sdata->tx_conf[ieee80211_ac_from_wmm(i)];
241 wmm->ac[i].aci_aifsn = ieee80211_wmm_aci_aifsn(txq->aifs,
242 txq->acm, i);
243 wmm->ac[i].cw = ieee80211_wmm_ecw(txq->cw_min, txq->cw_max);
244 wmm->ac[i].txop_limit = cpu_to_le16(txq->txop);
245 }
246}
247
f09a87d2
AN
248static void
249ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
250 struct sk_buff *skb, const u8 *peer,
1606ef4a
AN
251 u8 action_code, bool initiator,
252 const u8 *extra_ies, size_t extra_ies_len)
f09a87d2
AN
253{
254 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
40b861a0 255 struct ieee80211_local *local = sdata->local;
13cc8a4a
AN
256 struct ieee80211_supported_band *sband;
257 struct ieee80211_sta_ht_cap ht_cap;
258 struct sta_info *sta = NULL;
f09a87d2
AN
259 size_t offset = 0, noffset;
260 u8 *pos;
261
13cc8a4a
AN
262 rcu_read_lock();
263
264 /* we should have the peer STA if we're already responding */
265 if (action_code == WLAN_TDLS_SETUP_RESPONSE) {
266 sta = sta_info_get(sdata, peer);
267 if (WARN_ON_ONCE(!sta)) {
268 rcu_read_unlock();
269 return;
270 }
271 }
272
f09a87d2
AN
273 ieee80211_add_srates_ie(sdata, skb, false, band);
274 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
f0d29cb9 275 ieee80211_tdls_add_supp_channels(sdata, skb);
f09a87d2
AN
276
277 /* add any custom IEs that go before Extended Capabilities */
278 if (extra_ies_len) {
279 static const u8 before_ext_cap[] = {
280 WLAN_EID_SUPP_RATES,
281 WLAN_EID_COUNTRY,
282 WLAN_EID_EXT_SUPP_RATES,
283 WLAN_EID_SUPPORTED_CHANNELS,
284 WLAN_EID_RSN,
285 };
286 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
287 before_ext_cap,
288 ARRAY_SIZE(before_ext_cap),
289 offset);
290 pos = skb_put(skb, noffset - offset);
291 memcpy(pos, extra_ies + offset, noffset - offset);
292 offset = noffset;
293 }
294
78632a17 295 ieee80211_tdls_add_ext_capab(local, skb);
f09a87d2 296
40b861a0
AN
297 /* add the QoS element if we support it */
298 if (local->hw.queues >= IEEE80211_NUM_ACS &&
299 action_code != WLAN_PUB_ACTION_TDLS_DISCOVER_RES)
300 ieee80211_add_wmm_info_ie(skb_put(skb, 9), 0); /* no U-APSD */
301
f09a87d2
AN
302 /* add any custom IEs that go before HT capabilities */
303 if (extra_ies_len) {
304 static const u8 before_ht_cap[] = {
305 WLAN_EID_SUPP_RATES,
306 WLAN_EID_COUNTRY,
307 WLAN_EID_EXT_SUPP_RATES,
308 WLAN_EID_SUPPORTED_CHANNELS,
309 WLAN_EID_RSN,
310 WLAN_EID_EXT_CAPABILITY,
311 WLAN_EID_QOS_CAPA,
312 WLAN_EID_FAST_BSS_TRANSITION,
313 WLAN_EID_TIMEOUT_INTERVAL,
314 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
315 };
316 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
317 before_ht_cap,
318 ARRAY_SIZE(before_ht_cap),
319 offset);
320 pos = skb_put(skb, noffset - offset);
321 memcpy(pos, extra_ies + offset, noffset - offset);
322 offset = noffset;
323 }
324
13cc8a4a
AN
325 /*
326 * with TDLS we can switch channels, and HT-caps are not necessarily
327 * the same on all bands. The specification limits the setup to a
328 * single HT-cap, so use the current band for now.
329 */
330 sband = local->hw.wiphy->bands[band];
331 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
332 if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
333 action_code == WLAN_TDLS_SETUP_RESPONSE) &&
334 ht_cap.ht_supported && (!sta || sta->sta.ht_cap.ht_supported)) {
335 if (action_code == WLAN_TDLS_SETUP_REQUEST) {
336 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
337
338 /* disable SMPS in TDLS initiator */
339 ht_cap.cap |= (WLAN_HT_CAP_SM_PS_DISABLED
340 << IEEE80211_HT_CAP_SM_PS_SHIFT);
341 } else {
342 /* disable SMPS in TDLS responder */
343 sta->sta.ht_cap.cap |=
344 (WLAN_HT_CAP_SM_PS_DISABLED
345 << IEEE80211_HT_CAP_SM_PS_SHIFT);
346
347 /* the peer caps are already intersected with our own */
348 memcpy(&ht_cap, &sta->sta.ht_cap, sizeof(ht_cap));
349 }
350
351 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
352 ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
353 }
354
355 rcu_read_unlock();
356
2cedd879
AN
357 if (ht_cap.ht_supported &&
358 (ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
359 ieee80211_tdls_add_bss_coex_ie(skb);
360
f09a87d2
AN
361 /* add any remaining IEs */
362 if (extra_ies_len) {
363 noffset = extra_ies_len;
364 pos = skb_put(skb, noffset - offset);
365 memcpy(pos, extra_ies + offset, noffset - offset);
366 }
1606ef4a
AN
367
368 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
f09a87d2
AN
369}
370
6f7eaa47
AN
371static void
372ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
373 struct sk_buff *skb, const u8 *peer,
374 bool initiator, const u8 *extra_ies,
375 size_t extra_ies_len)
376{
377 struct ieee80211_local *local = sdata->local;
13cc8a4a 378 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6f7eaa47 379 size_t offset = 0, noffset;
13cc8a4a 380 struct sta_info *sta, *ap_sta;
6f7eaa47
AN
381 u8 *pos;
382
383 rcu_read_lock();
384
385 sta = sta_info_get(sdata, peer);
13cc8a4a
AN
386 ap_sta = sta_info_get(sdata, ifmgd->bssid);
387 if (WARN_ON_ONCE(!sta || !ap_sta)) {
6f7eaa47
AN
388 rcu_read_unlock();
389 return;
390 }
391
392 /* add any custom IEs that go before the QoS IE */
393 if (extra_ies_len) {
394 static const u8 before_qos[] = {
395 WLAN_EID_RSN,
396 };
397 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
398 before_qos,
399 ARRAY_SIZE(before_qos),
400 offset);
401 pos = skb_put(skb, noffset - offset);
402 memcpy(pos, extra_ies + offset, noffset - offset);
403 offset = noffset;
404 }
405
406 /* add the QoS param IE if both the peer and we support it */
a74a8c84 407 if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme)
6f7eaa47
AN
408 ieee80211_tdls_add_wmm_param_ie(sdata, skb);
409
13cc8a4a
AN
410 /* add any custom IEs that go before HT operation */
411 if (extra_ies_len) {
412 static const u8 before_ht_op[] = {
413 WLAN_EID_RSN,
414 WLAN_EID_QOS_CAPA,
415 WLAN_EID_FAST_BSS_TRANSITION,
416 WLAN_EID_TIMEOUT_INTERVAL,
417 };
418 noffset = ieee80211_ie_split(extra_ies, extra_ies_len,
419 before_ht_op,
420 ARRAY_SIZE(before_ht_op),
421 offset);
422 pos = skb_put(skb, noffset - offset);
423 memcpy(pos, extra_ies + offset, noffset - offset);
424 offset = noffset;
425 }
426
427 /* if HT support is only added in TDLS, we need an HT-operation IE */
428 if (!ap_sta->sta.ht_cap.ht_supported && sta->sta.ht_cap.ht_supported) {
429 struct ieee80211_chanctx_conf *chanctx_conf =
430 rcu_dereference(sdata->vif.chanctx_conf);
431 if (!WARN_ON(!chanctx_conf)) {
432 pos = skb_put(skb, 2 +
433 sizeof(struct ieee80211_ht_operation));
434 /* send an empty HT operation IE */
435 ieee80211_ie_build_ht_oper(pos, &sta->sta.ht_cap,
436 &chanctx_conf->def, 0);
437 }
438 }
439
440 rcu_read_unlock();
441
6f7eaa47
AN
442 /* add any remaining IEs */
443 if (extra_ies_len) {
444 noffset = extra_ies_len;
445 pos = skb_put(skb, noffset - offset);
446 memcpy(pos, extra_ies + offset, noffset - offset);
447 }
448
449 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
6f7eaa47
AN
450}
451
46792a2d
AN
452static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata,
453 struct sk_buff *skb, const u8 *peer,
1606ef4a
AN
454 u8 action_code, u16 status_code,
455 bool initiator, const u8 *extra_ies,
c2733905
AN
456 size_t extra_ies_len, u8 oper_class,
457 struct cfg80211_chan_def *chandef)
46792a2d 458{
46792a2d
AN
459 switch (action_code) {
460 case WLAN_TDLS_SETUP_REQUEST:
461 case WLAN_TDLS_SETUP_RESPONSE:
462 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
1606ef4a
AN
463 if (status_code == 0)
464 ieee80211_tdls_add_setup_start_ies(sdata, skb, peer,
465 action_code,
466 initiator,
467 extra_ies,
468 extra_ies_len);
46792a2d
AN
469 break;
470 case WLAN_TDLS_SETUP_CONFIRM:
6f7eaa47
AN
471 if (status_code == 0)
472 ieee80211_tdls_add_setup_cfm_ies(sdata, skb, peer,
473 initiator, extra_ies,
474 extra_ies_len);
475 break;
46792a2d
AN
476 case WLAN_TDLS_TEARDOWN:
477 case WLAN_TDLS_DISCOVERY_REQUEST:
f09a87d2
AN
478 if (extra_ies_len)
479 memcpy(skb_put(skb, extra_ies_len), extra_ies,
480 extra_ies_len);
1606ef4a
AN
481 if (status_code == 0 || action_code == WLAN_TDLS_TEARDOWN)
482 ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
46792a2d
AN
483 break;
484 }
485
46792a2d
AN
486}
487
95224fe8
AN
488static int
489ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
3b3a0162 490 const u8 *peer, u8 action_code, u8 dialog_token,
95224fe8
AN
491 u16 status_code, struct sk_buff *skb)
492{
493 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
95224fe8
AN
494 struct ieee80211_tdls_data *tf;
495
496 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
497
498 memcpy(tf->da, peer, ETH_ALEN);
499 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
500 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
501 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
502
59cd85cb
AN
503 /* network header is after the ethernet header */
504 skb_set_network_header(skb, ETH_HLEN);
505
95224fe8
AN
506 switch (action_code) {
507 case WLAN_TDLS_SETUP_REQUEST:
508 tf->category = WLAN_CATEGORY_TDLS;
509 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
510
511 skb_put(skb, sizeof(tf->u.setup_req));
512 tf->u.setup_req.dialog_token = dialog_token;
513 tf->u.setup_req.capability =
dd8c0b03
AN
514 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
515 status_code));
95224fe8
AN
516 break;
517 case WLAN_TDLS_SETUP_RESPONSE:
518 tf->category = WLAN_CATEGORY_TDLS;
519 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
520
521 skb_put(skb, sizeof(tf->u.setup_resp));
522 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
523 tf->u.setup_resp.dialog_token = dialog_token;
524 tf->u.setup_resp.capability =
dd8c0b03
AN
525 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
526 status_code));
95224fe8
AN
527 break;
528 case WLAN_TDLS_SETUP_CONFIRM:
529 tf->category = WLAN_CATEGORY_TDLS;
530 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
531
532 skb_put(skb, sizeof(tf->u.setup_cfm));
533 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
534 tf->u.setup_cfm.dialog_token = dialog_token;
535 break;
536 case WLAN_TDLS_TEARDOWN:
537 tf->category = WLAN_CATEGORY_TDLS;
538 tf->action_code = WLAN_TDLS_TEARDOWN;
539
540 skb_put(skb, sizeof(tf->u.teardown));
541 tf->u.teardown.reason_code = cpu_to_le16(status_code);
542 break;
543 case WLAN_TDLS_DISCOVERY_REQUEST:
544 tf->category = WLAN_CATEGORY_TDLS;
545 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
546
547 skb_put(skb, sizeof(tf->u.discover_req));
548 tf->u.discover_req.dialog_token = dialog_token;
549 break;
550 default:
551 return -EINVAL;
552 }
553
554 return 0;
555}
556
557static int
558ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
3b3a0162 559 const u8 *peer, u8 action_code, u8 dialog_token,
95224fe8
AN
560 u16 status_code, struct sk_buff *skb)
561{
562 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
95224fe8
AN
563 struct ieee80211_mgmt *mgmt;
564
565 mgmt = (void *)skb_put(skb, 24);
566 memset(mgmt, 0, 24);
567 memcpy(mgmt->da, peer, ETH_ALEN);
568 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
569 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
570
571 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
572 IEEE80211_STYPE_ACTION);
573
574 switch (action_code) {
575 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
576 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
577 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
578 mgmt->u.action.u.tdls_discover_resp.action_code =
579 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
580 mgmt->u.action.u.tdls_discover_resp.dialog_token =
581 dialog_token;
582 mgmt->u.action.u.tdls_discover_resp.capability =
dd8c0b03
AN
583 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata,
584 status_code));
95224fe8
AN
585 break;
586 default:
587 return -EINVAL;
588 }
589
590 return 0;
591}
592
c2733905
AN
593static struct sk_buff *
594ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata,
595 const u8 *peer, u8 action_code,
596 u8 dialog_token, u16 status_code,
597 bool initiator, const u8 *extra_ies,
598 size_t extra_ies_len, u8 oper_class,
599 struct cfg80211_chan_def *chandef)
95224fe8 600{
95224fe8 601 struct ieee80211_local *local = sdata->local;
c2733905 602 struct sk_buff *skb;
95224fe8
AN
603 int ret;
604
c2733905 605 skb = netdev_alloc_skb(sdata->dev,
1277b4a9
LK
606 local->hw.extra_tx_headroom +
607 max(sizeof(struct ieee80211_mgmt),
608 sizeof(struct ieee80211_tdls_data)) +
609 50 + /* supported rates */
610 7 + /* ext capab */
611 26 + /* max(WMM-info, WMM-param) */
612 2 + max(sizeof(struct ieee80211_ht_cap),
613 sizeof(struct ieee80211_ht_operation)) +
f0d29cb9 614 50 + /* supported channels */
2cedd879 615 3 + /* 40/20 BSS coex */
1277b4a9
LK
616 extra_ies_len +
617 sizeof(struct ieee80211_tdls_lnkie));
95224fe8 618 if (!skb)
c2733905 619 return NULL;
95224fe8
AN
620
621 skb_reserve(skb, local->hw.extra_tx_headroom);
622
623 switch (action_code) {
624 case WLAN_TDLS_SETUP_REQUEST:
625 case WLAN_TDLS_SETUP_RESPONSE:
626 case WLAN_TDLS_SETUP_CONFIRM:
627 case WLAN_TDLS_TEARDOWN:
628 case WLAN_TDLS_DISCOVERY_REQUEST:
c2733905
AN
629 ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy,
630 sdata->dev, peer,
95224fe8
AN
631 action_code, dialog_token,
632 status_code, skb);
95224fe8
AN
633 break;
634 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
c2733905
AN
635 ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev,
636 peer, action_code,
95224fe8
AN
637 dialog_token, status_code,
638 skb);
95224fe8
AN
639 break;
640 default:
641 ret = -ENOTSUPP;
642 break;
643 }
644
645 if (ret < 0)
646 goto fail;
647
c2733905
AN
648 ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
649 initiator, extra_ies, extra_ies_len, oper_class,
650 chandef);
651 return skb;
652
653fail:
654 dev_kfree_skb(skb);
655 return NULL;
656}
657
658static int
659ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
660 const u8 *peer, u8 action_code, u8 dialog_token,
661 u16 status_code, u32 peer_capability,
662 bool initiator, const u8 *extra_ies,
663 size_t extra_ies_len, u8 oper_class,
664 struct cfg80211_chan_def *chandef)
665{
666 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
667 struct sk_buff *skb = NULL;
668 struct sta_info *sta;
669 u32 flags = 0;
670 int ret = 0;
671
626911cc
AN
672 rcu_read_lock();
673 sta = sta_info_get(sdata, peer);
674
675 /* infer the initiator if we can, to support old userspace */
95224fe8
AN
676 switch (action_code) {
677 case WLAN_TDLS_SETUP_REQUEST:
8b94148c 678 if (sta) {
626911cc 679 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
8b94148c
AN
680 sta->sta.tdls_initiator = false;
681 }
626911cc 682 /* fall-through */
95224fe8 683 case WLAN_TDLS_SETUP_CONFIRM:
95224fe8 684 case WLAN_TDLS_DISCOVERY_REQUEST:
626911cc 685 initiator = true;
95224fe8
AN
686 break;
687 case WLAN_TDLS_SETUP_RESPONSE:
626911cc
AN
688 /*
689 * In some testing scenarios, we send a request and response.
690 * Make the last packet sent take effect for the initiator
691 * value.
692 */
8b94148c 693 if (sta) {
626911cc 694 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
8b94148c
AN
695 sta->sta.tdls_initiator = true;
696 }
626911cc 697 /* fall-through */
95224fe8 698 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
626911cc 699 initiator = false;
2fb6b9b8
AN
700 break;
701 case WLAN_TDLS_TEARDOWN:
702 /* any value is ok */
95224fe8
AN
703 break;
704 default:
705 ret = -ENOTSUPP;
626911cc 706 break;
95224fe8
AN
707 }
708
46792a2d
AN
709 if (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))
710 initiator = true;
2fb6b9b8 711
626911cc
AN
712 rcu_read_unlock();
713 if (ret < 0)
714 goto fail;
715
c2733905
AN
716 skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code,
717 dialog_token, status_code,
718 initiator, extra_ies,
719 extra_ies_len, oper_class,
720 chandef);
721 if (!skb) {
722 ret = -EINVAL;
723 goto fail;
724 }
725
726 if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
95224fe8
AN
727 ieee80211_tx_skb(sdata, skb);
728 return 0;
729 }
730
731 /*
732 * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
733 * we should default to AC_VI.
734 */
735 switch (action_code) {
736 case WLAN_TDLS_SETUP_REQUEST:
737 case WLAN_TDLS_SETUP_RESPONSE:
738 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
739 skb->priority = 2;
740 break;
741 default:
742 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
743 skb->priority = 5;
744 break;
745 }
746
1277b4a9
LK
747 /*
748 * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress.
749 * Later, if no ACK is returned from peer, we will re-send the teardown
750 * packet through the AP.
751 */
752 if ((action_code == WLAN_TDLS_TEARDOWN) &&
c2733905 753 (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
1277b4a9
LK
754 struct sta_info *sta = NULL;
755 bool try_resend; /* Should we keep skb for possible resend */
756
757 /* If not sending directly to peer - no point in keeping skb */
758 rcu_read_lock();
759 sta = sta_info_get(sdata, peer);
760 try_resend = sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
761 rcu_read_unlock();
762
763 spin_lock_bh(&sdata->u.mgd.teardown_lock);
764 if (try_resend && !sdata->u.mgd.teardown_skb) {
765 /* Mark it as requiring TX status callback */
766 flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
767 IEEE80211_TX_INTFL_MLME_CONN_TX;
768
769 /*
770 * skb is copied since mac80211 will later set
771 * properties that might not be the same as the AP,
772 * such as encryption, QoS, addresses, etc.
773 *
774 * No problem if skb_copy() fails, so no need to check.
775 */
776 sdata->u.mgd.teardown_skb = skb_copy(skb, GFP_ATOMIC);
777 sdata->u.mgd.orig_teardown_skb = skb;
778 }
779 spin_unlock_bh(&sdata->u.mgd.teardown_lock);
780 }
781
95224fe8
AN
782 /* disable bottom halves when entering the Tx path */
783 local_bh_disable();
1277b4a9 784 __ieee80211_subif_start_xmit(skb, dev, flags);
95224fe8
AN
785 local_bh_enable();
786
787 return ret;
788
789fail:
790 dev_kfree_skb(skb);
791 return ret;
792}
793
191dd469
AN
794static int
795ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
796 const u8 *peer, u8 action_code, u8 dialog_token,
797 u16 status_code, u32 peer_capability, bool initiator,
798 const u8 *extra_ies, size_t extra_ies_len)
17e6a59a
AN
799{
800 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
801 struct ieee80211_local *local = sdata->local;
802 int ret;
803
17e6a59a
AN
804 mutex_lock(&local->mtx);
805
806 /* we don't support concurrent TDLS peer setups */
81dd2b88
AN
807 if (!is_zero_ether_addr(sdata->u.mgd.tdls_peer) &&
808 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
17e6a59a
AN
809 ret = -EBUSY;
810 goto exit;
811 }
812
7adc3e46
AN
813 /*
814 * make sure we have a STA representing the peer so we drop or buffer
815 * non-TDLS-setup frames to the peer. We can't send other packets
6ae32e5d
AN
816 * during setup through the AP path.
817 * Allow error packets to be sent - sometimes we don't even add a STA
818 * before failing the setup.
7adc3e46 819 */
6ae32e5d
AN
820 if (status_code == 0) {
821 rcu_read_lock();
822 if (!sta_info_get(sdata, peer)) {
823 rcu_read_unlock();
824 ret = -ENOLINK;
825 goto exit;
826 }
7adc3e46 827 rcu_read_unlock();
7adc3e46 828 }
7adc3e46 829
db67d661
AN
830 ieee80211_flush_queues(local, sdata);
831
17e6a59a
AN
832 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
833 dialog_token, status_code,
2fb6b9b8 834 peer_capability, initiator,
c2733905
AN
835 extra_ies, extra_ies_len, 0,
836 NULL);
17e6a59a
AN
837 if (ret < 0)
838 goto exit;
839
81dd2b88 840 memcpy(sdata->u.mgd.tdls_peer, peer, ETH_ALEN);
191dd469 841 ieee80211_queue_delayed_work(&sdata->local->hw,
81dd2b88 842 &sdata->u.mgd.tdls_peer_del_work,
191dd469 843 TDLS_PEER_SETUP_TIMEOUT);
17e6a59a
AN
844
845exit:
846 mutex_unlock(&local->mtx);
191dd469
AN
847 return ret;
848}
849
db67d661
AN
850static int
851ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
852 const u8 *peer, u8 action_code, u8 dialog_token,
853 u16 status_code, u32 peer_capability,
854 bool initiator, const u8 *extra_ies,
855 size_t extra_ies_len)
856{
857 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
858 struct ieee80211_local *local = sdata->local;
859 struct sta_info *sta;
860 int ret;
861
862 /*
863 * No packets can be transmitted to the peer via the AP during setup -
864 * the STA is set as a TDLS peer, but is not authorized.
865 * During teardown, we prevent direct transmissions by stopping the
866 * queues and flushing all direct packets.
867 */
868 ieee80211_stop_vif_queues(local, sdata,
869 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
870 ieee80211_flush_queues(local, sdata);
871
872 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
873 dialog_token, status_code,
874 peer_capability, initiator,
c2733905
AN
875 extra_ies, extra_ies_len, 0,
876 NULL);
db67d661
AN
877 if (ret < 0)
878 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
879 ret);
880
881 /*
882 * Remove the STA AUTH flag to force further traffic through the AP. If
883 * the STA was unreachable, it was already removed.
884 */
885 rcu_read_lock();
886 sta = sta_info_get(sdata, peer);
887 if (sta)
888 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
889 rcu_read_unlock();
890
891 ieee80211_wake_vif_queues(local, sdata,
892 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
893
894 return 0;
895}
896
191dd469
AN
897int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
898 const u8 *peer, u8 action_code, u8 dialog_token,
899 u16 status_code, u32 peer_capability,
900 bool initiator, const u8 *extra_ies,
901 size_t extra_ies_len)
902{
903 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
904 int ret;
905
906 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
907 return -ENOTSUPP;
908
909 /* make sure we are in managed mode, and associated */
910 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
911 !sdata->u.mgd.associated)
912 return -EINVAL;
913
914 switch (action_code) {
915 case WLAN_TDLS_SETUP_REQUEST:
916 case WLAN_TDLS_SETUP_RESPONSE:
917 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
918 dialog_token, status_code,
919 peer_capability, initiator,
920 extra_ies, extra_ies_len);
921 break;
922 case WLAN_TDLS_TEARDOWN:
db67d661
AN
923 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
924 action_code, dialog_token,
925 status_code,
926 peer_capability, initiator,
927 extra_ies, extra_ies_len);
928 break;
191dd469 929 case WLAN_TDLS_DISCOVERY_REQUEST:
ee10f2c7
AN
930 /*
931 * Protect the discovery so we can hear the TDLS discovery
932 * response frame. It is transmitted directly and not buffered
933 * by the AP.
934 */
935 drv_mgd_protect_tdls_discover(sdata->local, sdata);
936 /* fall-through */
937 case WLAN_TDLS_SETUP_CONFIRM:
191dd469
AN
938 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
939 /* no special handling */
940 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
941 action_code,
942 dialog_token,
943 status_code,
944 peer_capability,
945 initiator, extra_ies,
c2733905 946 extra_ies_len, 0, NULL);
191dd469
AN
947 break;
948 default:
949 ret = -EOPNOTSUPP;
950 break;
951 }
17e6a59a
AN
952
953 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
954 action_code, peer, ret);
955 return ret;
956}
957
95224fe8 958int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
3b3a0162 959 const u8 *peer, enum nl80211_tdls_operation oper)
95224fe8
AN
960{
961 struct sta_info *sta;
962 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
17e6a59a
AN
963 struct ieee80211_local *local = sdata->local;
964 int ret;
95224fe8
AN
965
966 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
967 return -ENOTSUPP;
968
969 if (sdata->vif.type != NL80211_IFTYPE_STATION)
970 return -EINVAL;
971
17e6a59a
AN
972 switch (oper) {
973 case NL80211_TDLS_ENABLE_LINK:
974 case NL80211_TDLS_DISABLE_LINK:
975 break;
976 case NL80211_TDLS_TEARDOWN:
977 case NL80211_TDLS_SETUP:
978 case NL80211_TDLS_DISCOVERY_REQ:
979 /* We don't support in-driver setup/teardown/discovery */
980 return -ENOTSUPP;
981 }
982
983 mutex_lock(&local->mtx);
95224fe8
AN
984 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
985
986 switch (oper) {
987 case NL80211_TDLS_ENABLE_LINK:
988 rcu_read_lock();
989 sta = sta_info_get(sdata, peer);
990 if (!sta) {
991 rcu_read_unlock();
17e6a59a
AN
992 ret = -ENOLINK;
993 break;
95224fe8
AN
994 }
995
996 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
997 rcu_read_unlock();
17e6a59a 998
81dd2b88
AN
999 WARN_ON_ONCE(is_zero_ether_addr(sdata->u.mgd.tdls_peer) ||
1000 !ether_addr_equal(sdata->u.mgd.tdls_peer, peer));
17e6a59a 1001 ret = 0;
95224fe8
AN
1002 break;
1003 case NL80211_TDLS_DISABLE_LINK:
bb3f8486
LK
1004 /*
1005 * The teardown message in ieee80211_tdls_mgmt_teardown() was
1006 * created while the queues were stopped, so it might still be
1007 * pending. Before flushing the queues we need to be sure the
1008 * message is handled by the tasklet handling pending messages,
1009 * otherwise we might start destroying the station before
1010 * sending the teardown packet.
1011 * Note that this only forces the tasklet to flush pendings -
1012 * not to stop the tasklet from rescheduling itself.
1013 */
1014 tasklet_kill(&local->tx_pending_tasklet);
db67d661
AN
1015 /* flush a potentially queued teardown packet */
1016 ieee80211_flush_queues(local, sdata);
1017
17e6a59a
AN
1018 ret = sta_info_destroy_addr(sdata, peer);
1019 break;
95224fe8 1020 default:
17e6a59a
AN
1021 ret = -ENOTSUPP;
1022 break;
95224fe8
AN
1023 }
1024
81dd2b88
AN
1025 if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) {
1026 cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work);
1027 eth_zero_addr(sdata->u.mgd.tdls_peer);
17e6a59a
AN
1028 }
1029
1030 mutex_unlock(&local->mtx);
1031 return ret;
95224fe8 1032}
c887f0d3
AN
1033
1034void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
1035 enum nl80211_tdls_operation oper,
1036 u16 reason_code, gfp_t gfp)
1037{
1038 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1039
1040 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
1041 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
1042 oper);
1043 return;
1044 }
1045
1046 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
1047}
1048EXPORT_SYMBOL(ieee80211_tdls_oper_request);