]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/mac80211/mesh_hwmp.c
Merge tag 'stable/for-linus-3.9-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / net / mac80211 / mesh_hwmp.c
1 /*
2  * Copyright (c) 2008, 2009 open80211s Ltd.
3  * Author:     Luis Carlos Cobo <luisca@cozybit.com>
4  *
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.
8  */
9
10 #include <linux/slab.h>
11 #include <linux/etherdevice.h>
12 #include <asm/unaligned.h>
13 #include "wme.h"
14 #include "mesh.h"
15
16 #define TEST_FRAME_LEN  8192
17 #define MAX_METRIC      0xffffffff
18 #define ARITH_SHIFT     8
19
20 #define MAX_PREQ_QUEUE_LEN      64
21
22 /* Destination only */
23 #define MP_F_DO 0x1
24 /* Reply and forward */
25 #define MP_F_RF 0x2
26 /* Unknown Sequence Number */
27 #define MP_F_USN    0x01
28 /* Reason code Present */
29 #define MP_F_RCODE  0x02
30
31 static void mesh_queue_preq(struct mesh_path *, u8);
32
33 static inline u32 u32_field_get(const u8 *preq_elem, int offset, bool ae)
34 {
35         if (ae)
36                 offset += 6;
37         return get_unaligned_le32(preq_elem + offset);
38 }
39
40 static inline u32 u16_field_get(const u8 *preq_elem, int offset, bool ae)
41 {
42         if (ae)
43                 offset += 6;
44         return get_unaligned_le16(preq_elem + offset);
45 }
46
47 /* HWMP IE processing macros */
48 #define AE_F                    (1<<6)
49 #define AE_F_SET(x)             (*x & AE_F)
50 #define PREQ_IE_FLAGS(x)        (*(x))
51 #define PREQ_IE_HOPCOUNT(x)     (*(x + 1))
52 #define PREQ_IE_TTL(x)          (*(x + 2))
53 #define PREQ_IE_PREQ_ID(x)      u32_field_get(x, 3, 0)
54 #define PREQ_IE_ORIG_ADDR(x)    (x + 7)
55 #define PREQ_IE_ORIG_SN(x)      u32_field_get(x, 13, 0)
56 #define PREQ_IE_LIFETIME(x)     u32_field_get(x, 17, AE_F_SET(x))
57 #define PREQ_IE_METRIC(x)       u32_field_get(x, 21, AE_F_SET(x))
58 #define PREQ_IE_TARGET_F(x)     (*(AE_F_SET(x) ? x + 32 : x + 26))
59 #define PREQ_IE_TARGET_ADDR(x)  (AE_F_SET(x) ? x + 33 : x + 27)
60 #define PREQ_IE_TARGET_SN(x)    u32_field_get(x, 33, AE_F_SET(x))
61
62
63 #define PREP_IE_FLAGS(x)        PREQ_IE_FLAGS(x)
64 #define PREP_IE_HOPCOUNT(x)     PREQ_IE_HOPCOUNT(x)
65 #define PREP_IE_TTL(x)          PREQ_IE_TTL(x)
66 #define PREP_IE_ORIG_ADDR(x)    (AE_F_SET(x) ? x + 27 : x + 21)
67 #define PREP_IE_ORIG_SN(x)      u32_field_get(x, 27, AE_F_SET(x))
68 #define PREP_IE_LIFETIME(x)     u32_field_get(x, 13, AE_F_SET(x))
69 #define PREP_IE_METRIC(x)       u32_field_get(x, 17, AE_F_SET(x))
70 #define PREP_IE_TARGET_ADDR(x)  (x + 3)
71 #define PREP_IE_TARGET_SN(x)    u32_field_get(x, 9, 0)
72
73 #define PERR_IE_TTL(x)          (*(x))
74 #define PERR_IE_TARGET_FLAGS(x) (*(x + 2))
75 #define PERR_IE_TARGET_ADDR(x)  (x + 3)
76 #define PERR_IE_TARGET_SN(x)    u32_field_get(x, 9, 0)
77 #define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0)
78
79 #define MSEC_TO_TU(x) (x*1000/1024)
80 #define SN_GT(x, y) ((s32)(y - x) < 0)
81 #define SN_LT(x, y) ((s32)(x - y) < 0)
82
83 #define net_traversal_jiffies(s) \
84         msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
85 #define default_lifetime(s) \
86         MSEC_TO_TU(s->u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout)
87 #define min_preq_int_jiff(s) \
88         (msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval))
89 #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
90 #define disc_timeout_jiff(s) \
91         msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
92 #define root_path_confirmation_jiffies(s) \
93         msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
94
95 enum mpath_frame_type {
96         MPATH_PREQ = 0,
97         MPATH_PREP,
98         MPATH_PERR,
99         MPATH_RANN
100 };
101
102 static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
103
104 static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
105                                   const u8 *orig_addr, __le32 orig_sn,
106                                   u8 target_flags, const u8 *target,
107                                   __le32 target_sn, const u8 *da,
108                                   u8 hop_count, u8 ttl,
109                                   __le32 lifetime, __le32 metric,
110                                   __le32 preq_id,
111                                   struct ieee80211_sub_if_data *sdata)
112 {
113         struct ieee80211_local *local = sdata->local;
114         struct sk_buff *skb;
115         struct ieee80211_mgmt *mgmt;
116         u8 *pos, ie_len;
117         int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
118                       sizeof(mgmt->u.action.u.mesh_action);
119
120         skb = dev_alloc_skb(local->tx_headroom +
121                             hdr_len +
122                             2 + 37); /* max HWMP IE */
123         if (!skb)
124                 return -1;
125         skb_reserve(skb, local->tx_headroom);
126         mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
127         memset(mgmt, 0, hdr_len);
128         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
129                                           IEEE80211_STYPE_ACTION);
130
131         memcpy(mgmt->da, da, ETH_ALEN);
132         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
133         /* BSSID == SA */
134         memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
135         mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
136         mgmt->u.action.u.mesh_action.action_code =
137                                         WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
138
139         switch (action) {
140         case MPATH_PREQ:
141                 mhwmp_dbg(sdata, "sending PREQ to %pM\n", target);
142                 ie_len = 37;
143                 pos = skb_put(skb, 2 + ie_len);
144                 *pos++ = WLAN_EID_PREQ;
145                 break;
146         case MPATH_PREP:
147                 mhwmp_dbg(sdata, "sending PREP to %pM\n", target);
148                 ie_len = 31;
149                 pos = skb_put(skb, 2 + ie_len);
150                 *pos++ = WLAN_EID_PREP;
151                 break;
152         case MPATH_RANN:
153                 mhwmp_dbg(sdata, "sending RANN from %pM\n", orig_addr);
154                 ie_len = sizeof(struct ieee80211_rann_ie);
155                 pos = skb_put(skb, 2 + ie_len);
156                 *pos++ = WLAN_EID_RANN;
157                 break;
158         default:
159                 kfree_skb(skb);
160                 return -ENOTSUPP;
161                 break;
162         }
163         *pos++ = ie_len;
164         *pos++ = flags;
165         *pos++ = hop_count;
166         *pos++ = ttl;
167         if (action == MPATH_PREP) {
168                 memcpy(pos, target, ETH_ALEN);
169                 pos += ETH_ALEN;
170                 memcpy(pos, &target_sn, 4);
171                 pos += 4;
172         } else {
173                 if (action == MPATH_PREQ) {
174                         memcpy(pos, &preq_id, 4);
175                         pos += 4;
176                 }
177                 memcpy(pos, orig_addr, ETH_ALEN);
178                 pos += ETH_ALEN;
179                 memcpy(pos, &orig_sn, 4);
180                 pos += 4;
181         }
182         memcpy(pos, &lifetime, 4);      /* interval for RANN */
183         pos += 4;
184         memcpy(pos, &metric, 4);
185         pos += 4;
186         if (action == MPATH_PREQ) {
187                 *pos++ = 1; /* destination count */
188                 *pos++ = target_flags;
189                 memcpy(pos, target, ETH_ALEN);
190                 pos += ETH_ALEN;
191                 memcpy(pos, &target_sn, 4);
192                 pos += 4;
193         } else if (action == MPATH_PREP) {
194                 memcpy(pos, orig_addr, ETH_ALEN);
195                 pos += ETH_ALEN;
196                 memcpy(pos, &orig_sn, 4);
197                 pos += 4;
198         }
199
200         ieee80211_tx_skb(sdata, skb);
201         return 0;
202 }
203
204
205 /*  Headroom is not adjusted.  Caller should ensure that skb has sufficient
206  *  headroom in case the frame is encrypted. */
207 static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
208                 struct sk_buff *skb)
209 {
210         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
211         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
212
213         skb_set_mac_header(skb, 0);
214         skb_set_network_header(skb, 0);
215         skb_set_transport_header(skb, 0);
216
217         /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
218         skb_set_queue_mapping(skb, IEEE80211_AC_VO);
219         skb->priority = 7;
220
221         info->control.vif = &sdata->vif;
222         info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
223         ieee80211_set_qos_hdr(sdata, skb);
224         ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
225 }
226
227 /**
228  * mesh_path_error_tx - Sends a PERR mesh management frame
229  *
230  * @ttl: allowed remaining hops
231  * @target: broken destination
232  * @target_sn: SN of the broken destination
233  * @target_rcode: reason code for this PERR
234  * @ra: node this frame is addressed to
235  * @sdata: local mesh subif
236  *
237  * Note: This function may be called with driver locks taken that the driver
238  * also acquires in the TX path.  To avoid a deadlock we don't transmit the
239  * frame directly but add it to the pending queue instead.
240  */
241 int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
242                        u8 ttl, const u8 *target, __le32 target_sn,
243                        __le16 target_rcode, const u8 *ra)
244 {
245         struct ieee80211_local *local = sdata->local;
246         struct sk_buff *skb;
247         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
248         struct ieee80211_mgmt *mgmt;
249         u8 *pos, ie_len;
250         int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
251                       sizeof(mgmt->u.action.u.mesh_action);
252
253         if (time_before(jiffies, ifmsh->next_perr))
254                 return -EAGAIN;
255
256         skb = dev_alloc_skb(local->tx_headroom +
257                             IEEE80211_ENCRYPT_HEADROOM +
258                             IEEE80211_ENCRYPT_TAILROOM +
259                             hdr_len +
260                             2 + 15 /* PERR IE */);
261         if (!skb)
262                 return -1;
263         skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM);
264         mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
265         memset(mgmt, 0, hdr_len);
266         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
267                                           IEEE80211_STYPE_ACTION);
268
269         memcpy(mgmt->da, ra, ETH_ALEN);
270         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
271         /* BSSID == SA */
272         memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
273         mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
274         mgmt->u.action.u.mesh_action.action_code =
275                                         WLAN_MESH_ACTION_HWMP_PATH_SELECTION;
276         ie_len = 15;
277         pos = skb_put(skb, 2 + ie_len);
278         *pos++ = WLAN_EID_PERR;
279         *pos++ = ie_len;
280         /* ttl */
281         *pos++ = ttl;
282         /* number of destinations */
283         *pos++ = 1;
284         /*
285          * flags bit, bit 1 is unset if we know the sequence number and
286          * bit 2 is set if we have a reason code
287          */
288         *pos = 0;
289         if (!target_sn)
290                 *pos |= MP_F_USN;
291         if (target_rcode)
292                 *pos |= MP_F_RCODE;
293         pos++;
294         memcpy(pos, target, ETH_ALEN);
295         pos += ETH_ALEN;
296         memcpy(pos, &target_sn, 4);
297         pos += 4;
298         memcpy(pos, &target_rcode, 2);
299
300         /* see note in function header */
301         prepare_frame_for_deferred_tx(sdata, skb);
302         ifmsh->next_perr = TU_TO_EXP_TIME(
303                                    ifmsh->mshcfg.dot11MeshHWMPperrMinInterval);
304         ieee80211_add_pending_skb(local, skb);
305         return 0;
306 }
307
308 void ieee80211s_update_metric(struct ieee80211_local *local,
309                 struct sta_info *sta, struct sk_buff *skb)
310 {
311         struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
312         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
313         int failed;
314
315         if (!ieee80211_is_data(hdr->frame_control))
316                 return;
317
318         failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
319
320         /* moving average, scaled to 100 */
321         sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed);
322         if (sta->fail_avg > 95)
323                 mesh_plink_broken(sta);
324 }
325
326 static u32 airtime_link_metric_get(struct ieee80211_local *local,
327                                    struct sta_info *sta)
328 {
329         struct rate_info rinfo;
330         /* This should be adjusted for each device */
331         int device_constant = 1 << ARITH_SHIFT;
332         int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
333         int s_unit = 1 << ARITH_SHIFT;
334         int rate, err;
335         u32 tx_time, estimated_retx;
336         u64 result;
337
338         if (sta->fail_avg >= 100)
339                 return MAX_METRIC;
340
341         sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo);
342         rate = cfg80211_calculate_bitrate(&rinfo);
343         if (WARN_ON(!rate))
344                 return MAX_METRIC;
345
346         err = (sta->fail_avg << ARITH_SHIFT) / 100;
347
348         /* bitrate is in units of 100 Kbps, while we need rate in units of
349          * 1Mbps. This will be corrected on tx_time computation.
350          */
351         tx_time = (device_constant + 10 * test_frame_len / rate);
352         estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
353         result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
354         return (u32)result;
355 }
356
357 /**
358  * hwmp_route_info_get - Update routing info to originator and transmitter
359  *
360  * @sdata: local mesh subif
361  * @mgmt: mesh management frame
362  * @hwmp_ie: hwmp information element (PREP or PREQ)
363  * @action: type of hwmp ie
364  *
365  * This function updates the path routing information to the originator and the
366  * transmitter of a HWMP PREQ or PREP frame.
367  *
368  * Returns: metric to frame originator or 0 if the frame should not be further
369  * processed
370  *
371  * Notes: this function is the only place (besides user-provided info) where
372  * path routing information is updated.
373  */
374 static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
375                                struct ieee80211_mgmt *mgmt,
376                                const u8 *hwmp_ie, enum mpath_frame_type action)
377 {
378         struct ieee80211_local *local = sdata->local;
379         struct mesh_path *mpath;
380         struct sta_info *sta;
381         bool fresh_info;
382         const u8 *orig_addr, *ta;
383         u32 orig_sn, orig_metric;
384         unsigned long orig_lifetime, exp_time;
385         u32 last_hop_metric, new_metric;
386         bool process = true;
387
388         rcu_read_lock();
389         sta = sta_info_get(sdata, mgmt->sa);
390         if (!sta) {
391                 rcu_read_unlock();
392                 return 0;
393         }
394
395         last_hop_metric = airtime_link_metric_get(local, sta);
396         /* Update and check originator routing info */
397         fresh_info = true;
398
399         switch (action) {
400         case MPATH_PREQ:
401                 orig_addr = PREQ_IE_ORIG_ADDR(hwmp_ie);
402                 orig_sn = PREQ_IE_ORIG_SN(hwmp_ie);
403                 orig_lifetime = PREQ_IE_LIFETIME(hwmp_ie);
404                 orig_metric = PREQ_IE_METRIC(hwmp_ie);
405                 break;
406         case MPATH_PREP:
407                 /* Originator here refers to the MP that was the target in the
408                  * Path Request. We divert from the nomenclature in the draft
409                  * so that we can easily use a single function to gather path
410                  * information from both PREQ and PREP frames.
411                  */
412                 orig_addr = PREP_IE_TARGET_ADDR(hwmp_ie);
413                 orig_sn = PREP_IE_TARGET_SN(hwmp_ie);
414                 orig_lifetime = PREP_IE_LIFETIME(hwmp_ie);
415                 orig_metric = PREP_IE_METRIC(hwmp_ie);
416                 break;
417         default:
418                 rcu_read_unlock();
419                 return 0;
420         }
421         new_metric = orig_metric + last_hop_metric;
422         if (new_metric < orig_metric)
423                 new_metric = MAX_METRIC;
424         exp_time = TU_TO_EXP_TIME(orig_lifetime);
425
426         if (ether_addr_equal(orig_addr, sdata->vif.addr)) {
427                 /* This MP is the originator, we are not interested in this
428                  * frame, except for updating transmitter's path info.
429                  */
430                 process = false;
431                 fresh_info = false;
432         } else {
433                 mpath = mesh_path_lookup(sdata, orig_addr);
434                 if (mpath) {
435                         spin_lock_bh(&mpath->state_lock);
436                         if (mpath->flags & MESH_PATH_FIXED)
437                                 fresh_info = false;
438                         else if ((mpath->flags & MESH_PATH_ACTIVE) &&
439                             (mpath->flags & MESH_PATH_SN_VALID)) {
440                                 if (SN_GT(mpath->sn, orig_sn) ||
441                                     (mpath->sn == orig_sn &&
442                                      new_metric >= mpath->metric)) {
443                                         process = false;
444                                         fresh_info = false;
445                                 }
446                         }
447                 } else {
448                         mesh_path_add(sdata, orig_addr);
449                         mpath = mesh_path_lookup(sdata, orig_addr);
450                         if (!mpath) {
451                                 rcu_read_unlock();
452                                 return 0;
453                         }
454                         spin_lock_bh(&mpath->state_lock);
455                 }
456
457                 if (fresh_info) {
458                         mesh_path_assign_nexthop(mpath, sta);
459                         mpath->flags |= MESH_PATH_SN_VALID;
460                         mpath->metric = new_metric;
461                         mpath->sn = orig_sn;
462                         mpath->exp_time = time_after(mpath->exp_time, exp_time)
463                                           ?  mpath->exp_time : exp_time;
464                         mesh_path_activate(mpath);
465                         spin_unlock_bh(&mpath->state_lock);
466                         mesh_path_tx_pending(mpath);
467                         /* draft says preq_id should be saved to, but there does
468                          * not seem to be any use for it, skipping by now
469                          */
470                 } else
471                         spin_unlock_bh(&mpath->state_lock);
472         }
473
474         /* Update and check transmitter routing info */
475         ta = mgmt->sa;
476         if (ether_addr_equal(orig_addr, ta))
477                 fresh_info = false;
478         else {
479                 fresh_info = true;
480
481                 mpath = mesh_path_lookup(sdata, ta);
482                 if (mpath) {
483                         spin_lock_bh(&mpath->state_lock);
484                         if ((mpath->flags & MESH_PATH_FIXED) ||
485                                 ((mpath->flags & MESH_PATH_ACTIVE) &&
486                                         (last_hop_metric > mpath->metric)))
487                                 fresh_info = false;
488                 } else {
489                         mesh_path_add(sdata, ta);
490                         mpath = mesh_path_lookup(sdata, ta);
491                         if (!mpath) {
492                                 rcu_read_unlock();
493                                 return 0;
494                         }
495                         spin_lock_bh(&mpath->state_lock);
496                 }
497
498                 if (fresh_info) {
499                         mesh_path_assign_nexthop(mpath, sta);
500                         mpath->metric = last_hop_metric;
501                         mpath->exp_time = time_after(mpath->exp_time, exp_time)
502                                           ?  mpath->exp_time : exp_time;
503                         mesh_path_activate(mpath);
504                         spin_unlock_bh(&mpath->state_lock);
505                         mesh_path_tx_pending(mpath);
506                 } else
507                         spin_unlock_bh(&mpath->state_lock);
508         }
509
510         rcu_read_unlock();
511
512         return process ? new_metric : 0;
513 }
514
515 static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
516                                     struct ieee80211_mgmt *mgmt,
517                                     const u8 *preq_elem, u32 metric)
518 {
519         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
520         struct mesh_path *mpath = NULL;
521         const u8 *target_addr, *orig_addr;
522         const u8 *da;
523         u8 target_flags, ttl, flags;
524         u32 orig_sn, target_sn, lifetime, orig_metric;
525         bool reply = false;
526         bool forward = true;
527         bool root_is_gate;
528
529         /* Update target SN, if present */
530         target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
531         orig_addr = PREQ_IE_ORIG_ADDR(preq_elem);
532         target_sn = PREQ_IE_TARGET_SN(preq_elem);
533         orig_sn = PREQ_IE_ORIG_SN(preq_elem);
534         target_flags = PREQ_IE_TARGET_F(preq_elem);
535         orig_metric = metric;
536         /* Proactive PREQ gate announcements */
537         flags = PREQ_IE_FLAGS(preq_elem);
538         root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
539
540         mhwmp_dbg(sdata, "received PREQ from %pM\n", orig_addr);
541
542         if (ether_addr_equal(target_addr, sdata->vif.addr)) {
543                 mhwmp_dbg(sdata, "PREQ is for us\n");
544                 forward = false;
545                 reply = true;
546                 metric = 0;
547                 if (time_after(jiffies, ifmsh->last_sn_update +
548                                         net_traversal_jiffies(sdata)) ||
549                     time_before(jiffies, ifmsh->last_sn_update)) {
550                         target_sn = ++ifmsh->sn;
551                         ifmsh->last_sn_update = jiffies;
552                 }
553         } else if (is_broadcast_ether_addr(target_addr) &&
554                    (target_flags & IEEE80211_PREQ_TO_FLAG)) {
555                 rcu_read_lock();
556                 mpath = mesh_path_lookup(sdata, orig_addr);
557                 if (mpath) {
558                         if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
559                                 reply = true;
560                                 target_addr = sdata->vif.addr;
561                                 target_sn = ++ifmsh->sn;
562                                 metric = 0;
563                                 ifmsh->last_sn_update = jiffies;
564                         }
565                         if (root_is_gate)
566                                 mesh_path_add_gate(mpath);
567                 }
568                 rcu_read_unlock();
569         } else {
570                 rcu_read_lock();
571                 mpath = mesh_path_lookup(sdata, target_addr);
572                 if (mpath) {
573                         if ((!(mpath->flags & MESH_PATH_SN_VALID)) ||
574                                         SN_LT(mpath->sn, target_sn)) {
575                                 mpath->sn = target_sn;
576                                 mpath->flags |= MESH_PATH_SN_VALID;
577                         } else if ((!(target_flags & MP_F_DO)) &&
578                                         (mpath->flags & MESH_PATH_ACTIVE)) {
579                                 reply = true;
580                                 metric = mpath->metric;
581                                 target_sn = mpath->sn;
582                                 if (target_flags & MP_F_RF)
583                                         target_flags |= MP_F_DO;
584                                 else
585                                         forward = false;
586                         }
587                 }
588                 rcu_read_unlock();
589         }
590
591         if (reply) {
592                 lifetime = PREQ_IE_LIFETIME(preq_elem);
593                 ttl = ifmsh->mshcfg.element_ttl;
594                 if (ttl != 0) {
595                         mhwmp_dbg(sdata, "replying to the PREQ\n");
596                         mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
597                                 cpu_to_le32(orig_sn), 0, target_addr,
598                                 cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
599                                 cpu_to_le32(lifetime), cpu_to_le32(metric),
600                                 0, sdata);
601                 } else {
602                         ifmsh->mshstats.dropped_frames_ttl++;
603                 }
604         }
605
606         if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
607                 u32 preq_id;
608                 u8 hopcount;
609
610                 ttl = PREQ_IE_TTL(preq_elem);
611                 lifetime = PREQ_IE_LIFETIME(preq_elem);
612                 if (ttl <= 1) {
613                         ifmsh->mshstats.dropped_frames_ttl++;
614                         return;
615                 }
616                 mhwmp_dbg(sdata, "forwarding the PREQ from %pM\n", orig_addr);
617                 --ttl;
618                 preq_id = PREQ_IE_PREQ_ID(preq_elem);
619                 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
620                 da = (mpath && mpath->is_root) ?
621                         mpath->rann_snd_addr : broadcast_addr;
622
623                 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
624                         target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
625                         target_sn = PREQ_IE_TARGET_SN(preq_elem);
626                         metric = orig_metric;
627                 }
628
629                 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
630                                 cpu_to_le32(orig_sn), target_flags, target_addr,
631                                 cpu_to_le32(target_sn), da,
632                                 hopcount, ttl, cpu_to_le32(lifetime),
633                                 cpu_to_le32(metric), cpu_to_le32(preq_id),
634                                 sdata);
635                 if (!is_multicast_ether_addr(da))
636                         ifmsh->mshstats.fwded_unicast++;
637                 else
638                         ifmsh->mshstats.fwded_mcast++;
639                 ifmsh->mshstats.fwded_frames++;
640         }
641 }
642
643
644 static inline struct sta_info *
645 next_hop_deref_protected(struct mesh_path *mpath)
646 {
647         return rcu_dereference_protected(mpath->next_hop,
648                                          lockdep_is_held(&mpath->state_lock));
649 }
650
651
652 static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
653                                     struct ieee80211_mgmt *mgmt,
654                                     const u8 *prep_elem, u32 metric)
655 {
656         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
657         struct mesh_path *mpath;
658         const u8 *target_addr, *orig_addr;
659         u8 ttl, hopcount, flags;
660         u8 next_hop[ETH_ALEN];
661         u32 target_sn, orig_sn, lifetime;
662
663         mhwmp_dbg(sdata, "received PREP from %pM\n",
664                   PREP_IE_ORIG_ADDR(prep_elem));
665
666         orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
667         if (ether_addr_equal(orig_addr, sdata->vif.addr))
668                 /* destination, no forwarding required */
669                 return;
670
671         if (!ifmsh->mshcfg.dot11MeshForwarding)
672                 return;
673
674         ttl = PREP_IE_TTL(prep_elem);
675         if (ttl <= 1) {
676                 sdata->u.mesh.mshstats.dropped_frames_ttl++;
677                 return;
678         }
679
680         rcu_read_lock();
681         mpath = mesh_path_lookup(sdata, orig_addr);
682         if (mpath)
683                 spin_lock_bh(&mpath->state_lock);
684         else
685                 goto fail;
686         if (!(mpath->flags & MESH_PATH_ACTIVE)) {
687                 spin_unlock_bh(&mpath->state_lock);
688                 goto fail;
689         }
690         memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN);
691         spin_unlock_bh(&mpath->state_lock);
692         --ttl;
693         flags = PREP_IE_FLAGS(prep_elem);
694         lifetime = PREP_IE_LIFETIME(prep_elem);
695         hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1;
696         target_addr = PREP_IE_TARGET_ADDR(prep_elem);
697         target_sn = PREP_IE_TARGET_SN(prep_elem);
698         orig_sn = PREP_IE_ORIG_SN(prep_elem);
699
700         mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
701                 cpu_to_le32(orig_sn), 0, target_addr,
702                 cpu_to_le32(target_sn), next_hop, hopcount,
703                 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
704                 0, sdata);
705         rcu_read_unlock();
706
707         sdata->u.mesh.mshstats.fwded_unicast++;
708         sdata->u.mesh.mshstats.fwded_frames++;
709         return;
710
711 fail:
712         rcu_read_unlock();
713         sdata->u.mesh.mshstats.dropped_frames_no_route++;
714 }
715
716 static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
717                                     struct ieee80211_mgmt *mgmt,
718                                     const u8 *perr_elem)
719 {
720         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
721         struct mesh_path *mpath;
722         u8 ttl;
723         const u8 *ta, *target_addr;
724         u32 target_sn;
725         u16 target_rcode;
726
727         ta = mgmt->sa;
728         ttl = PERR_IE_TTL(perr_elem);
729         if (ttl <= 1) {
730                 ifmsh->mshstats.dropped_frames_ttl++;
731                 return;
732         }
733         ttl--;
734         target_addr = PERR_IE_TARGET_ADDR(perr_elem);
735         target_sn = PERR_IE_TARGET_SN(perr_elem);
736         target_rcode = PERR_IE_TARGET_RCODE(perr_elem);
737
738         rcu_read_lock();
739         mpath = mesh_path_lookup(sdata, target_addr);
740         if (mpath) {
741                 struct sta_info *sta;
742
743                 spin_lock_bh(&mpath->state_lock);
744                 sta = next_hop_deref_protected(mpath);
745                 if (mpath->flags & MESH_PATH_ACTIVE &&
746                     ether_addr_equal(ta, sta->sta.addr) &&
747                     (!(mpath->flags & MESH_PATH_SN_VALID) ||
748                     SN_GT(target_sn, mpath->sn))) {
749                         mpath->flags &= ~MESH_PATH_ACTIVE;
750                         mpath->sn = target_sn;
751                         spin_unlock_bh(&mpath->state_lock);
752                         if (!ifmsh->mshcfg.dot11MeshForwarding)
753                                 goto endperr;
754                         mesh_path_error_tx(sdata, ttl, target_addr,
755                                            cpu_to_le32(target_sn),
756                                            cpu_to_le16(target_rcode),
757                                            broadcast_addr);
758                 } else
759                         spin_unlock_bh(&mpath->state_lock);
760         }
761 endperr:
762         rcu_read_unlock();
763 }
764
765 static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
766                                     struct ieee80211_mgmt *mgmt,
767                                     const struct ieee80211_rann_ie *rann)
768 {
769         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
770         struct ieee80211_local *local = sdata->local;
771         struct sta_info *sta;
772         struct mesh_path *mpath;
773         u8 ttl, flags, hopcount;
774         const u8 *orig_addr;
775         u32 orig_sn, metric, metric_txsta, interval;
776         bool root_is_gate;
777
778         ttl = rann->rann_ttl;
779         flags = rann->rann_flags;
780         root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
781         orig_addr = rann->rann_addr;
782         orig_sn = le32_to_cpu(rann->rann_seq);
783         interval = le32_to_cpu(rann->rann_interval);
784         hopcount = rann->rann_hopcount;
785         hopcount++;
786         metric = le32_to_cpu(rann->rann_metric);
787
788         /*  Ignore our own RANNs */
789         if (ether_addr_equal(orig_addr, sdata->vif.addr))
790                 return;
791
792         mhwmp_dbg(sdata,
793                   "received RANN from %pM via neighbour %pM (is_gate=%d)\n",
794                   orig_addr, mgmt->sa, root_is_gate);
795
796         rcu_read_lock();
797         sta = sta_info_get(sdata, mgmt->sa);
798         if (!sta) {
799                 rcu_read_unlock();
800                 return;
801         }
802
803         metric_txsta = airtime_link_metric_get(local, sta);
804
805         mpath = mesh_path_lookup(sdata, orig_addr);
806         if (!mpath) {
807                 mesh_path_add(sdata, orig_addr);
808                 mpath = mesh_path_lookup(sdata, orig_addr);
809                 if (!mpath) {
810                         rcu_read_unlock();
811                         sdata->u.mesh.mshstats.dropped_frames_no_route++;
812                         return;
813                 }
814         }
815
816         if (!(SN_LT(mpath->sn, orig_sn)) &&
817             !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
818                 rcu_read_unlock();
819                 return;
820         }
821
822         if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
823              (time_after(jiffies, mpath->last_preq_to_root +
824                                   root_path_confirmation_jiffies(sdata)) ||
825              time_before(jiffies, mpath->last_preq_to_root))) &&
826              !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) {
827                 mhwmp_dbg(sdata,
828                           "time to refresh root mpath %pM\n",
829                           orig_addr);
830                 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
831                 mpath->last_preq_to_root = jiffies;
832         }
833
834         mpath->sn = orig_sn;
835         mpath->rann_metric = metric + metric_txsta;
836         mpath->is_root = true;
837         /* Recording RANNs sender address to send individually
838          * addressed PREQs destined for root mesh STA */
839         memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
840
841         if (root_is_gate)
842                 mesh_path_add_gate(mpath);
843
844         if (ttl <= 1) {
845                 ifmsh->mshstats.dropped_frames_ttl++;
846                 rcu_read_unlock();
847                 return;
848         }
849         ttl--;
850
851         if (ifmsh->mshcfg.dot11MeshForwarding) {
852                 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
853                                        cpu_to_le32(orig_sn),
854                                        0, NULL, 0, broadcast_addr,
855                                        hopcount, ttl, cpu_to_le32(interval),
856                                        cpu_to_le32(metric + metric_txsta),
857                                        0, sdata);
858         }
859
860         rcu_read_unlock();
861 }
862
863
864 void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
865                             struct ieee80211_mgmt *mgmt, size_t len)
866 {
867         struct ieee802_11_elems elems;
868         size_t baselen;
869         u32 last_hop_metric;
870         struct sta_info *sta;
871
872         /* need action_code */
873         if (len < IEEE80211_MIN_ACTION_SIZE + 1)
874                 return;
875
876         rcu_read_lock();
877         sta = sta_info_get(sdata, mgmt->sa);
878         if (!sta || sta->plink_state != NL80211_PLINK_ESTAB) {
879                 rcu_read_unlock();
880                 return;
881         }
882         rcu_read_unlock();
883
884         baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
885         ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
886                         len - baselen, &elems);
887
888         if (elems.preq) {
889                 if (elems.preq_len != 37)
890                         /* Right now we support just 1 destination and no AE */
891                         return;
892                 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq,
893                                                       MPATH_PREQ);
894                 if (last_hop_metric)
895                         hwmp_preq_frame_process(sdata, mgmt, elems.preq,
896                                                 last_hop_metric);
897         }
898         if (elems.prep) {
899                 if (elems.prep_len != 31)
900                         /* Right now we support no AE */
901                         return;
902                 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep,
903                                                       MPATH_PREP);
904                 if (last_hop_metric)
905                         hwmp_prep_frame_process(sdata, mgmt, elems.prep,
906                                                 last_hop_metric);
907         }
908         if (elems.perr) {
909                 if (elems.perr_len != 15)
910                         /* Right now we support only one destination per PERR */
911                         return;
912                 hwmp_perr_frame_process(sdata, mgmt, elems.perr);
913         }
914         if (elems.rann)
915                 hwmp_rann_frame_process(sdata, mgmt, elems.rann);
916 }
917
918 /**
919  * mesh_queue_preq - queue a PREQ to a given destination
920  *
921  * @mpath: mesh path to discover
922  * @flags: special attributes of the PREQ to be sent
923  *
924  * Locking: the function must be called from within a rcu read lock block.
925  *
926  */
927 static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
928 {
929         struct ieee80211_sub_if_data *sdata = mpath->sdata;
930         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
931         struct mesh_preq_queue *preq_node;
932
933         preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
934         if (!preq_node) {
935                 mhwmp_dbg(sdata, "could not allocate PREQ node\n");
936                 return;
937         }
938
939         spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
940         if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) {
941                 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
942                 kfree(preq_node);
943                 if (printk_ratelimit())
944                         mhwmp_dbg(sdata, "PREQ node queue full\n");
945                 return;
946         }
947
948         spin_lock(&mpath->state_lock);
949         if (mpath->flags & MESH_PATH_REQ_QUEUED) {
950                 spin_unlock(&mpath->state_lock);
951                 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
952                 kfree(preq_node);
953                 return;
954         }
955
956         memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
957         preq_node->flags = flags;
958
959         mpath->flags |= MESH_PATH_REQ_QUEUED;
960         spin_unlock(&mpath->state_lock);
961
962         list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
963         ++ifmsh->preq_queue_len;
964         spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
965
966         if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
967                 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
968
969         else if (time_before(jiffies, ifmsh->last_preq)) {
970                 /* avoid long wait if did not send preqs for a long time
971                  * and jiffies wrapped around
972                  */
973                 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
974                 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
975         } else
976                 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
977                                                 min_preq_int_jiff(sdata));
978 }
979
980 /**
981  * mesh_path_start_discovery - launch a path discovery from the PREQ queue
982  *
983  * @sdata: local mesh subif
984  */
985 void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
986 {
987         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
988         struct mesh_preq_queue *preq_node;
989         struct mesh_path *mpath;
990         u8 ttl, target_flags;
991         const u8 *da;
992         u32 lifetime;
993
994         spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
995         if (!ifmsh->preq_queue_len ||
996                 time_before(jiffies, ifmsh->last_preq +
997                                 min_preq_int_jiff(sdata))) {
998                 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
999                 return;
1000         }
1001
1002         preq_node = list_first_entry(&ifmsh->preq_queue.list,
1003                         struct mesh_preq_queue, list);
1004         list_del(&preq_node->list);
1005         --ifmsh->preq_queue_len;
1006         spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
1007
1008         rcu_read_lock();
1009         mpath = mesh_path_lookup(sdata, preq_node->dst);
1010         if (!mpath)
1011                 goto enddiscovery;
1012
1013         spin_lock_bh(&mpath->state_lock);
1014         mpath->flags &= ~MESH_PATH_REQ_QUEUED;
1015         if (preq_node->flags & PREQ_Q_F_START) {
1016                 if (mpath->flags & MESH_PATH_RESOLVING) {
1017                         spin_unlock_bh(&mpath->state_lock);
1018                         goto enddiscovery;
1019                 } else {
1020                         mpath->flags &= ~MESH_PATH_RESOLVED;
1021                         mpath->flags |= MESH_PATH_RESOLVING;
1022                         mpath->discovery_retries = 0;
1023                         mpath->discovery_timeout = disc_timeout_jiff(sdata);
1024                 }
1025         } else if (!(mpath->flags & MESH_PATH_RESOLVING) ||
1026                         mpath->flags & MESH_PATH_RESOLVED) {
1027                 mpath->flags &= ~MESH_PATH_RESOLVING;
1028                 spin_unlock_bh(&mpath->state_lock);
1029                 goto enddiscovery;
1030         }
1031
1032         ifmsh->last_preq = jiffies;
1033
1034         if (time_after(jiffies, ifmsh->last_sn_update +
1035                                 net_traversal_jiffies(sdata)) ||
1036             time_before(jiffies, ifmsh->last_sn_update)) {
1037                 ++ifmsh->sn;
1038                 sdata->u.mesh.last_sn_update = jiffies;
1039         }
1040         lifetime = default_lifetime(sdata);
1041         ttl = sdata->u.mesh.mshcfg.element_ttl;
1042         if (ttl == 0) {
1043                 sdata->u.mesh.mshstats.dropped_frames_ttl++;
1044                 spin_unlock_bh(&mpath->state_lock);
1045                 goto enddiscovery;
1046         }
1047
1048         if (preq_node->flags & PREQ_Q_F_REFRESH)
1049                 target_flags = MP_F_DO;
1050         else
1051                 target_flags = MP_F_RF;
1052
1053         spin_unlock_bh(&mpath->state_lock);
1054         da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
1055         mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr,
1056                         cpu_to_le32(ifmsh->sn), target_flags, mpath->dst,
1057                         cpu_to_le32(mpath->sn), da, 0,
1058                         ttl, cpu_to_le32(lifetime), 0,
1059                         cpu_to_le32(ifmsh->preq_id++), sdata);
1060         mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
1061
1062 enddiscovery:
1063         rcu_read_unlock();
1064         kfree(preq_node);
1065 }
1066
1067 /**
1068  * mesh_nexthop_resolve - lookup next hop; conditionally start path discovery
1069  *
1070  * @skb: 802.11 frame to be sent
1071  * @sdata: network subif the frame will be sent through
1072  *
1073  * Lookup next hop for given skb and start path discovery if no
1074  * forwarding information is found.
1075  *
1076  * Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
1077  * skb is freeed here if no mpath could be allocated.
1078  */
1079 int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata,
1080                          struct sk_buff *skb)
1081 {
1082         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1083         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1084         struct mesh_path *mpath;
1085         struct sk_buff *skb_to_free = NULL;
1086         u8 *target_addr = hdr->addr3;
1087         int err = 0;
1088
1089         /* Nulls are only sent to peers for PS and should be pre-addressed */
1090         if (ieee80211_is_qos_nullfunc(hdr->frame_control))
1091                 return 0;
1092
1093         rcu_read_lock();
1094         err = mesh_nexthop_lookup(sdata, skb);
1095         if (!err)
1096                 goto endlookup;
1097
1098         /* no nexthop found, start resolving */
1099         mpath = mesh_path_lookup(sdata, target_addr);
1100         if (!mpath) {
1101                 mesh_path_add(sdata, target_addr);
1102                 mpath = mesh_path_lookup(sdata, target_addr);
1103                 if (!mpath) {
1104                         mesh_path_discard_frame(sdata, skb);
1105                         err = -ENOSPC;
1106                         goto endlookup;
1107                 }
1108         }
1109
1110         if (!(mpath->flags & MESH_PATH_RESOLVING))
1111                 mesh_queue_preq(mpath, PREQ_Q_F_START);
1112
1113         if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
1114                 skb_to_free = skb_dequeue(&mpath->frame_queue);
1115
1116         info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1117         ieee80211_set_qos_hdr(sdata, skb);
1118         skb_queue_tail(&mpath->frame_queue, skb);
1119         err = -ENOENT;
1120         if (skb_to_free)
1121                 mesh_path_discard_frame(sdata, skb_to_free);
1122
1123 endlookup:
1124         rcu_read_unlock();
1125         return err;
1126 }
1127
1128 /**
1129  * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
1130  * this function is considered "using" the associated mpath, so preempt a path
1131  * refresh if this mpath expires soon.
1132  *
1133  * @skb: 802.11 frame to be sent
1134  * @sdata: network subif the frame will be sent through
1135  *
1136  * Returns: 0 if the next hop was found. Nonzero otherwise.
1137  */
1138 int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata,
1139                         struct sk_buff *skb)
1140 {
1141         struct mesh_path *mpath;
1142         struct sta_info *next_hop;
1143         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1144         u8 *target_addr = hdr->addr3;
1145         int err = -ENOENT;
1146
1147         rcu_read_lock();
1148         mpath = mesh_path_lookup(sdata, target_addr);
1149
1150         if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE))
1151                 goto endlookup;
1152
1153         if (time_after(jiffies,
1154                        mpath->exp_time -
1155                        msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
1156             ether_addr_equal(sdata->vif.addr, hdr->addr4) &&
1157             !(mpath->flags & MESH_PATH_RESOLVING) &&
1158             !(mpath->flags & MESH_PATH_FIXED))
1159                 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
1160
1161         next_hop = rcu_dereference(mpath->next_hop);
1162         if (next_hop) {
1163                 memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
1164                 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
1165                 ieee80211_mps_set_frame_flags(sdata, next_hop, hdr);
1166                 err = 0;
1167         }
1168
1169 endlookup:
1170         rcu_read_unlock();
1171         return err;
1172 }
1173
1174 void mesh_path_timer(unsigned long data)
1175 {
1176         struct mesh_path *mpath = (void *) data;
1177         struct ieee80211_sub_if_data *sdata = mpath->sdata;
1178         int ret;
1179
1180         if (sdata->local->quiescing)
1181                 return;
1182
1183         spin_lock_bh(&mpath->state_lock);
1184         if (mpath->flags & MESH_PATH_RESOLVED ||
1185                         (!(mpath->flags & MESH_PATH_RESOLVING))) {
1186                 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
1187                 spin_unlock_bh(&mpath->state_lock);
1188         } else if (mpath->discovery_retries < max_preq_retries(sdata)) {
1189                 ++mpath->discovery_retries;
1190                 mpath->discovery_timeout *= 2;
1191                 mpath->flags &= ~MESH_PATH_REQ_QUEUED;
1192                 spin_unlock_bh(&mpath->state_lock);
1193                 mesh_queue_preq(mpath, 0);
1194         } else {
1195                 mpath->flags = 0;
1196                 mpath->exp_time = jiffies;
1197                 spin_unlock_bh(&mpath->state_lock);
1198                 if (!mpath->is_gate && mesh_gate_num(sdata) > 0) {
1199                         ret = mesh_path_send_to_gates(mpath);
1200                         if (ret)
1201                                 mhwmp_dbg(sdata, "no gate was reachable\n");
1202                 } else
1203                         mesh_path_flush_pending(mpath);
1204         }
1205 }
1206
1207 void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1208 {
1209         struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1210         u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
1211         u8 flags, target_flags = 0;
1212
1213         flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
1214                         ? RANN_FLAG_IS_GATE : 0;
1215
1216         switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
1217         case IEEE80211_PROACTIVE_RANN:
1218                 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1219                                cpu_to_le32(++ifmsh->sn),
1220                                0, NULL, 0, broadcast_addr,
1221                                0, ifmsh->mshcfg.element_ttl,
1222                                cpu_to_le32(interval), 0, 0, sdata);
1223                 break;
1224         case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
1225                 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
1226         case IEEE80211_PROACTIVE_PREQ_NO_PREP:
1227                 interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
1228                 target_flags |= IEEE80211_PREQ_TO_FLAG |
1229                                 IEEE80211_PREQ_USN_FLAG;
1230                 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
1231                                 cpu_to_le32(++ifmsh->sn), target_flags,
1232                                 (u8 *) broadcast_addr, 0, broadcast_addr,
1233                                 0, ifmsh->mshcfg.element_ttl,
1234                                 cpu_to_le32(interval),
1235                                 0, cpu_to_le32(ifmsh->preq_id++), sdata);
1236                 break;
1237         default:
1238                 mhwmp_dbg(sdata, "Proactive mechanism not supported\n");
1239                 return;
1240         }
1241 }