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