]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/mac80211/tdls.c
mac80211: fix error path for TDLS setup
[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          * Allow error packets to be sent - sometimes we don't even add a STA
354          * before failing the setup.
355          */
356         if (status_code == 0) {
357                 rcu_read_lock();
358                 if (!sta_info_get(sdata, peer)) {
359                         rcu_read_unlock();
360                         ret = -ENOLINK;
361                         goto exit;
362                 }
363                 rcu_read_unlock();
364         }
365
366         ieee80211_flush_queues(local, sdata);
367
368         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
369                                               dialog_token, status_code,
370                                               peer_capability, initiator,
371                                               extra_ies, extra_ies_len);
372         if (ret < 0)
373                 goto exit;
374
375         memcpy(sdata->tdls_peer, peer, ETH_ALEN);
376         ieee80211_queue_delayed_work(&sdata->local->hw,
377                                      &sdata->tdls_peer_del_work,
378                                      TDLS_PEER_SETUP_TIMEOUT);
379
380 exit:
381         mutex_unlock(&local->mtx);
382         return ret;
383 }
384
385 static int
386 ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
387                              const u8 *peer, u8 action_code, u8 dialog_token,
388                              u16 status_code, u32 peer_capability,
389                              bool initiator, const u8 *extra_ies,
390                              size_t extra_ies_len)
391 {
392         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
393         struct ieee80211_local *local = sdata->local;
394         struct sta_info *sta;
395         int ret;
396
397         /*
398          * No packets can be transmitted to the peer via the AP during setup -
399          * the STA is set as a TDLS peer, but is not authorized.
400          * During teardown, we prevent direct transmissions by stopping the
401          * queues and flushing all direct packets.
402          */
403         ieee80211_stop_vif_queues(local, sdata,
404                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
405         ieee80211_flush_queues(local, sdata);
406
407         ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
408                                               dialog_token, status_code,
409                                               peer_capability, initiator,
410                                               extra_ies, extra_ies_len);
411         if (ret < 0)
412                 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
413                           ret);
414
415         /*
416          * Remove the STA AUTH flag to force further traffic through the AP. If
417          * the STA was unreachable, it was already removed.
418          */
419         rcu_read_lock();
420         sta = sta_info_get(sdata, peer);
421         if (sta)
422                 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
423         rcu_read_unlock();
424
425         ieee80211_wake_vif_queues(local, sdata,
426                                   IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
427
428         return 0;
429 }
430
431 int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
432                         const u8 *peer, u8 action_code, u8 dialog_token,
433                         u16 status_code, u32 peer_capability,
434                         bool initiator, const u8 *extra_ies,
435                         size_t extra_ies_len)
436 {
437         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
438         int ret;
439
440         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
441                 return -ENOTSUPP;
442
443         /* make sure we are in managed mode, and associated */
444         if (sdata->vif.type != NL80211_IFTYPE_STATION ||
445             !sdata->u.mgd.associated)
446                 return -EINVAL;
447
448         switch (action_code) {
449         case WLAN_TDLS_SETUP_REQUEST:
450         case WLAN_TDLS_SETUP_RESPONSE:
451                 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
452                                                 dialog_token, status_code,
453                                                 peer_capability, initiator,
454                                                 extra_ies, extra_ies_len);
455                 break;
456         case WLAN_TDLS_TEARDOWN:
457                 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
458                                                    action_code, dialog_token,
459                                                    status_code,
460                                                    peer_capability, initiator,
461                                                    extra_ies, extra_ies_len);
462                 break;
463         case WLAN_TDLS_DISCOVERY_REQUEST:
464                 /*
465                  * Protect the discovery so we can hear the TDLS discovery
466                  * response frame. It is transmitted directly and not buffered
467                  * by the AP.
468                  */
469                 drv_mgd_protect_tdls_discover(sdata->local, sdata);
470                 /* fall-through */
471         case WLAN_TDLS_SETUP_CONFIRM:
472         case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
473                 /* no special handling */
474                 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
475                                                       action_code,
476                                                       dialog_token,
477                                                       status_code,
478                                                       peer_capability,
479                                                       initiator, extra_ies,
480                                                       extra_ies_len);
481                 break;
482         default:
483                 ret = -EOPNOTSUPP;
484                 break;
485         }
486
487         tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
488                  action_code, peer, ret);
489         return ret;
490 }
491
492 int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
493                         const u8 *peer, enum nl80211_tdls_operation oper)
494 {
495         struct sta_info *sta;
496         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
497         struct ieee80211_local *local = sdata->local;
498         int ret;
499
500         if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
501                 return -ENOTSUPP;
502
503         if (sdata->vif.type != NL80211_IFTYPE_STATION)
504                 return -EINVAL;
505
506         switch (oper) {
507         case NL80211_TDLS_ENABLE_LINK:
508         case NL80211_TDLS_DISABLE_LINK:
509                 break;
510         case NL80211_TDLS_TEARDOWN:
511         case NL80211_TDLS_SETUP:
512         case NL80211_TDLS_DISCOVERY_REQ:
513                 /* We don't support in-driver setup/teardown/discovery */
514                 return -ENOTSUPP;
515         }
516
517         mutex_lock(&local->mtx);
518         tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
519
520         switch (oper) {
521         case NL80211_TDLS_ENABLE_LINK:
522                 rcu_read_lock();
523                 sta = sta_info_get(sdata, peer);
524                 if (!sta) {
525                         rcu_read_unlock();
526                         ret = -ENOLINK;
527                         break;
528                 }
529
530                 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
531                 rcu_read_unlock();
532
533                 WARN_ON_ONCE(is_zero_ether_addr(sdata->tdls_peer) ||
534                              !ether_addr_equal(sdata->tdls_peer, peer));
535                 ret = 0;
536                 break;
537         case NL80211_TDLS_DISABLE_LINK:
538                 /* flush a potentially queued teardown packet */
539                 ieee80211_flush_queues(local, sdata);
540
541                 ret = sta_info_destroy_addr(sdata, peer);
542                 break;
543         default:
544                 ret = -ENOTSUPP;
545                 break;
546         }
547
548         if (ret == 0 && ether_addr_equal(sdata->tdls_peer, peer)) {
549                 cancel_delayed_work(&sdata->tdls_peer_del_work);
550                 eth_zero_addr(sdata->tdls_peer);
551         }
552
553         mutex_unlock(&local->mtx);
554         return ret;
555 }
556
557 void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
558                                  enum nl80211_tdls_operation oper,
559                                  u16 reason_code, gfp_t gfp)
560 {
561         struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
562
563         if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
564                 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
565                           oper);
566                 return;
567         }
568
569         cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
570 }
571 EXPORT_SYMBOL(ieee80211_tdls_oper_request);