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