]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/mac80211/tdls.c
mac80211: track TDLS initiator internally
[karo-tx-linux.git] / net / mac80211 / tdls.c
1 /*
2  * mac80211 TDLS handling code
3  *
4  * Copyright 2006-2010  Johannes Berg <johannes@sipsolutions.net>
5  * Copyright 2014, Intel Corporation
6  *
7  * This file is GPLv2 as found in COPYING.
8  */
9
10 #include <linux/ieee80211.h>
11 #include <net/cfg80211.h>
12 #include "ieee80211_i.h"
13 #include "driver-ops.h"
14
15 /* give usermode some time for retries in setting up the TDLS session */
16 #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
17
18 void ieee80211_tdls_peer_del_work(struct work_struct *wk)
19 {
20         struct ieee80211_sub_if_data *sdata;
21         struct ieee80211_local *local;
22
23         sdata = container_of(wk, struct ieee80211_sub_if_data,
24                              tdls_peer_del_work.work);
25         local = sdata->local;
26
27         mutex_lock(&local->mtx);
28         if (!is_zero_ether_addr(sdata->tdls_peer)) {
29                 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->tdls_peer);
30                 sta_info_destroy_addr(sdata, sdata->tdls_peer);
31                 eth_zero_addr(sdata->tdls_peer);
32         }
33         mutex_unlock(&local->mtx);
34 }
35
36 static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
37 {
38         u8 *pos = (void *)skb_put(skb, 7);
39
40         *pos++ = WLAN_EID_EXT_CAPABILITY;
41         *pos++ = 5; /* len */
42         *pos++ = 0x0;
43         *pos++ = 0x0;
44         *pos++ = 0x0;
45         *pos++ = 0x0;
46         *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
47 }
48
49 static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
50 {
51         struct ieee80211_local *local = sdata->local;
52         u16 capab;
53
54         capab = 0;
55         if (ieee80211_get_sdata_band(sdata) != IEEE80211_BAND_2GHZ)
56                 return capab;
57
58         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
59                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
60         if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
61                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
62
63         return capab;
64 }
65
66 static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr,
67                                        const u8 *peer, const u8 *bssid)
68 {
69         struct ieee80211_tdls_lnkie *lnkid;
70
71         lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
72
73         lnkid->ie_type = WLAN_EID_LINK_ID;
74         lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
75
76         memcpy(lnkid->bssid, bssid, ETH_ALEN);
77         memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
78         memcpy(lnkid->resp_sta, peer, ETH_ALEN);
79 }
80
81 static int
82 ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
83                                const u8 *peer, u8 action_code, u8 dialog_token,
84                                u16 status_code, struct sk_buff *skb)
85 {
86         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
87         enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
88         struct ieee80211_tdls_data *tf;
89
90         tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
91
92         memcpy(tf->da, peer, ETH_ALEN);
93         memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
94         tf->ether_type = cpu_to_be16(ETH_P_TDLS);
95         tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
96
97         switch (action_code) {
98         case WLAN_TDLS_SETUP_REQUEST:
99                 tf->category = WLAN_CATEGORY_TDLS;
100                 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
101
102                 skb_put(skb, sizeof(tf->u.setup_req));
103                 tf->u.setup_req.dialog_token = dialog_token;
104                 tf->u.setup_req.capability =
105                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
106
107                 ieee80211_add_srates_ie(sdata, skb, false, band);
108                 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
109                 ieee80211_tdls_add_ext_capab(skb);
110                 break;
111         case WLAN_TDLS_SETUP_RESPONSE:
112                 tf->category = WLAN_CATEGORY_TDLS;
113                 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
114
115                 skb_put(skb, sizeof(tf->u.setup_resp));
116                 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
117                 tf->u.setup_resp.dialog_token = dialog_token;
118                 tf->u.setup_resp.capability =
119                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
120
121                 ieee80211_add_srates_ie(sdata, skb, false, band);
122                 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
123                 ieee80211_tdls_add_ext_capab(skb);
124                 break;
125         case WLAN_TDLS_SETUP_CONFIRM:
126                 tf->category = WLAN_CATEGORY_TDLS;
127                 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
128
129                 skb_put(skb, sizeof(tf->u.setup_cfm));
130                 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
131                 tf->u.setup_cfm.dialog_token = dialog_token;
132                 break;
133         case WLAN_TDLS_TEARDOWN:
134                 tf->category = WLAN_CATEGORY_TDLS;
135                 tf->action_code = WLAN_TDLS_TEARDOWN;
136
137                 skb_put(skb, sizeof(tf->u.teardown));
138                 tf->u.teardown.reason_code = cpu_to_le16(status_code);
139                 break;
140         case WLAN_TDLS_DISCOVERY_REQUEST:
141                 tf->category = WLAN_CATEGORY_TDLS;
142                 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
143
144                 skb_put(skb, sizeof(tf->u.discover_req));
145                 tf->u.discover_req.dialog_token = dialog_token;
146                 break;
147         default:
148                 return -EINVAL;
149         }
150
151         return 0;
152 }
153
154 static int
155 ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
156                            const u8 *peer, u8 action_code, u8 dialog_token,
157                            u16 status_code, struct sk_buff *skb)
158 {
159         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
160         enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
161         struct ieee80211_mgmt *mgmt;
162
163         mgmt = (void *)skb_put(skb, 24);
164         memset(mgmt, 0, 24);
165         memcpy(mgmt->da, peer, ETH_ALEN);
166         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
167         memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
168
169         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
170                                           IEEE80211_STYPE_ACTION);
171
172         switch (action_code) {
173         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
174                 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
175                 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
176                 mgmt->u.action.u.tdls_discover_resp.action_code =
177                         WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
178                 mgmt->u.action.u.tdls_discover_resp.dialog_token =
179                         dialog_token;
180                 mgmt->u.action.u.tdls_discover_resp.capability =
181                         cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
182
183                 ieee80211_add_srates_ie(sdata, skb, false, band);
184                 ieee80211_add_ext_srates_ie(sdata, skb, false, band);
185                 ieee80211_tdls_add_ext_capab(skb);
186                 break;
187         default:
188                 return -EINVAL;
189         }
190
191         return 0;
192 }
193
194 static int
195 ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
196                                 const u8 *peer, u8 action_code,
197                                 u8 dialog_token, u16 status_code,
198                                 u32 peer_capability, bool initiator,
199                                 const u8 *extra_ies, size_t extra_ies_len)
200 {
201         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
202         struct ieee80211_local *local = sdata->local;
203         struct sk_buff *skb = NULL;
204         bool send_direct;
205         const u8 *init_addr, *rsp_addr;
206         struct sta_info *sta;
207         int ret;
208
209         skb = dev_alloc_skb(local->hw.extra_tx_headroom +
210                             max(sizeof(struct ieee80211_mgmt),
211                                 sizeof(struct ieee80211_tdls_data)) +
212                             50 + /* supported rates */
213                             7 + /* ext capab */
214                             extra_ies_len +
215                             sizeof(struct ieee80211_tdls_lnkie));
216         if (!skb)
217                 return -ENOMEM;
218
219         skb_reserve(skb, local->hw.extra_tx_headroom);
220
221         switch (action_code) {
222         case WLAN_TDLS_SETUP_REQUEST:
223         case WLAN_TDLS_SETUP_RESPONSE:
224         case WLAN_TDLS_SETUP_CONFIRM:
225         case WLAN_TDLS_TEARDOWN:
226         case WLAN_TDLS_DISCOVERY_REQUEST:
227                 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
228                                                      action_code, dialog_token,
229                                                      status_code, skb);
230                 send_direct = false;
231                 break;
232         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
233                 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
234                                                  dialog_token, status_code,
235                                                  skb);
236                 send_direct = true;
237                 break;
238         default:
239                 ret = -ENOTSUPP;
240                 break;
241         }
242
243         if (ret < 0)
244                 goto fail;
245
246         if (extra_ies_len)
247                 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
248
249         rcu_read_lock();
250         sta = sta_info_get(sdata, peer);
251
252         /* infer the initiator if we can, to support old userspace */
253         switch (action_code) {
254         case WLAN_TDLS_SETUP_REQUEST:
255                 if (sta)
256                         set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
257                 /* fall-through */
258         case WLAN_TDLS_SETUP_CONFIRM:
259         case WLAN_TDLS_DISCOVERY_REQUEST:
260                 initiator = true;
261                 break;
262         case WLAN_TDLS_SETUP_RESPONSE:
263                 /*
264                  * In some testing scenarios, we send a request and response.
265                  * Make the last packet sent take effect for the initiator
266                  * value.
267                  */
268                 if (sta)
269                         clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR);
270                 /* fall-through */
271         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
272                 initiator = false;
273                 break;
274         case WLAN_TDLS_TEARDOWN:
275                 /* any value is ok */
276                 break;
277         default:
278                 ret = -ENOTSUPP;
279                 break;
280         }
281
282         if (initiator || (sta && test_sta_flag(sta, WLAN_STA_TDLS_INITIATOR))) {
283                 init_addr = sdata->vif.addr;
284                 rsp_addr = peer;
285         } else {
286                 init_addr = peer;
287                 rsp_addr = sdata->vif.addr;
288         }
289
290         rcu_read_unlock();
291         if (ret < 0)
292                 goto fail;
293
294         ieee80211_tdls_add_link_ie(skb, init_addr, rsp_addr,
295                                    sdata->u.mgd.bssid);
296
297         if (send_direct) {
298                 ieee80211_tx_skb(sdata, skb);
299                 return 0;
300         }
301
302         /*
303          * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
304          * we should default to AC_VI.
305          */
306         switch (action_code) {
307         case WLAN_TDLS_SETUP_REQUEST:
308         case WLAN_TDLS_SETUP_RESPONSE:
309                 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
310                 skb->priority = 2;
311                 break;
312         default:
313                 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
314                 skb->priority = 5;
315                 break;
316         }
317
318         /* disable bottom halves when entering the Tx path */
319         local_bh_disable();
320         ret = ieee80211_subif_start_xmit(skb, dev);
321         local_bh_enable();
322
323         return ret;
324
325 fail:
326         dev_kfree_skb(skb);
327         return ret;
328 }
329
330 static int
331 ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
332                           const u8 *peer, u8 action_code, u8 dialog_token,
333                           u16 status_code, u32 peer_capability, bool initiator,
334                           const u8 *extra_ies, size_t extra_ies_len)
335 {
336         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
337         struct ieee80211_local *local = sdata->local;
338         int ret;
339
340         mutex_lock(&local->mtx);
341
342         /* we don't support concurrent TDLS peer setups */
343         if (!is_zero_ether_addr(sdata->tdls_peer) &&
344             !ether_addr_equal(sdata->tdls_peer, peer)) {
345                 ret = -EBUSY;
346                 goto exit;
347         }
348
349         /*
350          * make sure we have a STA representing the peer so we drop or buffer
351          * non-TDLS-setup frames to the peer. We can't send other packets
352          * during setup through the AP path
353          */
354         rcu_read_lock();
355         if (!sta_info_get(sdata, peer)) {
356                 rcu_read_unlock();
357                 ret = -ENOLINK;
358                 goto exit;
359         }
360         rcu_read_unlock();
361
362         ieee80211_flush_queues(local, sdata);
363
364         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
365                                               dialog_token, status_code,
366                                               peer_capability, initiator,
367                                               extra_ies, extra_ies_len);
368         if (ret < 0)
369                 goto exit;
370
371         memcpy(sdata->tdls_peer, peer, ETH_ALEN);
372         ieee80211_queue_delayed_work(&sdata->local->hw,
373                                      &sdata->tdls_peer_del_work,
374                                      TDLS_PEER_SETUP_TIMEOUT);
375
376 exit:
377         mutex_unlock(&local->mtx);
378         return ret;
379 }
380
381 static int
382 ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
383                              const u8 *peer, u8 action_code, u8 dialog_token,
384                              u16 status_code, u32 peer_capability,
385                              bool initiator, const u8 *extra_ies,
386                              size_t extra_ies_len)
387 {
388         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
389         struct ieee80211_local *local = sdata->local;
390         struct sta_info *sta;
391         int ret;
392
393         /*
394          * No packets can be transmitted to the peer via the AP during setup -
395          * the STA is set as a TDLS peer, but is not authorized.
396          * During teardown, we prevent direct transmissions by stopping the
397          * queues and flushing all direct packets.
398          */
399         ieee80211_stop_vif_queues(local, sdata,
400                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
401         ieee80211_flush_queues(local, sdata);
402
403         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
404                                               dialog_token, status_code,
405                                               peer_capability, initiator,
406                                               extra_ies, extra_ies_len);
407         if (ret < 0)
408                 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
409                           ret);
410
411         /*
412          * Remove the STA AUTH flag to force further traffic through the AP. If
413          * the STA was unreachable, it was already removed.
414          */
415         rcu_read_lock();
416         sta = sta_info_get(sdata, peer);
417         if (sta)
418                 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
419         rcu_read_unlock();
420
421         ieee80211_wake_vif_queues(local, sdata,
422                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
423
424         return 0;
425 }
426
427 int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
428                         const u8 *peer, u8 action_code, u8 dialog_token,
429                         u16 status_code, u32 peer_capability,
430                         bool initiator, const u8 *extra_ies,
431                         size_t extra_ies_len)
432 {
433         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
434         int ret;
435
436         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
437                 return -ENOTSUPP;
438
439         /* make sure we are in managed mode, and associated */
440         if (sdata->vif.type != NL80211_IFTYPE_STATION ||
441             !sdata->u.mgd.associated)
442                 return -EINVAL;
443
444         switch (action_code) {
445         case WLAN_TDLS_SETUP_REQUEST:
446         case WLAN_TDLS_SETUP_RESPONSE:
447                 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
448                                                 dialog_token, status_code,
449                                                 peer_capability, initiator,
450                                                 extra_ies, extra_ies_len);
451                 break;
452         case WLAN_TDLS_TEARDOWN:
453                 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
454                                                    action_code, dialog_token,
455                                                    status_code,
456                                                    peer_capability, initiator,
457                                                    extra_ies, extra_ies_len);
458                 break;
459         case WLAN_TDLS_DISCOVERY_REQUEST:
460                 /*
461                  * Protect the discovery so we can hear the TDLS discovery
462                  * response frame. It is transmitted directly and not buffered
463                  * by the AP.
464                  */
465                 drv_mgd_protect_tdls_discover(sdata->local, sdata);
466                 /* fall-through */
467         case WLAN_TDLS_SETUP_CONFIRM:
468         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
469                 /* no special handling */
470                 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
471                                                       action_code,
472                                                       dialog_token,
473                                                       status_code,
474                                                       peer_capability,
475                                                       initiator, extra_ies,
476                                                       extra_ies_len);
477                 break;
478         default:
479                 ret = -EOPNOTSUPP;
480                 break;
481         }
482
483         tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
484                  action_code, peer, ret);
485         return ret;
486 }
487
488 int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
489                         const u8 *peer, enum nl80211_tdls_operation oper)
490 {
491         struct sta_info *sta;
492         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
493         struct ieee80211_local *local = sdata->local;
494         int ret;
495
496         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
497                 return -ENOTSUPP;
498
499         if (sdata->vif.type != NL80211_IFTYPE_STATION)
500                 return -EINVAL;
501
502         switch (oper) {
503         case NL80211_TDLS_ENABLE_LINK:
504         case NL80211_TDLS_DISABLE_LINK:
505                 break;
506         case NL80211_TDLS_TEARDOWN:
507         case NL80211_TDLS_SETUP:
508         case NL80211_TDLS_DISCOVERY_REQ:
509                 /* We don't support in-driver setup/teardown/discovery */
510                 return -ENOTSUPP;
511         }
512
513         mutex_lock(&local->mtx);
514         tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
515
516         switch (oper) {
517         case NL80211_TDLS_ENABLE_LINK:
518                 rcu_read_lock();
519                 sta = sta_info_get(sdata, peer);
520                 if (!sta) {
521                         rcu_read_unlock();
522                         ret = -ENOLINK;
523                         break;
524                 }
525
526                 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
527                 rcu_read_unlock();
528
529                 WARN_ON_ONCE(is_zero_ether_addr(sdata->tdls_peer) ||
530                              !ether_addr_equal(sdata->tdls_peer, peer));
531                 ret = 0;
532                 break;
533         case NL80211_TDLS_DISABLE_LINK:
534                 /* flush a potentially queued teardown packet */
535                 ieee80211_flush_queues(local, sdata);
536
537                 ret = sta_info_destroy_addr(sdata, peer);
538                 break;
539         default:
540                 ret = -ENOTSUPP;
541                 break;
542         }
543
544         if (ret == 0 && ether_addr_equal(sdata->tdls_peer, peer)) {
545                 cancel_delayed_work(&sdata->tdls_peer_del_work);
546                 eth_zero_addr(sdata->tdls_peer);
547         }
548
549         mutex_unlock(&local->mtx);
550         return ret;
551 }
552
553 void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
554                                  enum nl80211_tdls_operation oper,
555                                  u16 reason_code, gfp_t gfp)
556 {
557         struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
558
559         if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
560                 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
561                           oper);
562                 return;
563         }
564
565         cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
566 }
567 EXPORT_SYMBOL(ieee80211_tdls_oper_request);