2 * Copyright (c) 2008 open80211s Ltd.
3 * Author: Luis Carlos Cobo <luisca@cozybit.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 #include <linux/kernel.h>
10 #include <linux/random.h>
11 #include "ieee80211_i.h"
12 #include "ieee80211_rate.h"
15 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
16 #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args)
18 #define mpl_dbg(fmt, args...) do { (void)(0); } while (0)
21 #define IEEE80211_FC(type, stype) cpu_to_le16(type | stype)
22 #define PLINK_GET_FRAME_SUBTYPE(p) (p)
23 #define PLINK_GET_LLID(p) (p + 1)
24 #define PLINK_GET_PLID(p) (p + 3)
26 #define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
27 jiffies + HZ * t / 1000))
29 /* Peer link cancel reasons, all subject to ANA approval */
30 #define MESH_LINK_CANCELLED 2
31 #define MESH_MAX_NEIGHBORS 3
32 #define MESH_CAPABILITY_POLICY_VIOLATION 4
33 #define MESH_CLOSE_RCVD 5
34 #define MESH_MAX_RETRIES 6
35 #define MESH_CONFIRM_TIMEOUT 7
36 #define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS 8
37 #define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9
38 #define MESH_SECURITY_FAILED_VERIFICATION 10
40 #define dot11MeshMaxRetries(s) (s->u.sta.mshcfg.dot11MeshMaxRetries)
41 #define dot11MeshRetryTimeout(s) (s->u.sta.mshcfg.dot11MeshRetryTimeout)
42 #define dot11MeshConfirmTimeout(s) (s->u.sta.mshcfg.dot11MeshConfirmTimeout)
43 #define dot11MeshHoldingTimeout(s) (s->u.sta.mshcfg.dot11MeshHoldingTimeout)
44 #define dot11MeshMaxPeerLinks(s) (s->u.sta.mshcfg.dot11MeshMaxPeerLinks)
46 enum plink_frame_type {
65 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
67 atomic_inc(&sdata->u.sta.mshstats.estab_plinks);
68 mesh_accept_plinks_update(sdata->dev);
72 void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
74 atomic_dec(&sdata->u.sta.mshstats.estab_plinks);
75 mesh_accept_plinks_update(sdata->dev);
79 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
81 * @sta: mes peer link to restart
83 * Locking: this function must be called holding sta->plink_lock
85 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
87 sta->plink_state = LISTEN;
88 sta->llid = sta->plid = sta->reason = sta->plink_retries = 0;
92 * mesh_plink_add - allocate and add a new mesh peer link
94 * @hw_addr: hardware address (ETH_ALEN length)
95 * @rates: rates the mesh peer supports
96 * @dev: local mesh interface
98 * The initial state of the new plink is set to LISTEN
100 * Returns: non-NULL on success, ERR_PTR() on error.
102 struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev)
104 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
105 struct sta_info *sta;
107 if (memcmp(hw_addr, dev->dev_addr, ETH_ALEN) == 0)
108 /* never add ourselves as neighbours */
109 return ERR_PTR(-EINVAL);
111 if (is_multicast_ether_addr(hw_addr))
112 return ERR_PTR(-EINVAL);
114 if (local->num_sta >= MESH_MAX_PLINKS)
115 return ERR_PTR(-ENOSPC);
117 sta = sta_info_add(local, dev, hw_addr, GFP_KERNEL);
121 sta->plink_state = LISTEN;
122 spin_lock_init(&sta->plink_lock);
123 init_timer(&sta->plink_timer);
124 sta->flags |= WLAN_STA_AUTHORIZED;
125 sta->supp_rates[local->hw.conf.channel->band] = rates;
126 rate_control_rate_init(sta, local);
128 mesh_accept_plinks_update(dev);
134 * __mesh_plink_deactivate - deactivate mesh peer link
136 * @sta: mesh peer link to deactivate
138 * All mesh paths with this peer as next hop will be flushed
140 * Locking: the caller must hold sta->plink_lock
142 static void __mesh_plink_deactivate(struct sta_info *sta)
144 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
145 if (sta->plink_state == ESTAB)
146 mesh_plink_dec_estab_count(sdata);
147 sta->plink_state = BLOCKED;
148 mesh_path_flush_by_nexthop(sta);
152 * __mesh_plink_deactivate - deactivate mesh peer link
154 * @sta: mesh peer link to deactivate
156 * All mesh paths with this peer as next hop will be flushed
158 void mesh_plink_deactivate(struct sta_info *sta)
160 spin_lock_bh(&sta->plink_lock);
161 __mesh_plink_deactivate(sta);
162 spin_unlock_bh(&sta->plink_lock);
165 static int mesh_plink_frame_tx(struct net_device *dev,
166 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
168 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
169 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
170 struct ieee80211_mgmt *mgmt;
171 bool include_plid = false;
177 skb_reserve(skb, local->hw.extra_tx_headroom);
178 /* 25 is the size of the common mgmt part (24) plus the size of the
179 * common action part (1)
181 mgmt = (struct ieee80211_mgmt *)
182 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
183 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
184 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
185 IEEE80211_STYPE_ACTION);
186 memcpy(mgmt->da, da, ETH_ALEN);
187 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
188 /* BSSID is left zeroed, wildcard value */
189 mgmt->u.action.category = PLINK_CATEGORY;
190 mgmt->u.action.u.plink_action.action_code = action;
192 if (action == PLINK_CLOSE)
193 mgmt->u.action.u.plink_action.aux = reason;
195 mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0);
196 if (action == PLINK_CONFIRM) {
197 pos = skb_put(skb, 4);
198 /* two-byte status code followed by two-byte AID */
201 mesh_mgmt_ies_add(skb, dev);
204 /* Add Peer Link Management element */
224 pos = skb_put(skb, 2 + ie_len);
225 *pos++ = WLAN_EID_PEER_LINK;
228 memcpy(pos, &llid, 2);
231 memcpy(pos, &plid, 2);
233 if (action == PLINK_CLOSE) {
235 memcpy(pos, &reason, 2);
238 ieee80211_sta_tx(dev, skb, 0);
242 void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
243 bool peer_accepting_plinks)
245 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
246 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
247 struct sta_info *sta;
249 sta = sta_info_get(local, hw_addr);
251 sta = mesh_plink_add(hw_addr, rates, dev);
256 sta->last_rx = jiffies;
257 sta->supp_rates[local->hw.conf.channel->band] = rates;
258 if (peer_accepting_plinks && sta->plink_state == LISTEN &&
259 sdata->u.sta.accepting_plinks &&
260 sdata->u.sta.mshcfg.auto_open_plinks)
261 mesh_plink_open(sta);
266 static void mesh_plink_timer(unsigned long data)
268 struct sta_info *sta;
269 __le16 llid, plid, reason;
270 struct net_device *dev = NULL;
271 struct ieee80211_sub_if_data *sdata;
272 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
273 DECLARE_MAC_BUF(mac);
276 sta = (struct sta_info *) data;
278 spin_lock_bh(&sta->plink_lock);
279 if (sta->ignore_plink_timer) {
280 sta->ignore_plink_timer = false;
281 spin_unlock_bh(&sta->plink_lock);
284 mpl_dbg("Mesh plink timer for %s fired on state %d\n",
285 print_mac(mac, sta->addr), sta->plink_state);
290 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
292 switch (sta->plink_state) {
296 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
298 mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
299 print_mac(mac, sta->addr),
300 sta->plink_retries, sta->plink_timeout);
301 get_random_bytes(&rand, sizeof(u32));
302 sta->plink_timeout = sta->plink_timeout +
303 rand % sta->plink_timeout;
304 ++sta->plink_retries;
305 if (!mod_plink_timer(sta, sta->plink_timeout))
307 spin_unlock_bh(&sta->plink_lock);
308 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
312 reason = cpu_to_le16(MESH_MAX_RETRIES);
313 /* fall through on else */
317 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
318 sta->plink_state = HOLDING;
319 if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
321 spin_unlock_bh(&sta->plink_lock);
322 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
327 if (del_timer(&sta->plink_timer))
329 mesh_plink_fsm_restart(sta);
330 spin_unlock_bh(&sta->plink_lock);
333 spin_unlock_bh(&sta->plink_lock);
340 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
342 sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
343 sta->plink_timer.data = (unsigned long) sta;
344 sta->plink_timer.function = mesh_plink_timer;
345 sta->plink_timeout = timeout;
347 add_timer(&sta->plink_timer);
350 int mesh_plink_open(struct sta_info *sta)
353 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
354 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
355 DECLARE_MAC_BUF(mac);
358 spin_lock_bh(&sta->plink_lock);
359 get_random_bytes(&llid, 2);
361 if (sta->plink_state != LISTEN) {
362 spin_unlock_bh(&sta->plink_lock);
366 sta->plink_state = OPN_SNT;
367 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
368 spin_unlock_bh(&sta->plink_lock);
369 mpl_dbg("Mesh plink: starting establishment with %s\n",
370 print_mac(mac, sta->addr));
372 return mesh_plink_frame_tx(sta->dev, PLINK_OPEN, sta->addr, llid, 0, 0);
375 void mesh_plink_block(struct sta_info *sta)
377 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
378 DECLARE_MAC_BUF(mac);
381 spin_lock_bh(&sta->plink_lock);
382 __mesh_plink_deactivate(sta);
383 sta->plink_state = BLOCKED;
384 spin_unlock_bh(&sta->plink_lock);
387 int mesh_plink_close(struct sta_info *sta)
389 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
390 int llid, plid, reason;
391 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
392 DECLARE_MAC_BUF(mac);
395 mpl_dbg("Mesh plink: closing link with %s\n",
396 print_mac(mac, sta->addr));
397 spin_lock_bh(&sta->plink_lock);
398 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
399 reason = sta->reason;
401 if (sta->plink_state == LISTEN || sta->plink_state == BLOCKED) {
402 mesh_plink_fsm_restart(sta);
403 spin_unlock_bh(&sta->plink_lock);
406 } else if (sta->plink_state == ESTAB) {
407 __mesh_plink_deactivate(sta);
408 /* The timer should not be running */
409 if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
411 } else if (!mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)))
412 sta->ignore_plink_timer = true;
414 sta->plink_state = HOLDING;
417 spin_unlock_bh(&sta->plink_lock);
418 mesh_plink_frame_tx(sta->dev, PLINK_CLOSE, sta->addr, llid, plid,
423 void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
424 size_t len, struct ieee80211_rx_status *rx_status)
426 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
427 struct ieee802_11_elems elems;
428 struct sta_info *sta;
429 enum plink_event event;
430 enum plink_frame_type ftype;
434 __le16 plid, llid, reason;
435 #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
436 DECLARE_MAC_BUF(mac);
438 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
440 if (is_multicast_ether_addr(mgmt->da)) {
441 mpl_dbg("Mesh plink: ignore frame from multicast address");
445 baseaddr = mgmt->u.action.u.plink_action.variable;
446 baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
447 if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
451 ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
452 if (!elems.peer_link) {
453 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
457 ftype = *((u8 *)PLINK_GET_FRAME_SUBTYPE(elems.peer_link));
458 ie_len = elems.peer_link_len;
459 if ((ftype == PLINK_OPEN && ie_len != 3) ||
460 (ftype == PLINK_CONFIRM && ie_len != 5) ||
461 (ftype == PLINK_CLOSE && ie_len != 5 && ie_len != 7)) {
462 mpl_dbg("Mesh plink: incorrect plink ie length\n");
466 if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
467 mpl_dbg("Mesh plink: missing necessary ie\n");
470 /* Note the lines below are correct, the llid in the frame is the plid
471 * from the point of view of this host.
473 memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
474 if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 7))
475 memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
477 sta = sta_info_get(local, mgmt->sa);
478 if (!sta && ftype != PLINK_OPEN) {
479 mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
483 if (sta && sta->plink_state == BLOCKED) {
488 /* Now we will figure out the appropriate event... */
489 event = PLINK_UNDEFINED;
490 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, dev))) {
502 spin_lock_bh(&sta->plink_lock);
504 /* ftype == PLINK_OPEN */
506 if (!mesh_plink_free_count(sdata)) {
507 mpl_dbg("Mesh plink error: no more free plinks\n");
511 rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
512 sta = mesh_plink_add(mgmt->sa, rates, dev);
514 mpl_dbg("Mesh plink error: plink table full\n");
518 spin_lock_bh(&sta->plink_lock);
520 spin_lock_bh(&sta->plink_lock);
523 if (!mesh_plink_free_count(sdata) ||
524 (sta->plid && sta->plid != plid))
530 if (!mesh_plink_free_count(sdata) ||
531 (sta->llid != llid || sta->plid != plid))
537 if (sta->plink_state == ESTAB)
538 /* Do not check for llid or plid. This does not
539 * follow the standard but since multiple plinks
540 * per sta are not supported, it is necessary in
541 * order to avoid a livelock when MP A sees an
542 * establish peer link to MP B but MP B does not
543 * see it. This can be caused by a timeout in
544 * B's peer link establishment or B beign
548 else if (sta->plid != plid)
550 else if (ie_len == 7 && sta->llid != llid)
556 mpl_dbg("Mesh plink: unknown frame subtype\n");
557 spin_unlock_bh(&sta->plink_lock);
563 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n",
564 print_mac(mac, mgmt->sa), sta->plink_state,
565 __le16_to_cpu(sta->llid), __le16_to_cpu(sta->plid),
568 switch (sta->plink_state) {
569 /* spin_unlock as soon as state is updated at each case */
573 mesh_plink_fsm_restart(sta);
574 spin_unlock_bh(&sta->plink_lock);
577 sta->plink_state = OPN_RCVD;
579 get_random_bytes(&llid, 2);
581 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
582 spin_unlock_bh(&sta->plink_lock);
583 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
585 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
589 spin_unlock_bh(&sta->plink_lock);
598 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
601 reason = cpu_to_le16(MESH_CLOSE_RCVD);
602 sta->reason = reason;
603 sta->plink_state = HOLDING;
604 if (!mod_plink_timer(sta,
605 dot11MeshHoldingTimeout(sdata)))
606 sta->ignore_plink_timer = true;
609 spin_unlock_bh(&sta->plink_lock);
610 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
614 /* retry timer is left untouched */
615 sta->plink_state = OPN_RCVD;
618 spin_unlock_bh(&sta->plink_lock);
619 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
623 sta->plink_state = CNF_RCVD;
624 if (!mod_plink_timer(sta,
625 dot11MeshConfirmTimeout(sdata)))
626 sta->ignore_plink_timer = true;
628 spin_unlock_bh(&sta->plink_lock);
631 spin_unlock_bh(&sta->plink_lock);
640 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
643 reason = cpu_to_le16(MESH_CLOSE_RCVD);
644 sta->reason = reason;
645 sta->plink_state = HOLDING;
646 if (!mod_plink_timer(sta,
647 dot11MeshHoldingTimeout(sdata)))
648 sta->ignore_plink_timer = true;
651 spin_unlock_bh(&sta->plink_lock);
652 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
657 spin_unlock_bh(&sta->plink_lock);
658 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
662 if (del_timer(&sta->plink_timer))
664 sta->plink_state = ESTAB;
665 mesh_plink_inc_estab_count(sdata);
666 spin_unlock_bh(&sta->plink_lock);
667 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
668 print_mac(mac, sta->addr));
671 spin_unlock_bh(&sta->plink_lock);
680 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
683 reason = cpu_to_le16(MESH_CLOSE_RCVD);
684 sta->reason = reason;
685 sta->plink_state = HOLDING;
686 if (!mod_plink_timer(sta,
687 dot11MeshHoldingTimeout(sdata)))
688 sta->ignore_plink_timer = true;
691 spin_unlock_bh(&sta->plink_lock);
692 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
695 if (del_timer(&sta->plink_timer))
697 sta->plink_state = ESTAB;
698 mesh_plink_inc_estab_count(sdata);
699 spin_unlock_bh(&sta->plink_lock);
700 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
701 print_mac(mac, sta->addr));
702 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
706 spin_unlock_bh(&sta->plink_lock);
714 reason = cpu_to_le16(MESH_CLOSE_RCVD);
715 sta->reason = reason;
716 __mesh_plink_deactivate(sta);
717 sta->plink_state = HOLDING;
719 if (!mod_plink_timer(sta,
720 dot11MeshHoldingTimeout(sdata)))
722 spin_unlock_bh(&sta->plink_lock);
723 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
728 spin_unlock_bh(&sta->plink_lock);
729 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
733 spin_unlock_bh(&sta->plink_lock);
740 if (del_timer(&sta->plink_timer)) {
741 sta->ignore_plink_timer = 1;
744 mesh_plink_fsm_restart(sta);
745 spin_unlock_bh(&sta->plink_lock);
752 reason = sta->reason;
753 spin_unlock_bh(&sta->plink_lock);
754 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
758 spin_unlock_bh(&sta->plink_lock);
762 /* should not get here, BLOCKED is dealt with at the beggining
765 spin_unlock_bh(&sta->plink_lock);