xref: /openbmc/linux/net/mac80211/mesh_hwmp.c (revision e8e0929d)
1 /*
2  * Copyright (c) 2008 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 "mesh.h"
11 
12 #define TEST_FRAME_LEN	8192
13 #define MAX_METRIC	0xffffffff
14 #define ARITH_SHIFT	8
15 
16 /* Number of frames buffered per destination for unresolved destinations */
17 #define MESH_FRAME_QUEUE_LEN	10
18 #define MAX_PREQ_QUEUE_LEN	64
19 
20 /* Destination only */
21 #define MP_F_DO	0x1
22 /* Reply and forward */
23 #define MP_F_RF	0x2
24 
25 static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
26 {
27 	if (ae)
28 		offset += 6;
29 	return get_unaligned_le32(preq_elem + offset);
30 }
31 
32 /* HWMP IE processing macros */
33 #define AE_F			(1<<6)
34 #define AE_F_SET(x)		(*x & AE_F)
35 #define PREQ_IE_FLAGS(x)	(*(x))
36 #define PREQ_IE_HOPCOUNT(x)	(*(x + 1))
37 #define PREQ_IE_TTL(x)		(*(x + 2))
38 #define PREQ_IE_PREQ_ID(x)	u32_field_get(x, 3, 0)
39 #define PREQ_IE_ORIG_ADDR(x)	(x + 7)
40 #define PREQ_IE_ORIG_DSN(x)	u32_field_get(x, 13, 0);
41 #define PREQ_IE_LIFETIME(x)	u32_field_get(x, 17, AE_F_SET(x));
42 #define PREQ_IE_METRIC(x) 	u32_field_get(x, 21, AE_F_SET(x));
43 #define PREQ_IE_DST_F(x)	(*(AE_F_SET(x) ? x + 32 : x + 26))
44 #define PREQ_IE_DST_ADDR(x) 	(AE_F_SET(x) ? x + 33 : x + 27)
45 #define PREQ_IE_DST_DSN(x) 	u32_field_get(x, 33, AE_F_SET(x));
46 
47 
48 #define PREP_IE_FLAGS(x)	PREQ_IE_FLAGS(x)
49 #define PREP_IE_HOPCOUNT(x)	PREQ_IE_HOPCOUNT(x)
50 #define PREP_IE_TTL(x)		PREQ_IE_TTL(x)
51 #define PREP_IE_ORIG_ADDR(x)	(x + 3)
52 #define PREP_IE_ORIG_DSN(x)	u32_field_get(x, 9, 0);
53 #define PREP_IE_LIFETIME(x)	u32_field_get(x, 13, AE_F_SET(x));
54 #define PREP_IE_METRIC(x)	u32_field_get(x, 17, AE_F_SET(x));
55 #define PREP_IE_DST_ADDR(x)	(AE_F_SET(x) ? x + 27 : x + 21)
56 #define PREP_IE_DST_DSN(x)	u32_field_get(x, 27, AE_F_SET(x));
57 
58 #define PERR_IE_DST_ADDR(x)	(x + 2)
59 #define PERR_IE_DST_DSN(x)	u32_field_get(x, 8, 0);
60 
61 #define MSEC_TO_TU(x) (x*1000/1024)
62 #define DSN_GT(x, y) ((long) (y) - (long) (x) < 0)
63 #define DSN_LT(x, y) ((long) (x) - (long) (y) < 0)
64 
65 #define net_traversal_jiffies(s) \
66 	msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
67 #define default_lifetime(s) \
68 	MSEC_TO_TU(s->u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout)
69 #define min_preq_int_jiff(s) \
70 	(msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval))
71 #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
72 #define disc_timeout_jiff(s) \
73 	msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
74 
75 enum mpath_frame_type {
76 	MPATH_PREQ = 0,
77 	MPATH_PREP,
78 	MPATH_PERR
79 };
80 
81 static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
82 		u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst,
83 		__le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime,
84 		__le32 metric, __le32 preq_id, struct ieee80211_sub_if_data *sdata)
85 {
86 	struct ieee80211_local *local = sdata->local;
87 	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
88 	struct ieee80211_mgmt *mgmt;
89 	u8 *pos;
90 	int ie_len;
91 
92 	if (!skb)
93 		return -1;
94 	skb_reserve(skb, local->hw.extra_tx_headroom);
95 	/* 25 is the size of the common mgmt part (24) plus the size of the
96 	 * common action part (1)
97 	 */
98 	mgmt = (struct ieee80211_mgmt *)
99 		skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
100 	memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
101 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
102 					  IEEE80211_STYPE_ACTION);
103 
104 	memcpy(mgmt->da, da, ETH_ALEN);
105 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
106 	/* BSSID is left zeroed, wildcard value */
107 	mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
108 	mgmt->u.action.u.mesh_action.action_code = action;
109 
110 	switch (action) {
111 	case MPATH_PREQ:
112 		ie_len = 37;
113 		pos = skb_put(skb, 2 + ie_len);
114 		*pos++ = WLAN_EID_PREQ;
115 		break;
116 	case MPATH_PREP:
117 		ie_len = 31;
118 		pos = skb_put(skb, 2 + ie_len);
119 		*pos++ = WLAN_EID_PREP;
120 		break;
121 	default:
122 		kfree_skb(skb);
123 		return -ENOTSUPP;
124 		break;
125 	}
126 	*pos++ = ie_len;
127 	*pos++ = flags;
128 	*pos++ = hop_count;
129 	*pos++ = ttl;
130 	if (action == MPATH_PREQ) {
131 		memcpy(pos, &preq_id, 4);
132 		pos += 4;
133 	}
134 	memcpy(pos, orig_addr, ETH_ALEN);
135 	pos += ETH_ALEN;
136 	memcpy(pos, &orig_dsn, 4);
137 	pos += 4;
138 	memcpy(pos, &lifetime, 4);
139 	pos += 4;
140 	memcpy(pos, &metric, 4);
141 	pos += 4;
142 	if (action == MPATH_PREQ) {
143 		/* destination count */
144 		*pos++ = 1;
145 		*pos++ = dst_flags;
146 	}
147 	memcpy(pos, dst, ETH_ALEN);
148 	pos += ETH_ALEN;
149 	memcpy(pos, &dst_dsn, 4);
150 
151 	ieee80211_tx_skb(sdata, skb, 1);
152 	return 0;
153 }
154 
155 /**
156  * mesh_send_path error - Sends a PERR mesh management frame
157  *
158  * @dst: broken destination
159  * @dst_dsn: dsn of the broken destination
160  * @ra: node this frame is addressed to
161  */
162 int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
163 		struct ieee80211_sub_if_data *sdata)
164 {
165 	struct ieee80211_local *local = sdata->local;
166 	struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
167 	struct ieee80211_mgmt *mgmt;
168 	u8 *pos;
169 	int ie_len;
170 
171 	if (!skb)
172 		return -1;
173 	skb_reserve(skb, local->hw.extra_tx_headroom);
174 	/* 25 is the size of the common mgmt part (24) plus the size of the
175 	 * common action part (1)
176 	 */
177 	mgmt = (struct ieee80211_mgmt *)
178 		skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
179 	memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
180 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
181 					  IEEE80211_STYPE_ACTION);
182 
183 	memcpy(mgmt->da, ra, ETH_ALEN);
184 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
185 	/* BSSID is left zeroed, wildcard value */
186 	mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
187 	mgmt->u.action.u.mesh_action.action_code = MPATH_PERR;
188 	ie_len = 12;
189 	pos = skb_put(skb, 2 + ie_len);
190 	*pos++ = WLAN_EID_PERR;
191 	*pos++ = ie_len;
192 	/* mode flags, reserved */
193 	*pos++ = 0;
194 	/* number of destinations */
195 	*pos++ = 1;
196 	memcpy(pos, dst, ETH_ALEN);
197 	pos += ETH_ALEN;
198 	memcpy(pos, &dst_dsn, 4);
199 
200 	ieee80211_tx_skb(sdata, skb, 1);
201 	return 0;
202 }
203 
204 void ieee80211s_update_metric(struct ieee80211_local *local,
205 		struct sta_info *stainfo, struct sk_buff *skb)
206 {
207 	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
208 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
209 	int failed;
210 
211 	if (!ieee80211_is_data(hdr->frame_control))
212 		return;
213 
214 	failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
215 
216 	/* moving average, scaled to 100 */
217 	stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
218 	if (stainfo->fail_avg > 95)
219 		mesh_plink_broken(stainfo);
220 }
221 
222 static u32 airtime_link_metric_get(struct ieee80211_local *local,
223 				   struct sta_info *sta)
224 {
225 	struct ieee80211_supported_band *sband;
226 	/* This should be adjusted for each device */
227 	int device_constant = 1 << ARITH_SHIFT;
228 	int test_frame_len = TEST_FRAME_LEN << ARITH_SHIFT;
229 	int s_unit = 1 << ARITH_SHIFT;
230 	int rate, err;
231 	u32 tx_time, estimated_retx;
232 	u64 result;
233 
234 	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
235 
236 	if (sta->fail_avg >= 100)
237 		return MAX_METRIC;
238 
239 	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
240 		return MAX_METRIC;
241 
242 	err = (sta->fail_avg << ARITH_SHIFT) / 100;
243 
244 	/* bitrate is in units of 100 Kbps, while we need rate in units of
245 	 * 1Mbps. This will be corrected on tx_time computation.
246 	 */
247 	rate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
248 	tx_time = (device_constant + 10 * test_frame_len / rate);
249 	estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
250 	result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
251 	return (u32)result;
252 }
253 
254 /**
255  * hwmp_route_info_get - Update routing info to originator and transmitter
256  *
257  * @sdata: local mesh subif
258  * @mgmt: mesh management frame
259  * @hwmp_ie: hwmp information element (PREP or PREQ)
260  *
261  * This function updates the path routing information to the originator and the
262  * transmitter of a HWMP PREQ or PREP fram.
263  *
264  * Returns: metric to frame originator or 0 if the frame should not be further
265  * processed
266  *
267  * Notes: this function is the only place (besides user-provided info) where
268  * path routing information is updated.
269  */
270 static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
271 			    struct ieee80211_mgmt *mgmt,
272 			    u8 *hwmp_ie)
273 {
274 	struct ieee80211_local *local = sdata->local;
275 	struct mesh_path *mpath;
276 	struct sta_info *sta;
277 	bool fresh_info;
278 	u8 *orig_addr, *ta;
279 	u32 orig_dsn, orig_metric;
280 	unsigned long orig_lifetime, exp_time;
281 	u32 last_hop_metric, new_metric;
282 	bool process = true;
283 	u8 action = mgmt->u.action.u.mesh_action.action_code;
284 
285 	rcu_read_lock();
286 	sta = sta_info_get(local, mgmt->sa);
287 	if (!sta) {
288 		rcu_read_unlock();
289 		return 0;
290 	}
291 
292 	last_hop_metric = airtime_link_metric_get(local, sta);
293 	/* Update and check originator routing info */
294 	fresh_info = true;
295 
296 	switch (action) {
297 	case MPATH_PREQ:
298 		orig_addr = PREQ_IE_ORIG_ADDR(hwmp_ie);
299 		orig_dsn = PREQ_IE_ORIG_DSN(hwmp_ie);
300 		orig_lifetime = PREQ_IE_LIFETIME(hwmp_ie);
301 		orig_metric = PREQ_IE_METRIC(hwmp_ie);
302 		break;
303 	case MPATH_PREP:
304 		/* Originator here refers to the MP that was the destination in
305 		 * the Path Request. The draft refers to that MP as the
306 		 * destination address, even though usually it is the origin of
307 		 * the PREP frame. We divert from the nomenclature in the draft
308 		 * so that we can easily use a single function to gather path
309 		 * information from both PREQ and PREP frames.
310 		 */
311 		orig_addr = PREP_IE_ORIG_ADDR(hwmp_ie);
312 		orig_dsn = PREP_IE_ORIG_DSN(hwmp_ie);
313 		orig_lifetime = PREP_IE_LIFETIME(hwmp_ie);
314 		orig_metric = PREP_IE_METRIC(hwmp_ie);
315 		break;
316 	default:
317 		rcu_read_unlock();
318 		return 0;
319 	}
320 	new_metric = orig_metric + last_hop_metric;
321 	if (new_metric < orig_metric)
322 		new_metric = MAX_METRIC;
323 	exp_time = TU_TO_EXP_TIME(orig_lifetime);
324 
325 	if (memcmp(orig_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
326 		/* This MP is the originator, we are not interested in this
327 		 * frame, except for updating transmitter's path info.
328 		 */
329 		process = false;
330 		fresh_info = false;
331 	} else {
332 		mpath = mesh_path_lookup(orig_addr, sdata);
333 		if (mpath) {
334 			spin_lock_bh(&mpath->state_lock);
335 			if (mpath->flags & MESH_PATH_FIXED)
336 				fresh_info = false;
337 			else if ((mpath->flags & MESH_PATH_ACTIVE) &&
338 			    (mpath->flags & MESH_PATH_DSN_VALID)) {
339 				if (DSN_GT(mpath->dsn, orig_dsn) ||
340 				    (mpath->dsn == orig_dsn &&
341 				     action == MPATH_PREQ &&
342 				     new_metric > mpath->metric)) {
343 					process = false;
344 					fresh_info = false;
345 				}
346 			}
347 		} else {
348 			mesh_path_add(orig_addr, sdata);
349 			mpath = mesh_path_lookup(orig_addr, sdata);
350 			if (!mpath) {
351 				rcu_read_unlock();
352 				return 0;
353 			}
354 			spin_lock_bh(&mpath->state_lock);
355 		}
356 
357 		if (fresh_info) {
358 			mesh_path_assign_nexthop(mpath, sta);
359 			mpath->flags |= MESH_PATH_DSN_VALID;
360 			mpath->metric = new_metric;
361 			mpath->dsn = orig_dsn;
362 			mpath->exp_time = time_after(mpath->exp_time, exp_time)
363 					  ?  mpath->exp_time : exp_time;
364 			mesh_path_activate(mpath);
365 			spin_unlock_bh(&mpath->state_lock);
366 			mesh_path_tx_pending(mpath);
367 			/* draft says preq_id should be saved to, but there does
368 			 * not seem to be any use for it, skipping by now
369 			 */
370 		} else
371 			spin_unlock_bh(&mpath->state_lock);
372 	}
373 
374 	/* Update and check transmitter routing info */
375 	ta = mgmt->sa;
376 	if (memcmp(orig_addr, ta, ETH_ALEN) == 0)
377 		fresh_info = false;
378 	else {
379 		fresh_info = true;
380 
381 		mpath = mesh_path_lookup(ta, sdata);
382 		if (mpath) {
383 			spin_lock_bh(&mpath->state_lock);
384 			if ((mpath->flags & MESH_PATH_FIXED) ||
385 				((mpath->flags & MESH_PATH_ACTIVE) &&
386 					(last_hop_metric > mpath->metric)))
387 				fresh_info = false;
388 		} else {
389 			mesh_path_add(ta, sdata);
390 			mpath = mesh_path_lookup(ta, sdata);
391 			if (!mpath) {
392 				rcu_read_unlock();
393 				return 0;
394 			}
395 			spin_lock_bh(&mpath->state_lock);
396 		}
397 
398 		if (fresh_info) {
399 			mesh_path_assign_nexthop(mpath, sta);
400 			mpath->flags &= ~MESH_PATH_DSN_VALID;
401 			mpath->metric = last_hop_metric;
402 			mpath->exp_time = time_after(mpath->exp_time, exp_time)
403 					  ?  mpath->exp_time : exp_time;
404 			mesh_path_activate(mpath);
405 			spin_unlock_bh(&mpath->state_lock);
406 			mesh_path_tx_pending(mpath);
407 		} else
408 			spin_unlock_bh(&mpath->state_lock);
409 	}
410 
411 	rcu_read_unlock();
412 
413 	return process ? new_metric : 0;
414 }
415 
416 static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
417 				    struct ieee80211_mgmt *mgmt,
418 				    u8 *preq_elem, u32 metric)
419 {
420 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
421 	struct mesh_path *mpath;
422 	u8 *dst_addr, *orig_addr;
423 	u8 dst_flags, ttl;
424 	u32 orig_dsn, dst_dsn, lifetime;
425 	bool reply = false;
426 	bool forward = true;
427 
428 	/* Update destination DSN, if present */
429 	dst_addr = PREQ_IE_DST_ADDR(preq_elem);
430 	orig_addr = PREQ_IE_ORIG_ADDR(preq_elem);
431 	dst_dsn = PREQ_IE_DST_DSN(preq_elem);
432 	orig_dsn = PREQ_IE_ORIG_DSN(preq_elem);
433 	dst_flags = PREQ_IE_DST_F(preq_elem);
434 
435 	if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
436 		forward = false;
437 		reply = true;
438 		metric = 0;
439 		if (time_after(jiffies, ifmsh->last_dsn_update +
440 					net_traversal_jiffies(sdata)) ||
441 		    time_before(jiffies, ifmsh->last_dsn_update)) {
442 			dst_dsn = ++ifmsh->dsn;
443 			ifmsh->last_dsn_update = jiffies;
444 		}
445 	} else {
446 		rcu_read_lock();
447 		mpath = mesh_path_lookup(dst_addr, sdata);
448 		if (mpath) {
449 			if ((!(mpath->flags & MESH_PATH_DSN_VALID)) ||
450 					DSN_LT(mpath->dsn, dst_dsn)) {
451 				mpath->dsn = dst_dsn;
452 				mpath->flags |= MESH_PATH_DSN_VALID;
453 			} else if ((!(dst_flags & MP_F_DO)) &&
454 					(mpath->flags & MESH_PATH_ACTIVE)) {
455 				reply = true;
456 				metric = mpath->metric;
457 				dst_dsn = mpath->dsn;
458 				if (dst_flags & MP_F_RF)
459 					dst_flags |= MP_F_DO;
460 				else
461 					forward = false;
462 			}
463 		}
464 		rcu_read_unlock();
465 	}
466 
467 	if (reply) {
468 		lifetime = PREQ_IE_LIFETIME(preq_elem);
469 		ttl = ifmsh->mshcfg.dot11MeshTTL;
470 		if (ttl != 0)
471 			mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr,
472 				cpu_to_le32(dst_dsn), 0, orig_addr,
473 				cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl,
474 				cpu_to_le32(lifetime), cpu_to_le32(metric),
475 				0, sdata);
476 		else
477 			ifmsh->mshstats.dropped_frames_ttl++;
478 	}
479 
480 	if (forward) {
481 		u32 preq_id;
482 		u8 hopcount, flags;
483 
484 		ttl = PREQ_IE_TTL(preq_elem);
485 		lifetime = PREQ_IE_LIFETIME(preq_elem);
486 		if (ttl <= 1) {
487 			ifmsh->mshstats.dropped_frames_ttl++;
488 			return;
489 		}
490 		--ttl;
491 		flags = PREQ_IE_FLAGS(preq_elem);
492 		preq_id = PREQ_IE_PREQ_ID(preq_elem);
493 		hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
494 		mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
495 				cpu_to_le32(orig_dsn), dst_flags, dst_addr,
496 				cpu_to_le32(dst_dsn), sdata->dev->broadcast,
497 				hopcount, ttl, cpu_to_le32(lifetime),
498 				cpu_to_le32(metric), cpu_to_le32(preq_id),
499 				sdata);
500 		ifmsh->mshstats.fwded_mcast++;
501 		ifmsh->mshstats.fwded_frames++;
502 	}
503 }
504 
505 
506 static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
507 				    struct ieee80211_mgmt *mgmt,
508 				    u8 *prep_elem, u32 metric)
509 {
510 	struct mesh_path *mpath;
511 	u8 *dst_addr, *orig_addr;
512 	u8 ttl, hopcount, flags;
513 	u8 next_hop[ETH_ALEN];
514 	u32 dst_dsn, orig_dsn, lifetime;
515 
516 	/* Note that we divert from the draft nomenclature and denominate
517 	 * destination to what the draft refers to as origininator. So in this
518 	 * function destnation refers to the final destination of the PREP,
519 	 * which corresponds with the originator of the PREQ which this PREP
520 	 * replies
521 	 */
522 	dst_addr = PREP_IE_DST_ADDR(prep_elem);
523 	if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0)
524 		/* destination, no forwarding required */
525 		return;
526 
527 	ttl = PREP_IE_TTL(prep_elem);
528 	if (ttl <= 1) {
529 		sdata->u.mesh.mshstats.dropped_frames_ttl++;
530 		return;
531 	}
532 
533 	rcu_read_lock();
534 	mpath = mesh_path_lookup(dst_addr, sdata);
535 	if (mpath)
536 		spin_lock_bh(&mpath->state_lock);
537 	else
538 		goto fail;
539 	if (!(mpath->flags & MESH_PATH_ACTIVE)) {
540 		spin_unlock_bh(&mpath->state_lock);
541 		goto fail;
542 	}
543 	memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
544 	spin_unlock_bh(&mpath->state_lock);
545 	--ttl;
546 	flags = PREP_IE_FLAGS(prep_elem);
547 	lifetime = PREP_IE_LIFETIME(prep_elem);
548 	hopcount = PREP_IE_HOPCOUNT(prep_elem) + 1;
549 	orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
550 	dst_dsn = PREP_IE_DST_DSN(prep_elem);
551 	orig_dsn = PREP_IE_ORIG_DSN(prep_elem);
552 
553 	mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
554 		cpu_to_le32(orig_dsn), 0, dst_addr,
555 		cpu_to_le32(dst_dsn), mpath->next_hop->sta.addr, hopcount, ttl,
556 		cpu_to_le32(lifetime), cpu_to_le32(metric),
557 		0, sdata);
558 	rcu_read_unlock();
559 
560 	sdata->u.mesh.mshstats.fwded_unicast++;
561 	sdata->u.mesh.mshstats.fwded_frames++;
562 	return;
563 
564 fail:
565 	rcu_read_unlock();
566 	sdata->u.mesh.mshstats.dropped_frames_no_route++;
567 	return;
568 }
569 
570 static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
571 			     struct ieee80211_mgmt *mgmt, u8 *perr_elem)
572 {
573 	struct mesh_path *mpath;
574 	u8 *ta, *dst_addr;
575 	u32 dst_dsn;
576 
577 	ta = mgmt->sa;
578 	dst_addr = PERR_IE_DST_ADDR(perr_elem);
579 	dst_dsn = PERR_IE_DST_DSN(perr_elem);
580 	rcu_read_lock();
581 	mpath = mesh_path_lookup(dst_addr, sdata);
582 	if (mpath) {
583 		spin_lock_bh(&mpath->state_lock);
584 		if (mpath->flags & MESH_PATH_ACTIVE &&
585 		    memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 &&
586 		    (!(mpath->flags & MESH_PATH_DSN_VALID) ||
587 		    DSN_GT(dst_dsn, mpath->dsn))) {
588 			mpath->flags &= ~MESH_PATH_ACTIVE;
589 			mpath->dsn = dst_dsn;
590 			spin_unlock_bh(&mpath->state_lock);
591 			mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn),
592 					   sdata->dev->broadcast, sdata);
593 		} else
594 			spin_unlock_bh(&mpath->state_lock);
595 	}
596 	rcu_read_unlock();
597 }
598 
599 
600 
601 void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
602 			    struct ieee80211_mgmt *mgmt,
603 			    size_t len)
604 {
605 	struct ieee802_11_elems elems;
606 	size_t baselen;
607 	u32 last_hop_metric;
608 
609 	/* need action_code */
610 	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
611 		return;
612 
613 	baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
614 	ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
615 			len - baselen, &elems);
616 
617 	switch (mgmt->u.action.u.mesh_action.action_code) {
618 	case MPATH_PREQ:
619 		if (!elems.preq || elems.preq_len != 37)
620 			/* Right now we support just 1 destination and no AE */
621 			return;
622 		last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq);
623 		if (!last_hop_metric)
624 			return;
625 		hwmp_preq_frame_process(sdata, mgmt, elems.preq, last_hop_metric);
626 		break;
627 	case MPATH_PREP:
628 		if (!elems.prep || elems.prep_len != 31)
629 			/* Right now we support no AE */
630 			return;
631 		last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep);
632 		if (!last_hop_metric)
633 			return;
634 		hwmp_prep_frame_process(sdata, mgmt, elems.prep, last_hop_metric);
635 		break;
636 	case MPATH_PERR:
637 		if (!elems.perr || elems.perr_len != 12)
638 			/* Right now we support only one destination per PERR */
639 			return;
640 		hwmp_perr_frame_process(sdata, mgmt, elems.perr);
641 	default:
642 		return;
643 	}
644 
645 }
646 
647 /**
648  * mesh_queue_preq - queue a PREQ to a given destination
649  *
650  * @mpath: mesh path to discover
651  * @flags: special attributes of the PREQ to be sent
652  *
653  * Locking: the function must be called from within a rcu read lock block.
654  *
655  */
656 static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
657 {
658 	struct ieee80211_sub_if_data *sdata = mpath->sdata;
659 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
660 	struct mesh_preq_queue *preq_node;
661 
662 	preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC);
663 	if (!preq_node) {
664 		printk(KERN_DEBUG "Mesh HWMP: could not allocate PREQ node\n");
665 		return;
666 	}
667 
668 	spin_lock(&ifmsh->mesh_preq_queue_lock);
669 	if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) {
670 		spin_unlock(&ifmsh->mesh_preq_queue_lock);
671 		kfree(preq_node);
672 		if (printk_ratelimit())
673 			printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n");
674 		return;
675 	}
676 
677 	memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
678 	preq_node->flags = flags;
679 
680 	list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
681 	++ifmsh->preq_queue_len;
682 	spin_unlock(&ifmsh->mesh_preq_queue_lock);
683 
684 	if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
685 		ieee80211_queue_work(&sdata->local->hw, &ifmsh->work);
686 
687 	else if (time_before(jiffies, ifmsh->last_preq)) {
688 		/* avoid long wait if did not send preqs for a long time
689 		 * and jiffies wrapped around
690 		 */
691 		ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
692 		ieee80211_queue_work(&sdata->local->hw, &ifmsh->work);
693 	} else
694 		mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
695 						min_preq_int_jiff(sdata));
696 }
697 
698 /**
699  * mesh_path_start_discovery - launch a path discovery from the PREQ queue
700  *
701  * @sdata: local mesh subif
702  */
703 void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
704 {
705 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
706 	struct mesh_preq_queue *preq_node;
707 	struct mesh_path *mpath;
708 	u8 ttl, dst_flags;
709 	u32 lifetime;
710 
711 	spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
712 	if (!ifmsh->preq_queue_len ||
713 		time_before(jiffies, ifmsh->last_preq +
714 				min_preq_int_jiff(sdata))) {
715 		spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
716 		return;
717 	}
718 
719 	preq_node = list_first_entry(&ifmsh->preq_queue.list,
720 			struct mesh_preq_queue, list);
721 	list_del(&preq_node->list);
722 	--ifmsh->preq_queue_len;
723 	spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
724 
725 	rcu_read_lock();
726 	mpath = mesh_path_lookup(preq_node->dst, sdata);
727 	if (!mpath)
728 		goto enddiscovery;
729 
730 	spin_lock_bh(&mpath->state_lock);
731 	if (preq_node->flags & PREQ_Q_F_START) {
732 		if (mpath->flags & MESH_PATH_RESOLVING) {
733 			spin_unlock_bh(&mpath->state_lock);
734 			goto enddiscovery;
735 		} else {
736 			mpath->flags &= ~MESH_PATH_RESOLVED;
737 			mpath->flags |= MESH_PATH_RESOLVING;
738 			mpath->discovery_retries = 0;
739 			mpath->discovery_timeout = disc_timeout_jiff(sdata);
740 		}
741 	} else if (!(mpath->flags & MESH_PATH_RESOLVING) ||
742 			mpath->flags & MESH_PATH_RESOLVED) {
743 		mpath->flags &= ~MESH_PATH_RESOLVING;
744 		spin_unlock_bh(&mpath->state_lock);
745 		goto enddiscovery;
746 	}
747 
748 	ifmsh->last_preq = jiffies;
749 
750 	if (time_after(jiffies, ifmsh->last_dsn_update +
751 				net_traversal_jiffies(sdata)) ||
752 	    time_before(jiffies, ifmsh->last_dsn_update)) {
753 		++ifmsh->dsn;
754 		sdata->u.mesh.last_dsn_update = jiffies;
755 	}
756 	lifetime = default_lifetime(sdata);
757 	ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
758 	if (ttl == 0) {
759 		sdata->u.mesh.mshstats.dropped_frames_ttl++;
760 		spin_unlock_bh(&mpath->state_lock);
761 		goto enddiscovery;
762 	}
763 
764 	if (preq_node->flags & PREQ_Q_F_REFRESH)
765 		dst_flags = MP_F_DO;
766 	else
767 		dst_flags = MP_F_RF;
768 
769 	spin_unlock_bh(&mpath->state_lock);
770 	mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr,
771 			cpu_to_le32(ifmsh->dsn), dst_flags, mpath->dst,
772 			cpu_to_le32(mpath->dsn), sdata->dev->broadcast, 0,
773 			ttl, cpu_to_le32(lifetime), 0,
774 			cpu_to_le32(ifmsh->preq_id++), sdata);
775 	mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
776 
777 enddiscovery:
778 	rcu_read_unlock();
779 	kfree(preq_node);
780 }
781 
782 /**
783  * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame
784  *
785  * @skb: 802.11 frame to be sent
786  * @sdata: network subif the frame will be sent through
787  *
788  * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is
789  * found, the function will start a path discovery and queue the frame so it is
790  * sent when the path is resolved. This means the caller must not free the skb
791  * in this case.
792  */
793 int mesh_nexthop_lookup(struct sk_buff *skb,
794 			struct ieee80211_sub_if_data *sdata)
795 {
796 	struct sk_buff *skb_to_free = NULL;
797 	struct mesh_path *mpath;
798 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
799 	u8 *dst_addr = hdr->addr3;
800 	int err = 0;
801 
802 	rcu_read_lock();
803 	mpath = mesh_path_lookup(dst_addr, sdata);
804 
805 	if (!mpath) {
806 		mesh_path_add(dst_addr, sdata);
807 		mpath = mesh_path_lookup(dst_addr, sdata);
808 		if (!mpath) {
809 			sdata->u.mesh.mshstats.dropped_frames_no_route++;
810 			err = -ENOSPC;
811 			goto endlookup;
812 		}
813 	}
814 
815 	if (mpath->flags & MESH_PATH_ACTIVE) {
816 		if (time_after(jiffies, mpath->exp_time +
817 			msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
818 				&& !memcmp(sdata->dev->dev_addr, hdr->addr4,
819 					   ETH_ALEN)
820 				&& !(mpath->flags & MESH_PATH_RESOLVING)
821 				&& !(mpath->flags & MESH_PATH_FIXED)) {
822 			mesh_queue_preq(mpath,
823 					PREQ_Q_F_START | PREQ_Q_F_REFRESH);
824 		}
825 		memcpy(hdr->addr1, mpath->next_hop->sta.addr,
826 				ETH_ALEN);
827 	} else {
828 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
829 		if (!(mpath->flags & MESH_PATH_RESOLVING)) {
830 			/* Start discovery only if it is not running yet */
831 			mesh_queue_preq(mpath, PREQ_Q_F_START);
832 		}
833 
834 		if (skb_queue_len(&mpath->frame_queue) >=
835 				MESH_FRAME_QUEUE_LEN)
836 			skb_to_free = skb_dequeue(&mpath->frame_queue);
837 
838 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
839 		skb_queue_tail(&mpath->frame_queue, skb);
840 		if (skb_to_free)
841 			mesh_path_discard_frame(skb_to_free, sdata);
842 		err = -ENOENT;
843 	}
844 
845 endlookup:
846 	rcu_read_unlock();
847 	return err;
848 }
849 
850 void mesh_path_timer(unsigned long data)
851 {
852 	struct ieee80211_sub_if_data *sdata;
853 	struct mesh_path *mpath;
854 
855 	rcu_read_lock();
856 	mpath = (struct mesh_path *) data;
857 	mpath = rcu_dereference(mpath);
858 	if (!mpath)
859 		goto endmpathtimer;
860 	sdata = mpath->sdata;
861 
862 	if (sdata->local->quiescing) {
863 		rcu_read_unlock();
864 		return;
865 	}
866 
867 	spin_lock_bh(&mpath->state_lock);
868 	if (mpath->flags & MESH_PATH_RESOLVED ||
869 			(!(mpath->flags & MESH_PATH_RESOLVING)))
870 		mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
871 	else if (mpath->discovery_retries < max_preq_retries(sdata)) {
872 		++mpath->discovery_retries;
873 		mpath->discovery_timeout *= 2;
874 		mesh_queue_preq(mpath, 0);
875 	} else {
876 		mpath->flags = 0;
877 		mpath->exp_time = jiffies;
878 		mesh_path_flush_pending(mpath);
879 	}
880 
881 	spin_unlock_bh(&mpath->state_lock);
882 endmpathtimer:
883 	rcu_read_unlock();
884 }
885