ieee80211_mesh.c revision 252847
1/*-
2 * Copyright (c) 2009 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Rui Paulo under sponsorship from the
6 * FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29#include <sys/cdefs.h>
30#ifdef __FreeBSD__
31__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_mesh.c 252847 2013-07-05 22:10:50Z adrian $");
32#endif
33
34/*
35 * IEEE 802.11s Mesh Point (MBSS) support.
36 *
37 * Based on March 2009, D3.0 802.11s draft spec.
38 */
39#include "opt_inet.h"
40#include "opt_wlan.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/mbuf.h>
45#include <sys/malloc.h>
46#include <sys/kernel.h>
47
48#include <sys/socket.h>
49#include <sys/sockio.h>
50#include <sys/endian.h>
51#include <sys/errno.h>
52#include <sys/proc.h>
53#include <sys/sysctl.h>
54
55#include <net/bpf.h>
56#include <net/if.h>
57#include <net/if_media.h>
58#include <net/if_llc.h>
59#include <net/ethernet.h>
60
61#include <net80211/ieee80211_var.h>
62#include <net80211/ieee80211_action.h>
63#ifdef IEEE80211_SUPPORT_SUPERG
64#include <net80211/ieee80211_superg.h>
65#endif
66#include <net80211/ieee80211_input.h>
67#include <net80211/ieee80211_mesh.h>
68
69static void	mesh_rt_flush_invalid(struct ieee80211vap *);
70static int	mesh_select_proto_path(struct ieee80211vap *, const char *);
71static int	mesh_select_proto_metric(struct ieee80211vap *, const char *);
72static void	mesh_vattach(struct ieee80211vap *);
73static int	mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int);
74static void	mesh_rt_cleanup_cb(void *);
75static void	mesh_gatemode_setup(struct ieee80211vap *);
76static void	mesh_gatemode_cb(void *);
77static void	mesh_linkchange(struct ieee80211_node *,
78		    enum ieee80211_mesh_mlstate);
79static void	mesh_checkid(void *, struct ieee80211_node *);
80static uint32_t	mesh_generateid(struct ieee80211vap *);
81static int	mesh_checkpseq(struct ieee80211vap *,
82		    const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
83static void	mesh_transmit_to_gate(struct ieee80211vap *, struct mbuf *,
84		    struct ieee80211_mesh_route *);
85static void	mesh_forward(struct ieee80211vap *, struct mbuf *,
86		    const struct ieee80211_meshcntl *);
87static int	mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
88static void	mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
89		    int, int);
90static void	mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
91static void	mesh_peer_timeout_setup(struct ieee80211_node *);
92static void	mesh_peer_timeout_backoff(struct ieee80211_node *);
93static void	mesh_peer_timeout_cb(void *);
94static __inline void
95		mesh_peer_timeout_stop(struct ieee80211_node *);
96static int	mesh_verify_meshid(struct ieee80211vap *, const uint8_t *);
97static int	mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *);
98static int	mesh_verify_meshpeer(struct ieee80211vap *, uint8_t,
99    		    const uint8_t *);
100uint32_t	mesh_airtime_calc(struct ieee80211_node *);
101
102/*
103 * Timeout values come from the specification and are in milliseconds.
104 */
105static SYSCTL_NODE(_net_wlan, OID_AUTO, mesh, CTLFLAG_RD, 0,
106    "IEEE 802.11s parameters");
107static int	ieee80211_mesh_gateint = -1;
108SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, gateint, CTLTYPE_INT | CTLFLAG_RW,
109    &ieee80211_mesh_gateint, 0, ieee80211_sysctl_msecs_ticks, "I",
110    "mesh gate interval (ms)");
111static int ieee80211_mesh_retrytimeout = -1;
112SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, retrytimeout, CTLTYPE_INT | CTLFLAG_RW,
113    &ieee80211_mesh_retrytimeout, 0, ieee80211_sysctl_msecs_ticks, "I",
114    "Retry timeout (msec)");
115static int ieee80211_mesh_holdingtimeout = -1;
116
117SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, holdingtimeout, CTLTYPE_INT | CTLFLAG_RW,
118    &ieee80211_mesh_holdingtimeout, 0, ieee80211_sysctl_msecs_ticks, "I",
119    "Holding state timeout (msec)");
120static int ieee80211_mesh_confirmtimeout = -1;
121SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, confirmtimeout, CTLTYPE_INT | CTLFLAG_RW,
122    &ieee80211_mesh_confirmtimeout, 0, ieee80211_sysctl_msecs_ticks, "I",
123    "Confirm state timeout (msec)");
124static int ieee80211_mesh_backofftimeout = -1;
125SYSCTL_PROC(_net_wlan_mesh, OID_AUTO, backofftimeout, CTLTYPE_INT | CTLFLAG_RW,
126    &ieee80211_mesh_backofftimeout, 0, ieee80211_sysctl_msecs_ticks, "I",
127    "Backoff timeout (msec). This is to throutles peering forever when "
128    "not receving answer or is rejected by a neighbor");
129static int ieee80211_mesh_maxretries = 2;
130SYSCTL_INT(_net_wlan_mesh, OID_AUTO, maxretries, CTLTYPE_INT | CTLFLAG_RW,
131    &ieee80211_mesh_maxretries, 0,
132    "Maximum retries during peer link establishment");
133static int ieee80211_mesh_maxholding = 2;
134SYSCTL_INT(_net_wlan_mesh, OID_AUTO, maxholding, CTLTYPE_INT | CTLFLAG_RW,
135    &ieee80211_mesh_maxholding, 0,
136    "Maximum times we are allowed to transition to HOLDING state before "
137    "backinoff during peer link establishment");
138
139static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] =
140	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
141
142static	ieee80211_recv_action_func mesh_recv_action_meshpeering_open;
143static	ieee80211_recv_action_func mesh_recv_action_meshpeering_confirm;
144static	ieee80211_recv_action_func mesh_recv_action_meshpeering_close;
145static	ieee80211_recv_action_func mesh_recv_action_meshlmetric;
146static	ieee80211_recv_action_func mesh_recv_action_meshgate;
147
148static	ieee80211_send_action_func mesh_send_action_meshpeering_open;
149static	ieee80211_send_action_func mesh_send_action_meshpeering_confirm;
150static	ieee80211_send_action_func mesh_send_action_meshpeering_close;
151static	ieee80211_send_action_func mesh_send_action_meshlmetric;
152static	ieee80211_send_action_func mesh_send_action_meshgate;
153
154static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
155	.mpm_descr	= "AIRTIME",
156	.mpm_ie		= IEEE80211_MESHCONF_METRIC_AIRTIME,
157	.mpm_metric	= mesh_airtime_calc,
158};
159
160static struct ieee80211_mesh_proto_path		mesh_proto_paths[4];
161static struct ieee80211_mesh_proto_metric	mesh_proto_metrics[4];
162
163#define	RT_ENTRY_LOCK(rt)	mtx_lock(&(rt)->rt_lock)
164#define	RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
165#define	RT_ENTRY_UNLOCK(rt)	mtx_unlock(&(rt)->rt_lock)
166
167#define	MESH_RT_LOCK(ms)	mtx_lock(&(ms)->ms_rt_lock)
168#define	MESH_RT_LOCK_ASSERT(ms)	mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
169#define	MESH_RT_UNLOCK(ms)	mtx_unlock(&(ms)->ms_rt_lock)
170
171MALLOC_DEFINE(M_80211_MESH_PREQ, "80211preq", "802.11 MESH Path Request frame");
172MALLOC_DEFINE(M_80211_MESH_PREP, "80211prep", "802.11 MESH Path Reply frame");
173MALLOC_DEFINE(M_80211_MESH_PERR, "80211perr", "802.11 MESH Path Error frame");
174
175/* The longer one of the lifetime should be stored as new lifetime */
176#define MESH_ROUTE_LIFETIME_MAX(a, b)	(a > b ? a : b)
177
178MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh_rt", "802.11s routing table");
179MALLOC_DEFINE(M_80211_MESH_GT_RT, "80211mesh_gt", "802.11s known gates table");
180
181/*
182 * Helper functions to manipulate the Mesh routing table.
183 */
184
185static struct ieee80211_mesh_route *
186mesh_rt_find_locked(struct ieee80211_mesh_state *ms,
187    const uint8_t dest[IEEE80211_ADDR_LEN])
188{
189	struct ieee80211_mesh_route *rt;
190
191	MESH_RT_LOCK_ASSERT(ms);
192
193	TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
194		if (IEEE80211_ADDR_EQ(dest, rt->rt_dest))
195			return rt;
196	}
197	return NULL;
198}
199
200static struct ieee80211_mesh_route *
201mesh_rt_add_locked(struct ieee80211vap *vap,
202    const uint8_t dest[IEEE80211_ADDR_LEN])
203{
204	struct ieee80211_mesh_state *ms = vap->iv_mesh;
205	struct ieee80211_mesh_route *rt;
206
207	KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest),
208	    ("%s: adding broadcast to the routing table", __func__));
209
210	MESH_RT_LOCK_ASSERT(ms);
211
212	rt = malloc(ALIGN(sizeof(struct ieee80211_mesh_route)) +
213	    ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
214	if (rt != NULL) {
215		rt->rt_vap = vap;
216		IEEE80211_ADDR_COPY(rt->rt_dest, dest);
217		rt->rt_priv = (void *)ALIGN(&rt[1]);
218		mtx_init(&rt->rt_lock, "MBSS_RT", "802.11s route entry", MTX_DEF);
219		callout_init(&rt->rt_discovery, CALLOUT_MPSAFE);
220		rt->rt_updtime = ticks;	/* create time */
221		TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
222	}
223	return rt;
224}
225
226struct ieee80211_mesh_route *
227ieee80211_mesh_rt_find(struct ieee80211vap *vap,
228    const uint8_t dest[IEEE80211_ADDR_LEN])
229{
230	struct ieee80211_mesh_state *ms = vap->iv_mesh;
231	struct ieee80211_mesh_route *rt;
232
233	MESH_RT_LOCK(ms);
234	rt = mesh_rt_find_locked(ms, dest);
235	MESH_RT_UNLOCK(ms);
236	return rt;
237}
238
239struct ieee80211_mesh_route *
240ieee80211_mesh_rt_add(struct ieee80211vap *vap,
241    const uint8_t dest[IEEE80211_ADDR_LEN])
242{
243	struct ieee80211_mesh_state *ms = vap->iv_mesh;
244	struct ieee80211_mesh_route *rt;
245
246	KASSERT(ieee80211_mesh_rt_find(vap, dest) == NULL,
247	    ("%s: duplicate entry in the routing table", __func__));
248	KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest),
249	    ("%s: adding self to the routing table", __func__));
250
251	MESH_RT_LOCK(ms);
252	rt = mesh_rt_add_locked(vap, dest);
253	MESH_RT_UNLOCK(ms);
254	return rt;
255}
256
257/*
258 * Update the route lifetime and returns the updated lifetime.
259 * If new_lifetime is zero and route is timedout it will be invalidated.
260 * new_lifetime is in msec
261 */
262int
263ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
264{
265	int timesince, now;
266	uint32_t lifetime = 0;
267
268	KASSERT(rt != NULL, ("route is NULL"));
269
270	now = ticks;
271	RT_ENTRY_LOCK(rt);
272
273	/* dont clobber a proxy entry gated by us */
274	if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && rt->rt_nhops == 0) {
275		RT_ENTRY_UNLOCK(rt);
276		return rt->rt_lifetime;
277	}
278
279	timesince = ticks_to_msecs(now - rt->rt_updtime);
280	rt->rt_updtime = now;
281	if (timesince >= rt->rt_lifetime) {
282		if (new_lifetime != 0) {
283			rt->rt_lifetime = new_lifetime;
284		}
285		else {
286			rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID;
287			rt->rt_lifetime = 0;
288		}
289	} else {
290		/* update what is left of lifetime */
291		rt->rt_lifetime = rt->rt_lifetime - timesince;
292		rt->rt_lifetime  = MESH_ROUTE_LIFETIME_MAX(
293			new_lifetime, rt->rt_lifetime);
294	}
295	lifetime = rt->rt_lifetime;
296	RT_ENTRY_UNLOCK(rt);
297
298	return lifetime;
299}
300
301/*
302 * Add a proxy route (as needed) for the specified destination.
303 */
304void
305ieee80211_mesh_proxy_check(struct ieee80211vap *vap,
306    const uint8_t dest[IEEE80211_ADDR_LEN])
307{
308	struct ieee80211_mesh_state *ms = vap->iv_mesh;
309	struct ieee80211_mesh_route *rt;
310
311	MESH_RT_LOCK(ms);
312	rt = mesh_rt_find_locked(ms, dest);
313	if (rt == NULL) {
314		rt = mesh_rt_add_locked(vap, dest);
315		if (rt == NULL) {
316			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
317			    "%s", "unable to add proxy entry");
318			vap->iv_stats.is_mesh_rtaddfailed++;
319		} else {
320			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
321			    "%s", "add proxy entry");
322			IEEE80211_ADDR_COPY(rt->rt_mesh_gate, vap->iv_myaddr);
323			IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr);
324			rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID
325				     |  IEEE80211_MESHRT_FLAGS_PROXY;
326		}
327	} else if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
328		KASSERT(rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY,
329		    ("no proxy flag for poxy entry"));
330		struct ieee80211com *ic = vap->iv_ic;
331		/*
332		 * Fix existing entry created by received frames from
333		 * stations that have some memory of dest.  We also
334		 * flush any frames held on the staging queue; delivering
335		 * them is too much trouble right now.
336		 */
337		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
338		    "%s", "fix proxy entry");
339		IEEE80211_ADDR_COPY(rt->rt_nexthop, vap->iv_myaddr);
340		rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID
341			     |  IEEE80211_MESHRT_FLAGS_PROXY;
342		/* XXX belongs in hwmp */
343		ieee80211_ageq_drain_node(&ic->ic_stageq,
344		   (void *)(uintptr_t) ieee80211_mac_hash(ic, dest));
345		/* XXX stat? */
346	}
347	MESH_RT_UNLOCK(ms);
348}
349
350static __inline void
351mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt)
352{
353	TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
354	/*
355	 * Grab the lock before destroying it, to be sure no one else
356	 * is holding the route.
357	 */
358	RT_ENTRY_LOCK(rt);
359	callout_drain(&rt->rt_discovery);
360	mtx_destroy(&rt->rt_lock);
361	free(rt, M_80211_MESH_RT);
362}
363
364void
365ieee80211_mesh_rt_del(struct ieee80211vap *vap,
366    const uint8_t dest[IEEE80211_ADDR_LEN])
367{
368	struct ieee80211_mesh_state *ms = vap->iv_mesh;
369	struct ieee80211_mesh_route *rt, *next;
370
371	MESH_RT_LOCK(ms);
372	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
373		if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
374			if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) {
375				ms->ms_ppath->mpp_senderror(vap, dest, rt,
376				    IEEE80211_REASON_MESH_PERR_NO_PROXY);
377			} else {
378				ms->ms_ppath->mpp_senderror(vap, dest, rt,
379				    IEEE80211_REASON_MESH_PERR_DEST_UNREACH);
380			}
381			mesh_rt_del(ms, rt);
382			MESH_RT_UNLOCK(ms);
383			return;
384		}
385	}
386	MESH_RT_UNLOCK(ms);
387}
388
389void
390ieee80211_mesh_rt_flush(struct ieee80211vap *vap)
391{
392	struct ieee80211_mesh_state *ms = vap->iv_mesh;
393	struct ieee80211_mesh_route *rt, *next;
394
395	if (ms == NULL)
396		return;
397	MESH_RT_LOCK(ms);
398	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next)
399		mesh_rt_del(ms, rt);
400	MESH_RT_UNLOCK(ms);
401}
402
403void
404ieee80211_mesh_rt_flush_peer(struct ieee80211vap *vap,
405    const uint8_t peer[IEEE80211_ADDR_LEN])
406{
407	struct ieee80211_mesh_state *ms = vap->iv_mesh;
408	struct ieee80211_mesh_route *rt, *next;
409
410	MESH_RT_LOCK(ms);
411	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
412		if (IEEE80211_ADDR_EQ(rt->rt_nexthop, peer))
413			mesh_rt_del(ms, rt);
414	}
415	MESH_RT_UNLOCK(ms);
416}
417
418/*
419 * Flush expired routing entries, i.e. those in invalid state for
420 * some time.
421 */
422static void
423mesh_rt_flush_invalid(struct ieee80211vap *vap)
424{
425	struct ieee80211_mesh_state *ms = vap->iv_mesh;
426	struct ieee80211_mesh_route *rt, *next;
427
428	if (ms == NULL)
429		return;
430	MESH_RT_LOCK(ms);
431	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
432		/* Discover paths will be deleted by their own callout */
433		if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER)
434			continue;
435		ieee80211_mesh_rt_update(rt, 0);
436		if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0)
437			mesh_rt_del(ms, rt);
438	}
439	MESH_RT_UNLOCK(ms);
440}
441
442#define	N(a)	(sizeof(a) / sizeof(a[0]))
443int
444ieee80211_mesh_register_proto_path(const struct ieee80211_mesh_proto_path *mpp)
445{
446	int i, firstempty = -1;
447
448	for (i = 0; i < N(mesh_proto_paths); i++) {
449		if (strncmp(mpp->mpp_descr, mesh_proto_paths[i].mpp_descr,
450		    IEEE80211_MESH_PROTO_DSZ) == 0)
451			return EEXIST;
452		if (!mesh_proto_paths[i].mpp_active && firstempty == -1)
453			firstempty = i;
454	}
455	if (firstempty < 0)
456		return ENOSPC;
457	memcpy(&mesh_proto_paths[firstempty], mpp, sizeof(*mpp));
458	mesh_proto_paths[firstempty].mpp_active = 1;
459	return 0;
460}
461
462int
463ieee80211_mesh_register_proto_metric(const struct
464    ieee80211_mesh_proto_metric *mpm)
465{
466	int i, firstempty = -1;
467
468	for (i = 0; i < N(mesh_proto_metrics); i++) {
469		if (strncmp(mpm->mpm_descr, mesh_proto_metrics[i].mpm_descr,
470		    IEEE80211_MESH_PROTO_DSZ) == 0)
471			return EEXIST;
472		if (!mesh_proto_metrics[i].mpm_active && firstempty == -1)
473			firstempty = i;
474	}
475	if (firstempty < 0)
476		return ENOSPC;
477	memcpy(&mesh_proto_metrics[firstempty], mpm, sizeof(*mpm));
478	mesh_proto_metrics[firstempty].mpm_active = 1;
479	return 0;
480}
481
482static int
483mesh_select_proto_path(struct ieee80211vap *vap, const char *name)
484{
485	struct ieee80211_mesh_state *ms = vap->iv_mesh;
486	int i;
487
488	for (i = 0; i < N(mesh_proto_paths); i++) {
489		if (strcasecmp(mesh_proto_paths[i].mpp_descr, name) == 0) {
490			ms->ms_ppath = &mesh_proto_paths[i];
491			return 0;
492		}
493	}
494	return ENOENT;
495}
496
497static int
498mesh_select_proto_metric(struct ieee80211vap *vap, const char *name)
499{
500	struct ieee80211_mesh_state *ms = vap->iv_mesh;
501	int i;
502
503	for (i = 0; i < N(mesh_proto_metrics); i++) {
504		if (strcasecmp(mesh_proto_metrics[i].mpm_descr, name) == 0) {
505			ms->ms_pmetric = &mesh_proto_metrics[i];
506			return 0;
507		}
508	}
509	return ENOENT;
510}
511#undef	N
512
513static void
514mesh_gatemode_setup(struct ieee80211vap *vap)
515{
516	struct ieee80211_mesh_state *ms = vap->iv_mesh;
517
518	/*
519	 * NB: When a mesh gate is running as a ROOT it shall
520	 * not send out periodic GANNs but instead mark the
521	 * mesh gate flag for the corresponding proactive PREQ
522	 * and RANN frames.
523	 */
524	if (ms->ms_flags & IEEE80211_MESHFLAGS_ROOT ||
525	    (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) == 0) {
526		callout_drain(&ms->ms_gatetimer);
527		return ;
528	}
529	callout_reset(&ms->ms_gatetimer, ieee80211_mesh_gateint,
530	    mesh_gatemode_cb, vap);
531}
532
533static void
534mesh_gatemode_cb(void *arg)
535{
536	struct ieee80211vap *vap = (struct ieee80211vap *)arg;
537	struct ieee80211_mesh_state *ms = vap->iv_mesh;
538	struct ieee80211_meshgann_ie gann;
539
540	gann.gann_flags = 0; /* Reserved */
541	gann.gann_hopcount = 0;
542	gann.gann_ttl = ms->ms_ttl;
543	IEEE80211_ADDR_COPY(gann.gann_addr, vap->iv_myaddr);
544	gann.gann_seq = ms->ms_gateseq++;
545	gann.gann_interval = ieee80211_mesh_gateint;
546
547	IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, vap->iv_bss,
548	    "send broadcast GANN (seq %u)", gann.gann_seq);
549
550	ieee80211_send_action(vap->iv_bss, IEEE80211_ACTION_CAT_MESH,
551	    IEEE80211_ACTION_MESH_GANN, &gann);
552	mesh_gatemode_setup(vap);
553}
554
555static void
556ieee80211_mesh_init(void)
557{
558
559	memset(mesh_proto_paths, 0, sizeof(mesh_proto_paths));
560	memset(mesh_proto_metrics, 0, sizeof(mesh_proto_metrics));
561
562	/*
563	 * Setup mesh parameters that depends on the clock frequency.
564	 */
565	ieee80211_mesh_gateint = msecs_to_ticks(10000);
566	ieee80211_mesh_retrytimeout = msecs_to_ticks(40);
567	ieee80211_mesh_holdingtimeout = msecs_to_ticks(40);
568	ieee80211_mesh_confirmtimeout = msecs_to_ticks(40);
569	ieee80211_mesh_backofftimeout = msecs_to_ticks(5000);
570
571	/*
572	 * Register action frame handlers.
573	 */
574	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
575	    IEEE80211_ACTION_MESHPEERING_OPEN,
576	    mesh_recv_action_meshpeering_open);
577	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
578	    IEEE80211_ACTION_MESHPEERING_CONFIRM,
579	    mesh_recv_action_meshpeering_confirm);
580	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
581	    IEEE80211_ACTION_MESHPEERING_CLOSE,
582	    mesh_recv_action_meshpeering_close);
583	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH,
584	    IEEE80211_ACTION_MESH_LMETRIC, mesh_recv_action_meshlmetric);
585	ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH,
586	    IEEE80211_ACTION_MESH_GANN, mesh_recv_action_meshgate);
587
588	ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
589	    IEEE80211_ACTION_MESHPEERING_OPEN,
590	    mesh_send_action_meshpeering_open);
591	ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
592	    IEEE80211_ACTION_MESHPEERING_CONFIRM,
593	    mesh_send_action_meshpeering_confirm);
594	ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT,
595	    IEEE80211_ACTION_MESHPEERING_CLOSE,
596	    mesh_send_action_meshpeering_close);
597	ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESH,
598	    IEEE80211_ACTION_MESH_LMETRIC,
599	    mesh_send_action_meshlmetric);
600	ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESH,
601	    IEEE80211_ACTION_MESH_GANN,
602	    mesh_send_action_meshgate);
603
604	/*
605	 * Register Airtime Link Metric.
606	 */
607	ieee80211_mesh_register_proto_metric(&mesh_metric_airtime);
608
609}
610SYSINIT(wlan_mesh, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_mesh_init, NULL);
611
612void
613ieee80211_mesh_attach(struct ieee80211com *ic)
614{
615	ic->ic_vattach[IEEE80211_M_MBSS] = mesh_vattach;
616}
617
618void
619ieee80211_mesh_detach(struct ieee80211com *ic)
620{
621}
622
623static void
624mesh_vdetach_peers(void *arg, struct ieee80211_node *ni)
625{
626	struct ieee80211com *ic = ni->ni_ic;
627	uint16_t args[3];
628
629	if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED) {
630		args[0] = ni->ni_mlpid;
631		args[1] = ni->ni_mllid;
632		args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
633		ieee80211_send_action(ni,
634		    IEEE80211_ACTION_CAT_SELF_PROT,
635		    IEEE80211_ACTION_MESHPEERING_CLOSE,
636		    args);
637	}
638	callout_drain(&ni->ni_mltimer);
639	/* XXX belongs in hwmp */
640	ieee80211_ageq_drain_node(&ic->ic_stageq,
641	   (void *)(uintptr_t) ieee80211_mac_hash(ic, ni->ni_macaddr));
642}
643
644static void
645mesh_vdetach(struct ieee80211vap *vap)
646{
647	struct ieee80211_mesh_state *ms = vap->iv_mesh;
648
649	callout_drain(&ms->ms_cleantimer);
650	ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers,
651	    NULL);
652	ieee80211_mesh_rt_flush(vap);
653	mtx_destroy(&ms->ms_rt_lock);
654	ms->ms_ppath->mpp_vdetach(vap);
655	free(vap->iv_mesh, M_80211_VAP);
656	vap->iv_mesh = NULL;
657}
658
659static void
660mesh_vattach(struct ieee80211vap *vap)
661{
662	struct ieee80211_mesh_state *ms;
663	vap->iv_newstate = mesh_newstate;
664	vap->iv_input = mesh_input;
665	vap->iv_opdetach = mesh_vdetach;
666	vap->iv_recv_mgmt = mesh_recv_mgmt;
667	vap->iv_recv_ctl = mesh_recv_ctl;
668	ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
669	    M_NOWAIT | M_ZERO);
670	if (ms == NULL) {
671		printf("%s: couldn't alloc MBSS state\n", __func__);
672		return;
673	}
674	vap->iv_mesh = ms;
675	ms->ms_seq = 0;
676	ms->ms_flags = (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_FWD);
677	ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL;
678	TAILQ_INIT(&ms->ms_known_gates);
679	TAILQ_INIT(&ms->ms_routes);
680	mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF);
681	callout_init(&ms->ms_cleantimer, CALLOUT_MPSAFE);
682	callout_init(&ms->ms_gatetimer, CALLOUT_MPSAFE);
683	ms->ms_gateseq = 0;
684	mesh_select_proto_metric(vap, "AIRTIME");
685	KASSERT(ms->ms_pmetric, ("ms_pmetric == NULL"));
686	mesh_select_proto_path(vap, "HWMP");
687	KASSERT(ms->ms_ppath, ("ms_ppath == NULL"));
688	ms->ms_ppath->mpp_vattach(vap);
689}
690
691/*
692 * IEEE80211_M_MBSS vap state machine handler.
693 */
694static int
695mesh_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
696{
697	struct ieee80211_mesh_state *ms = vap->iv_mesh;
698	struct ieee80211com *ic = vap->iv_ic;
699	struct ieee80211_node *ni;
700	enum ieee80211_state ostate;
701
702	IEEE80211_LOCK_ASSERT(ic);
703
704	ostate = vap->iv_state;
705	IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
706	    __func__, ieee80211_state_name[ostate],
707	    ieee80211_state_name[nstate], arg);
708	vap->iv_state = nstate;		/* state transition */
709	if (ostate != IEEE80211_S_SCAN)
710		ieee80211_cancel_scan(vap);	/* background scan */
711	ni = vap->iv_bss;			/* NB: no reference held */
712	if (nstate != IEEE80211_S_RUN && ostate == IEEE80211_S_RUN) {
713		callout_drain(&ms->ms_cleantimer);
714		callout_drain(&ms->ms_gatetimer);
715	}
716	switch (nstate) {
717	case IEEE80211_S_INIT:
718		switch (ostate) {
719		case IEEE80211_S_SCAN:
720			ieee80211_cancel_scan(vap);
721			break;
722		case IEEE80211_S_CAC:
723			ieee80211_dfs_cac_stop(vap);
724			break;
725		case IEEE80211_S_RUN:
726			ieee80211_iterate_nodes(&ic->ic_sta,
727			    mesh_vdetach_peers, NULL);
728			break;
729		default:
730			break;
731		}
732		if (ostate != IEEE80211_S_INIT) {
733			/* NB: optimize INIT -> INIT case */
734			ieee80211_reset_bss(vap);
735			ieee80211_mesh_rt_flush(vap);
736		}
737		break;
738	case IEEE80211_S_SCAN:
739		switch (ostate) {
740		case IEEE80211_S_INIT:
741			if (vap->iv_des_chan != IEEE80211_CHAN_ANYC &&
742			    !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan) &&
743			    ms->ms_idlen != 0) {
744				/*
745				 * Already have a channel and a mesh ID; bypass
746				 * the scan and startup immediately.
747				 */
748				ieee80211_create_ibss(vap, vap->iv_des_chan);
749				break;
750			}
751			/*
752			 * Initiate a scan.  We can come here as a result
753			 * of an IEEE80211_IOC_SCAN_REQ too in which case
754			 * the vap will be marked with IEEE80211_FEXT_SCANREQ
755			 * and the scan request parameters will be present
756			 * in iv_scanreq.  Otherwise we do the default.
757			*/
758			if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
759				ieee80211_check_scan(vap,
760				    vap->iv_scanreq_flags,
761				    vap->iv_scanreq_duration,
762				    vap->iv_scanreq_mindwell,
763				    vap->iv_scanreq_maxdwell,
764				    vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
765				vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
766			} else
767				ieee80211_check_scan_current(vap);
768			break;
769		default:
770			break;
771		}
772		break;
773	case IEEE80211_S_CAC:
774		/*
775		 * Start CAC on a DFS channel.  We come here when starting
776		 * a bss on a DFS channel (see ieee80211_create_ibss).
777		 */
778		ieee80211_dfs_cac_start(vap);
779		break;
780	case IEEE80211_S_RUN:
781		switch (ostate) {
782		case IEEE80211_S_INIT:
783			/*
784			 * Already have a channel; bypass the
785			 * scan and startup immediately.
786			 * Note that ieee80211_create_ibss will call
787			 * back to do a RUN->RUN state change.
788			 */
789			ieee80211_create_ibss(vap,
790			    ieee80211_ht_adjust_channel(ic,
791				ic->ic_curchan, vap->iv_flags_ht));
792			/* NB: iv_bss is changed on return */
793			break;
794		case IEEE80211_S_CAC:
795			/*
796			 * NB: This is the normal state change when CAC
797			 * expires and no radar was detected; no need to
798			 * clear the CAC timer as it's already expired.
799			 */
800			/* fall thru... */
801		case IEEE80211_S_CSA:
802#if 0
803			/*
804			 * Shorten inactivity timer of associated stations
805			 * to weed out sta's that don't follow a CSA.
806			 */
807			ieee80211_iterate_nodes(&ic->ic_sta, sta_csa, vap);
808#endif
809			/*
810			 * Update bss node channel to reflect where
811			 * we landed after CSA.
812			 */
813			ieee80211_node_set_chan(vap->iv_bss,
814			    ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
815				ieee80211_htchanflags(vap->iv_bss->ni_chan)));
816			/* XXX bypass debug msgs */
817			break;
818		case IEEE80211_S_SCAN:
819		case IEEE80211_S_RUN:
820#ifdef IEEE80211_DEBUG
821			if (ieee80211_msg_debug(vap)) {
822				struct ieee80211_node *ni = vap->iv_bss;
823				ieee80211_note(vap,
824				    "synchronized with %s meshid ",
825				    ether_sprintf(ni->ni_meshid));
826				ieee80211_print_essid(ni->ni_meshid,
827				    ni->ni_meshidlen);
828				/* XXX MCS/HT */
829				printf(" channel %d\n",
830				    ieee80211_chan2ieee(ic, ic->ic_curchan));
831			}
832#endif
833			break;
834		default:
835			break;
836		}
837		ieee80211_node_authorize(vap->iv_bss);
838		callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact,
839                    mesh_rt_cleanup_cb, vap);
840		mesh_gatemode_setup(vap);
841		break;
842	default:
843		break;
844	}
845	/* NB: ostate not nstate */
846	ms->ms_ppath->mpp_newstate(vap, ostate, arg);
847	return 0;
848}
849
850static void
851mesh_rt_cleanup_cb(void *arg)
852{
853	struct ieee80211vap *vap = arg;
854	struct ieee80211_mesh_state *ms = vap->iv_mesh;
855
856	mesh_rt_flush_invalid(vap);
857	callout_reset(&ms->ms_cleantimer, ms->ms_ppath->mpp_inact,
858	    mesh_rt_cleanup_cb, vap);
859}
860
861/*
862 * Mark a mesh STA as gate and return a pointer to it.
863 * If this is first time, we create a new gate route.
864 * Always update the path route to this mesh gate.
865 */
866struct ieee80211_mesh_gate_route *
867ieee80211_mesh_mark_gate(struct ieee80211vap *vap, const uint8_t *addr,
868    struct ieee80211_mesh_route *rt)
869{
870	struct ieee80211_mesh_state *ms = vap->iv_mesh;
871	struct ieee80211_mesh_gate_route *gr = NULL, *next;
872	int found = 0;
873
874	MESH_RT_LOCK(ms);
875	TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, next) {
876		if (IEEE80211_ADDR_EQ(gr->gr_addr, addr)) {
877			found = 1;
878			break;
879		}
880	}
881
882	if (!found) {
883		/* New mesh gate add it to known table. */
884		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, addr,
885		    "%s", "stored new gate information from pro-PREQ.");
886		gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
887		    M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
888		IEEE80211_ADDR_COPY(gr->gr_addr, addr);
889		TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
890	}
891	gr->gr_route = rt;
892	/* TODO: link from path route to gate route */
893	MESH_RT_UNLOCK(ms);
894
895	return gr;
896}
897
898
899/*
900 * Helper function to note the Mesh Peer Link FSM change.
901 */
902static void
903mesh_linkchange(struct ieee80211_node *ni, enum ieee80211_mesh_mlstate state)
904{
905	struct ieee80211vap *vap = ni->ni_vap;
906	struct ieee80211_mesh_state *ms = vap->iv_mesh;
907#ifdef IEEE80211_DEBUG
908	static const char *meshlinkstates[] = {
909		[IEEE80211_NODE_MESH_IDLE]		= "IDLE",
910		[IEEE80211_NODE_MESH_OPENSNT]		= "OPEN SENT",
911		[IEEE80211_NODE_MESH_OPENRCV]		= "OPEN RECEIVED",
912		[IEEE80211_NODE_MESH_CONFIRMRCV]	= "CONFIRM RECEIVED",
913		[IEEE80211_NODE_MESH_ESTABLISHED]	= "ESTABLISHED",
914		[IEEE80211_NODE_MESH_HOLDING]		= "HOLDING"
915	};
916#endif
917	IEEE80211_NOTE(vap, IEEE80211_MSG_MESH,
918	    ni, "peer link: %s -> %s",
919	    meshlinkstates[ni->ni_mlstate], meshlinkstates[state]);
920
921	/* track neighbor count */
922	if (state == IEEE80211_NODE_MESH_ESTABLISHED &&
923	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
924		KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow"));
925		ms->ms_neighbors++;
926		ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF);
927	} else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED &&
928	    state != IEEE80211_NODE_MESH_ESTABLISHED) {
929		KASSERT(ms->ms_neighbors > 0, ("neighbor count 0"));
930		ms->ms_neighbors--;
931		ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF);
932	}
933	ni->ni_mlstate = state;
934	switch (state) {
935	case IEEE80211_NODE_MESH_HOLDING:
936		ms->ms_ppath->mpp_peerdown(ni);
937		break;
938	case IEEE80211_NODE_MESH_ESTABLISHED:
939		ieee80211_mesh_discover(vap, ni->ni_macaddr, NULL);
940		break;
941	default:
942		break;
943	}
944}
945
946/*
947 * Helper function to generate a unique local ID required for mesh
948 * peer establishment.
949 */
950static void
951mesh_checkid(void *arg, struct ieee80211_node *ni)
952{
953	uint16_t *r = arg;
954
955	if (*r == ni->ni_mllid)
956		*(uint16_t *)arg = 0;
957}
958
959static uint32_t
960mesh_generateid(struct ieee80211vap *vap)
961{
962	int maxiter = 4;
963	uint16_t r;
964
965	do {
966		get_random_bytes(&r, 2);
967		ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_checkid, &r);
968		maxiter--;
969	} while (r == 0 && maxiter > 0);
970	return r;
971}
972
973/*
974 * Verifies if we already received this packet by checking its
975 * sequence number.
976 * Returns 0 if the frame is to be accepted, 1 otherwise.
977 */
978static int
979mesh_checkpseq(struct ieee80211vap *vap,
980    const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq)
981{
982	struct ieee80211_mesh_route *rt;
983
984	rt = ieee80211_mesh_rt_find(vap, source);
985	if (rt == NULL) {
986		rt = ieee80211_mesh_rt_add(vap, source);
987		if (rt == NULL) {
988			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, source,
989			    "%s", "add mcast route failed");
990			vap->iv_stats.is_mesh_rtaddfailed++;
991			return 1;
992		}
993		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, source,
994		    "add mcast route, mesh seqno %d", seq);
995		rt->rt_lastmseq = seq;
996		return 0;
997	}
998	if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastmseq, seq)) {
999		return 1;
1000	} else {
1001		rt->rt_lastmseq = seq;
1002		return 0;
1003	}
1004}
1005
1006/*
1007 * Iterate the routing table and locate the next hop.
1008 */
1009struct ieee80211_node *
1010ieee80211_mesh_find_txnode(struct ieee80211vap *vap,
1011    const uint8_t dest[IEEE80211_ADDR_LEN])
1012{
1013	struct ieee80211_mesh_route *rt;
1014
1015	rt = ieee80211_mesh_rt_find(vap, dest);
1016	if (rt == NULL)
1017		return NULL;
1018	if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
1019		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
1020		    "%s: !valid, flags 0x%x", __func__, rt->rt_flags);
1021		/* XXX stat */
1022		return NULL;
1023	}
1024	if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) {
1025		rt = ieee80211_mesh_rt_find(vap, rt->rt_mesh_gate);
1026		if (rt == NULL) return NULL;
1027		if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
1028			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
1029			    "%s: meshgate !valid, flags 0x%x", __func__,
1030			    rt->rt_flags);
1031			/* XXX stat */
1032			return NULL;
1033		}
1034	}
1035	return ieee80211_find_txnode(vap, rt->rt_nexthop);
1036}
1037
1038static void
1039mesh_transmit_to_gate(struct ieee80211vap *vap, struct mbuf *m,
1040    struct ieee80211_mesh_route *rt_gate)
1041{
1042	struct ifnet *ifp = vap->iv_ifp;
1043	struct ieee80211com *ic = vap->iv_ic;
1044	struct ieee80211_node *ni;
1045	struct ether_header *eh;
1046	int error;
1047
1048	IEEE80211_TX_UNLOCK_ASSERT(ic);
1049
1050	eh = mtod(m, struct ether_header *);
1051	ni = ieee80211_mesh_find_txnode(vap, rt_gate->rt_dest);
1052	if (ni == NULL) {
1053		ifp->if_oerrors++;
1054		m_freem(m);
1055		return;
1056	}
1057
1058	if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
1059	    (m->m_flags & M_PWR_SAV) == 0) {
1060		/*
1061		 * Station in power save mode; pass the frame
1062		 * to the 802.11 layer and continue.  We'll get
1063		 * the frame back when the time is right.
1064		 * XXX lose WDS vap linkage?
1065		 */
1066		(void) ieee80211_pwrsave(ni, m);
1067		ieee80211_free_node(ni);
1068		return;
1069	}
1070
1071	/* calculate priority so drivers can find the tx queue */
1072	if (ieee80211_classify(ni, m)) {
1073		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_OUTPUT,
1074			eh->ether_dhost, NULL,
1075			"%s", "classification failure");
1076		vap->iv_stats.is_tx_classify++;
1077		ifp->if_oerrors++;
1078		m_freem(m);
1079		ieee80211_free_node(ni);
1080		return;
1081	}
1082	/*
1083	 * Stash the node pointer.  Note that we do this after
1084	 * any call to ieee80211_dwds_mcast because that code
1085	 * uses any existing value for rcvif to identify the
1086	 * interface it (might have been) received on.
1087	 */
1088	m->m_pkthdr.rcvif = (void *)ni;
1089
1090	BPF_MTAP(ifp, m);		/* 802.3 tx */
1091
1092	/*
1093	 * Check if A-MPDU tx aggregation is setup or if we
1094	 * should try to enable it.  The sta must be associated
1095	 * with HT and A-MPDU enabled for use.  When the policy
1096	 * routine decides we should enable A-MPDU we issue an
1097	 * ADDBA request and wait for a reply.  The frame being
1098	 * encapsulated will go out w/o using A-MPDU, or possibly
1099	 * it might be collected by the driver and held/retransmit.
1100	 * The default ic_ampdu_enable routine handles staggering
1101	 * ADDBA requests in case the receiver NAK's us or we are
1102	 * otherwise unable to establish a BA stream.
1103	 */
1104	if ((ni->ni_flags & IEEE80211_NODE_AMPDU_TX) &&
1105	    (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_TX) &&
1106	    (m->m_flags & M_EAPOL) == 0) {
1107		int tid = WME_AC_TO_TID(M_WME_GETAC(m));
1108		struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
1109
1110		ieee80211_txampdu_count_packet(tap);
1111		if (IEEE80211_AMPDU_RUNNING(tap)) {
1112			/*
1113			 * Operational, mark frame for aggregation.
1114			 *
1115			 * XXX do tx aggregation here
1116			 */
1117			m->m_flags |= M_AMPDU_MPDU;
1118		} else if (!IEEE80211_AMPDU_REQUESTED(tap) &&
1119			ic->ic_ampdu_enable(ni, tap)) {
1120			/*
1121			 * Not negotiated yet, request service.
1122			 */
1123			ieee80211_ampdu_request(ni, tap);
1124			/* XXX hold frame for reply? */
1125		}
1126	}
1127#ifdef IEEE80211_SUPPORT_SUPERG
1128	else if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF)) {
1129		m = ieee80211_ff_check(ni, m);
1130		if (m == NULL) {
1131			/* NB: any ni ref held on stageq */
1132			return;
1133		}
1134	}
1135#endif /* IEEE80211_SUPPORT_SUPERG */
1136
1137	IEEE80211_TX_LOCK(ic);
1138	if (__predict_true((vap->iv_caps & IEEE80211_C_8023ENCAP) == 0)) {
1139		/*
1140		 * Encapsulate the packet in prep for transmission.
1141		 */
1142		m = ieee80211_encap(vap, ni, m);
1143		if (m == NULL) {
1144			/* NB: stat+msg handled in ieee80211_encap */
1145			IEEE80211_TX_UNLOCK(ic);
1146			ieee80211_free_node(ni);
1147			return;
1148		}
1149	}
1150	error = ieee80211_parent_transmit(ic, m);
1151	IEEE80211_TX_UNLOCK(ic);
1152	if (error != 0) {
1153		ieee80211_free_node(ni);
1154	} else {
1155		ifp->if_opackets++;
1156	}
1157	ic->ic_lastdata = ticks;
1158}
1159
1160/*
1161 * Forward the queued frames to known valid mesh gates.
1162 * Assume destination to be outside the MBSS (i.e. proxy entry),
1163 * If no valid mesh gates are known silently discard queued frames.
1164 * After transmitting frames to all known valid mesh gates, this route
1165 * will be marked invalid, and a new path discovery will happen in the hopes
1166 * that (at least) one of the mesh gates have a new proxy entry for us to use.
1167 */
1168void
1169ieee80211_mesh_forward_to_gates(struct ieee80211vap *vap,
1170    struct ieee80211_mesh_route *rt_dest)
1171{
1172	struct ieee80211com *ic = vap->iv_ic;
1173	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1174	struct ieee80211_mesh_route *rt_gate;
1175	struct ieee80211_mesh_gate_route *gr = NULL, *gr_next;
1176	struct mbuf *m, *mcopy, *next;
1177
1178	IEEE80211_TX_UNLOCK_ASSERT(ic);
1179
1180	KASSERT( rt_dest->rt_flags == IEEE80211_MESHRT_FLAGS_DISCOVER,
1181	    ("Route is not marked with IEEE80211_MESHRT_FLAGS_DISCOVER"));
1182
1183	/* XXX: send to more than one valid mash gate */
1184	MESH_RT_LOCK(ms);
1185
1186	m = ieee80211_ageq_remove(&ic->ic_stageq,
1187	    (struct ieee80211_node *)(uintptr_t)
1188	    ieee80211_mac_hash(ic, rt_dest->rt_dest));
1189
1190	TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, gr_next) {
1191		rt_gate = gr->gr_route;
1192		if (rt_gate == NULL) {
1193			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP,
1194				rt_dest->rt_dest,
1195				"mesh gate with no path %6D",
1196				gr->gr_addr, ":");
1197			continue;
1198		}
1199		if ((rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0)
1200			continue;
1201		KASSERT(rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_GATE,
1202		    ("route not marked as a mesh gate"));
1203		KASSERT((rt_gate->rt_flags &
1204			IEEE80211_MESHRT_FLAGS_PROXY) == 0,
1205			("found mesh gate that is also marked porxy"));
1206		/*
1207		 * convert route to a proxy route gated by the current
1208		 * mesh gate, this is needed so encap can built data
1209		 * frame with correct address.
1210		 */
1211		rt_dest->rt_flags = IEEE80211_MESHRT_FLAGS_PROXY |
1212			IEEE80211_MESHRT_FLAGS_VALID;
1213		rt_dest->rt_ext_seq = 1; /* random value */
1214		IEEE80211_ADDR_COPY(rt_dest->rt_mesh_gate, rt_gate->rt_dest);
1215		IEEE80211_ADDR_COPY(rt_dest->rt_nexthop, rt_gate->rt_nexthop);
1216		rt_dest->rt_metric = rt_gate->rt_metric;
1217		rt_dest->rt_nhops = rt_gate->rt_nhops;
1218		ieee80211_mesh_rt_update(rt_dest, ms->ms_ppath->mpp_inact);
1219		MESH_RT_UNLOCK(ms);
1220		/* XXX: lock?? */
1221		mcopy = m_dup(m, M_NOWAIT);
1222		for (; mcopy != NULL; mcopy = next) {
1223			next = mcopy->m_nextpkt;
1224			mcopy->m_nextpkt = NULL;
1225			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP,
1226			    rt_dest->rt_dest,
1227			    "flush queued frame %p len %d", mcopy,
1228			    mcopy->m_pkthdr.len);
1229			mesh_transmit_to_gate(vap, mcopy, rt_gate);
1230		}
1231		MESH_RT_LOCK(ms);
1232	}
1233	rt_dest->rt_flags = 0; /* Mark invalid */
1234	m_freem(m);
1235	MESH_RT_UNLOCK(ms);
1236}
1237
1238/*
1239 * Forward the specified frame.
1240 * Decrement the TTL and set TA to our MAC address.
1241 */
1242static void
1243mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
1244    const struct ieee80211_meshcntl *mc)
1245{
1246	struct ieee80211com *ic = vap->iv_ic;
1247	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1248	struct ifnet *ifp = vap->iv_ifp;
1249	const struct ieee80211_frame *wh =
1250	    mtod(m, const struct ieee80211_frame *);
1251	struct mbuf *mcopy;
1252	struct ieee80211_meshcntl *mccopy;
1253	struct ieee80211_frame *whcopy;
1254	struct ieee80211_node *ni;
1255	int err;
1256
1257	/* This is called from the RX path - don't hold this lock */
1258	IEEE80211_TX_UNLOCK_ASSERT(ic);
1259
1260	/*
1261	 * mesh ttl of 1 means we are the last one receving it,
1262	 * according to amendment we decrement and then check if
1263	 * 0, if so we dont forward.
1264	 */
1265	if (mc->mc_ttl < 1) {
1266		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1267		    "%s", "frame not fwd'd, ttl 1");
1268		vap->iv_stats.is_mesh_fwd_ttl++;
1269		return;
1270	}
1271	if (!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
1272		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1273		    "%s", "frame not fwd'd, fwding disabled");
1274		vap->iv_stats.is_mesh_fwd_disabled++;
1275		return;
1276	}
1277	mcopy = m_dup(m, M_NOWAIT);
1278	if (mcopy == NULL) {
1279		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1280		    "%s", "frame not fwd'd, cannot dup");
1281		vap->iv_stats.is_mesh_fwd_nobuf++;
1282		ifp->if_oerrors++;
1283		return;
1284	}
1285	mcopy = m_pullup(mcopy, ieee80211_hdrspace(ic, wh) +
1286	    sizeof(struct ieee80211_meshcntl));
1287	if (mcopy == NULL) {
1288		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1289		    "%s", "frame not fwd'd, too short");
1290		vap->iv_stats.is_mesh_fwd_tooshort++;
1291		ifp->if_oerrors++;
1292		m_freem(mcopy);
1293		return;
1294	}
1295	whcopy = mtod(mcopy, struct ieee80211_frame *);
1296	mccopy = (struct ieee80211_meshcntl *)
1297	    (mtod(mcopy, uint8_t *) + ieee80211_hdrspace(ic, wh));
1298	/* XXX clear other bits? */
1299	whcopy->i_fc[1] &= ~IEEE80211_FC1_RETRY;
1300	IEEE80211_ADDR_COPY(whcopy->i_addr2, vap->iv_myaddr);
1301	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1302		ni = ieee80211_ref_node(vap->iv_bss);
1303		mcopy->m_flags |= M_MCAST;
1304	} else {
1305		ni = ieee80211_mesh_find_txnode(vap, whcopy->i_addr3);
1306		if (ni == NULL) {
1307			/*
1308			 * [Optional] any of the following three actions:
1309			 * o silently discard
1310			 * o trigger a path discovery
1311			 * o inform TA that meshDA is unknown.
1312			 */
1313			IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1314			    "%s", "frame not fwd'd, no path");
1315			ms->ms_ppath->mpp_senderror(vap, whcopy->i_addr3, NULL,
1316			    IEEE80211_REASON_MESH_PERR_NO_FI);
1317			vap->iv_stats.is_mesh_fwd_nopath++;
1318			m_freem(mcopy);
1319			return;
1320		}
1321		IEEE80211_ADDR_COPY(whcopy->i_addr1, ni->ni_macaddr);
1322	}
1323	KASSERT(mccopy->mc_ttl > 0, ("%s called with wrong ttl", __func__));
1324	mccopy->mc_ttl--;
1325
1326	/* XXX calculate priority so drivers can find the tx queue */
1327	M_WME_SETAC(mcopy, WME_AC_BE);
1328
1329	/* XXX do we know m_nextpkt is NULL? */
1330	mcopy->m_pkthdr.rcvif = (void *) ni;
1331
1332	/*
1333	 * XXX this bypasses all of the VAP TX handling; it passes frames
1334	 * directly to the parent interface.
1335	 *
1336	 * Because of this, there's no TX lock being held as there's no
1337	 * encaps state being used.
1338	 *
1339	 * Doing a direct parent transmit may not be the correct thing
1340	 * to do here; we'll have to re-think this soon.
1341	 */
1342	IEEE80211_TX_LOCK(ic);
1343	err = ieee80211_parent_transmit(ic, mcopy);
1344	IEEE80211_TX_UNLOCK(ic);
1345	if (err != 0) {
1346		/* NB: IFQ_HANDOFF reclaims mbuf */
1347		ieee80211_free_node(ni);
1348	} else {
1349		ifp->if_opackets++;
1350	}
1351}
1352
1353static struct mbuf *
1354mesh_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen, int meshdrlen)
1355{
1356#define	WHDIR(wh)	((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK)
1357#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1358	uint8_t b[sizeof(struct ieee80211_qosframe_addr4) +
1359		  sizeof(struct ieee80211_meshcntl_ae10)];
1360	const struct ieee80211_qosframe_addr4 *wh;
1361	const struct ieee80211_meshcntl_ae10 *mc;
1362	struct ether_header *eh;
1363	struct llc *llc;
1364	int ae;
1365
1366	if (m->m_len < hdrlen + sizeof(*llc) &&
1367	    (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) {
1368		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY,
1369		    "discard data frame: %s", "m_pullup failed");
1370		vap->iv_stats.is_rx_tooshort++;
1371		return NULL;
1372	}
1373	memcpy(b, mtod(m, caddr_t), hdrlen);
1374	wh = (const struct ieee80211_qosframe_addr4 *)&b[0];
1375	mc = (const struct ieee80211_meshcntl_ae10 *)&b[hdrlen - meshdrlen];
1376	KASSERT(WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS ||
1377		WHDIR(wh) == IEEE80211_FC1_DIR_DSTODS,
1378	    ("bogus dir, fc 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1]));
1379
1380	llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
1381	if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
1382	    llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
1383	    llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 &&
1384	    /* NB: preserve AppleTalk frames that have a native SNAP hdr */
1385	    !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) ||
1386	      llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) {
1387		m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
1388		llc = NULL;
1389	} else {
1390		m_adj(m, hdrlen - sizeof(*eh));
1391	}
1392	eh = mtod(m, struct ether_header *);
1393	ae = mc->mc_flags & IEEE80211_MESH_AE_MASK;
1394	if (WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS) {
1395		IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr1);
1396		if (ae == IEEE80211_MESH_AE_00) {
1397			IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr3);
1398		} else if (ae == IEEE80211_MESH_AE_01) {
1399			IEEE80211_ADDR_COPY(eh->ether_shost,
1400			    MC01(mc)->mc_addr4);
1401		} else {
1402			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1403			    (const struct ieee80211_frame *)wh, NULL,
1404			    "bad AE %d", ae);
1405			vap->iv_stats.is_mesh_badae++;
1406			m_freem(m);
1407			return NULL;
1408		}
1409	} else {
1410		if (ae == IEEE80211_MESH_AE_00) {
1411			IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr3);
1412			IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr4);
1413		} else if (ae == IEEE80211_MESH_AE_10) {
1414			IEEE80211_ADDR_COPY(eh->ether_dhost, mc->mc_addr5);
1415			IEEE80211_ADDR_COPY(eh->ether_shost, mc->mc_addr6);
1416		} else {
1417			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1418			    (const struct ieee80211_frame *)wh, NULL,
1419			    "bad AE %d", ae);
1420			vap->iv_stats.is_mesh_badae++;
1421			m_freem(m);
1422			return NULL;
1423		}
1424	}
1425#ifndef __NO_STRICT_ALIGNMENT
1426	if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) {
1427		m = ieee80211_realign(vap, m, sizeof(*eh));
1428		if (m == NULL)
1429			return NULL;
1430	}
1431#endif /* !__NO_STRICT_ALIGNMENT */
1432	if (llc != NULL) {
1433		eh = mtod(m, struct ether_header *);
1434		eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
1435	}
1436	return m;
1437#undef	WDIR
1438#undef	MC01
1439}
1440
1441/*
1442 * Return non-zero if the unicast mesh data frame should be processed
1443 * locally.  Frames that are not proxy'd have our address, otherwise
1444 * we need to consult the routing table to look for a proxy entry.
1445 */
1446static __inline int
1447mesh_isucastforme(struct ieee80211vap *vap, const struct ieee80211_frame *wh,
1448    const struct ieee80211_meshcntl *mc)
1449{
1450	int ae = mc->mc_flags & 3;
1451
1452	KASSERT((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS,
1453	    ("bad dir 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1]));
1454	KASSERT(ae == IEEE80211_MESH_AE_00 || ae == IEEE80211_MESH_AE_10,
1455	    ("bad AE %d", ae));
1456	if (ae == IEEE80211_MESH_AE_10) {	/* ucast w/ proxy */
1457		const struct ieee80211_meshcntl_ae10 *mc10 =
1458		    (const struct ieee80211_meshcntl_ae10 *) mc;
1459		struct ieee80211_mesh_route *rt =
1460		    ieee80211_mesh_rt_find(vap, mc10->mc_addr5);
1461		/* check for proxy route to ourself */
1462		return (rt != NULL &&
1463		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY));
1464	} else					/* ucast w/o proxy */
1465		return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr);
1466}
1467
1468/*
1469 * Verifies transmitter, updates lifetime, precursor list and forwards data.
1470 * > 0 means we have forwarded data and no need to process locally
1471 * == 0 means we want to process locally (and we may have forwarded data
1472 * < 0 means there was an error and data should be discarded
1473 */
1474static int
1475mesh_recv_indiv_data_to_fwrd(struct ieee80211vap *vap, struct mbuf *m,
1476    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1477{
1478	struct ieee80211_qosframe_addr4 *qwh;
1479	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1480	struct ieee80211_mesh_route *rt_meshda, *rt_meshsa;
1481
1482	/* This is called from the RX path - don't hold this lock */
1483	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1484
1485	qwh = (struct ieee80211_qosframe_addr4 *)wh;
1486
1487	/*
1488	 * TODO:
1489	 * o verify addr2 is  a legitimate transmitter
1490	 * o lifetime of precursor of addr3 (addr2) is max(init, curr)
1491	 * o lifetime of precursor of addr4 (nexthop) is max(init, curr)
1492	 */
1493
1494	/* set lifetime of addr3 (meshDA) to initial value */
1495	rt_meshda = ieee80211_mesh_rt_find(vap, qwh->i_addr3);
1496	if (rt_meshda == NULL) {
1497		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, qwh->i_addr2,
1498		    "no route to meshDA(%6D)", qwh->i_addr3, ":");
1499		/*
1500		 * [Optional] any of the following three actions:
1501		 * o silently discard 				[X]
1502		 * o trigger a path discovery			[ ]
1503		 * o inform TA that meshDA is unknown.		[ ]
1504		 */
1505		/* XXX: stats */
1506		return (-1);
1507	}
1508
1509	ieee80211_mesh_rt_update(rt_meshda, ticks_to_msecs(
1510	    ms->ms_ppath->mpp_inact));
1511
1512	/* set lifetime of addr4 (meshSA) to initial value */
1513	rt_meshsa = ieee80211_mesh_rt_find(vap, qwh->i_addr4);
1514	KASSERT(rt_meshsa != NULL, ("no route"));
1515	ieee80211_mesh_rt_update(rt_meshsa, ticks_to_msecs(
1516	    ms->ms_ppath->mpp_inact));
1517
1518	mesh_forward(vap, m, mc);
1519	return (1); /* dont process locally */
1520}
1521
1522/*
1523 * Verifies transmitter, updates lifetime, precursor list and process data
1524 * locally, if data is proxy with AE = 10 it could mean data should go
1525 * on another mesh path or data should be forwarded to the DS.
1526 *
1527 * > 0 means we have forwarded data and no need to process locally
1528 * == 0 means we want to process locally (and we may have forwarded data
1529 * < 0 means there was an error and data should be discarded
1530 */
1531static int
1532mesh_recv_indiv_data_to_me(struct ieee80211vap *vap, struct mbuf *m,
1533    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1534{
1535	struct ieee80211_qosframe_addr4 *qwh;
1536	const struct ieee80211_meshcntl_ae10 *mc10;
1537	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1538	struct ieee80211_mesh_route *rt;
1539	int ae;
1540
1541	/* This is called from the RX path - don't hold this lock */
1542	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1543
1544	qwh = (struct ieee80211_qosframe_addr4 *)wh;
1545	mc10 = (const struct ieee80211_meshcntl_ae10 *)mc;
1546
1547	/*
1548	 * TODO:
1549	 * o verify addr2 is  a legitimate transmitter
1550	 * o lifetime of precursor entry is max(init, curr)
1551	 */
1552
1553	/* set lifetime of addr4 (meshSA) to initial value */
1554	rt = ieee80211_mesh_rt_find(vap, qwh->i_addr4);
1555	KASSERT(rt != NULL, ("no route"));
1556	ieee80211_mesh_rt_update(rt, ticks_to_msecs(ms->ms_ppath->mpp_inact));
1557	rt = NULL;
1558
1559	ae = mc10->mc_flags & IEEE80211_MESH_AE_MASK;
1560	KASSERT(ae == IEEE80211_MESH_AE_00 ||
1561	    ae == IEEE80211_MESH_AE_10, ("bad AE %d", ae));
1562	if (ae == IEEE80211_MESH_AE_10) {
1563		if (IEEE80211_ADDR_EQ(mc10->mc_addr5, qwh->i_addr3)) {
1564			return (0); /* process locally */
1565		}
1566
1567		rt =  ieee80211_mesh_rt_find(vap, mc10->mc_addr5);
1568		if (rt != NULL &&
1569		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) &&
1570		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) == 0) {
1571			/*
1572			 * Forward on another mesh-path, according to
1573			 * amendment as specified in 9.32.4.1
1574			 */
1575			IEEE80211_ADDR_COPY(qwh->i_addr3, mc10->mc_addr5);
1576			mesh_forward(vap, m,
1577			    (const struct ieee80211_meshcntl *)mc10);
1578			return (1); /* dont process locally */
1579		}
1580		/*
1581		 * All other cases: forward of MSDUs from the MBSS to DS indiv.
1582		 * addressed according to 13.11.3.2.
1583		 */
1584		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, qwh->i_addr2,
1585		    "forward frame to DS, SA(%6D) DA(%6D)",
1586		    mc10->mc_addr6, ":", mc10->mc_addr5, ":");
1587	}
1588	return (0); /* process locally */
1589}
1590
1591/*
1592 * Try to forward the group addressed data on to other mesh STAs, and
1593 * also to the DS.
1594 *
1595 * > 0 means we have forwarded data and no need to process locally
1596 * == 0 means we want to process locally (and we may have forwarded data
1597 * < 0 means there was an error and data should be discarded
1598 */
1599static int
1600mesh_recv_group_data(struct ieee80211vap *vap, struct mbuf *m,
1601    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1602{
1603#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1604	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1605
1606	/* This is called from the RX path - don't hold this lock */
1607	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1608
1609	mesh_forward(vap, m, mc);
1610
1611	if(mc->mc_ttl > 0) {
1612		if (mc->mc_flags & IEEE80211_MESH_AE_01) {
1613			/*
1614			 * Forward of MSDUs from the MBSS to DS group addressed
1615			 * (according to 13.11.3.2)
1616			 * This happens by delivering the packet, and a bridge
1617			 * will sent it on another port member.
1618			 */
1619			if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE &&
1620			    ms->ms_flags & IEEE80211_MESHFLAGS_FWD)
1621				IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH,
1622				    MC01(mc)->mc_addr4, "%s",
1623				    "forward from MBSS to the DS");
1624		}
1625	}
1626	return (0); /* process locally */
1627#undef	MC01
1628}
1629
1630static int
1631mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
1632{
1633#define	HAS_SEQ(type)	((type & 0x4) == 0)
1634#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1635#define	MC10(mc)	((const struct ieee80211_meshcntl_ae10 *)mc)
1636	struct ieee80211vap *vap = ni->ni_vap;
1637	struct ieee80211com *ic = ni->ni_ic;
1638	struct ifnet *ifp = vap->iv_ifp;
1639	struct ieee80211_frame *wh;
1640	const struct ieee80211_meshcntl *mc;
1641	int hdrspace, meshdrlen, need_tap, error;
1642	uint8_t dir, type, subtype, ae;
1643	uint32_t seq;
1644	const uint8_t *addr;
1645	uint8_t qos[2];
1646	ieee80211_seq rxseq;
1647
1648	KASSERT(ni != NULL, ("null node"));
1649	ni->ni_inact = ni->ni_inact_reload;
1650
1651	need_tap = 1;			/* mbuf need to be tapped. */
1652	type = -1;			/* undefined */
1653
1654	/* This is called from the RX path - don't hold this lock */
1655	IEEE80211_TX_UNLOCK_ASSERT(ic);
1656
1657	if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
1658		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1659		    ni->ni_macaddr, NULL,
1660		    "too short (1): len %u", m->m_pkthdr.len);
1661		vap->iv_stats.is_rx_tooshort++;
1662		goto out;
1663	}
1664	/*
1665	 * Bit of a cheat here, we use a pointer for a 3-address
1666	 * frame format but don't reference fields past outside
1667	 * ieee80211_frame_min w/o first validating the data is
1668	 * present.
1669	*/
1670	wh = mtod(m, struct ieee80211_frame *);
1671
1672	if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
1673	    IEEE80211_FC0_VERSION_0) {
1674		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1675		    ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
1676		vap->iv_stats.is_rx_badversion++;
1677		goto err;
1678	}
1679	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1680	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1681	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1682	if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
1683		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
1684		ni->ni_noise = nf;
1685		if (HAS_SEQ(type)) {
1686			uint8_t tid = ieee80211_gettid(wh);
1687
1688			if (IEEE80211_QOS_HAS_SEQ(wh) &&
1689			    TID_TO_WME_AC(tid) >= WME_AC_VI)
1690				ic->ic_wme.wme_hipri_traffic++;
1691			rxseq = le16toh(*(uint16_t *)wh->i_seq);
1692			if (! ieee80211_check_rxseq(ni, wh)) {
1693				/* duplicate, discard */
1694				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1695				    wh->i_addr1, "duplicate",
1696				    "seqno <%u,%u> fragno <%u,%u> tid %u",
1697				    rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
1698				    ni->ni_rxseqs[tid] >>
1699				    IEEE80211_SEQ_SEQ_SHIFT,
1700				    rxseq & IEEE80211_SEQ_FRAG_MASK,
1701				    ni->ni_rxseqs[tid] &
1702				    IEEE80211_SEQ_FRAG_MASK,
1703				    tid);
1704				vap->iv_stats.is_rx_dup++;
1705				IEEE80211_NODE_STAT(ni, rx_dup);
1706				goto out;
1707			}
1708			ni->ni_rxseqs[tid] = rxseq;
1709		}
1710	}
1711#ifdef IEEE80211_DEBUG
1712	/*
1713	 * It's easier, but too expensive, to simulate different mesh
1714	 * topologies by consulting the ACL policy very early, so do this
1715	 * only under DEBUG.
1716	 *
1717	 * NB: this check is also done upon peering link initiation.
1718	 */
1719	if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) {
1720		IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL,
1721		    wh, NULL, "%s", "disallowed by ACL");
1722		vap->iv_stats.is_rx_acl++;
1723		goto out;
1724	}
1725#endif
1726	switch (type) {
1727	case IEEE80211_FC0_TYPE_DATA:
1728		if (ni == vap->iv_bss)
1729			goto out;
1730		if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
1731			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
1732			    ni->ni_macaddr, NULL,
1733			    "peer link not yet established (%d)",
1734			    ni->ni_mlstate);
1735			vap->iv_stats.is_mesh_nolink++;
1736			goto out;
1737		}
1738		if (dir != IEEE80211_FC1_DIR_FROMDS &&
1739		    dir != IEEE80211_FC1_DIR_DSTODS) {
1740			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1741			    wh, "data", "incorrect dir 0x%x", dir);
1742			vap->iv_stats.is_rx_wrongdir++;
1743			goto err;
1744		}
1745
1746		/* All Mesh data frames are QoS subtype */
1747		if (!HAS_SEQ(type)) {
1748			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1749			    wh, "data", "incorrect subtype 0x%x", subtype);
1750			vap->iv_stats.is_rx_badsubtype++;
1751			goto err;
1752		}
1753
1754		/*
1755		 * Next up, any fragmentation.
1756		 * XXX: we defrag before we even try to forward,
1757		 * Mesh Control field is not present in sub-sequent
1758		 * fragmented frames. This is in contrast to Draft 4.0.
1759		 */
1760		hdrspace = ieee80211_hdrspace(ic, wh);
1761		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1762			m = ieee80211_defrag(ni, m, hdrspace);
1763			if (m == NULL) {
1764				/* Fragment dropped or frame not complete yet */
1765				goto out;
1766			}
1767		}
1768		wh = mtod(m, struct ieee80211_frame *); /* NB: after defrag */
1769
1770		/*
1771		 * Now we have a complete Mesh Data frame.
1772		 */
1773
1774		/*
1775		 * Only fromDStoDS data frames use 4 address qos frames
1776		 * as specified in amendment. Otherwise addr4 is located
1777		 * in the Mesh Control field and a 3 address qos frame
1778		 * is used.
1779		 */
1780		if (IEEE80211_IS_DSTODS(wh))
1781			*(uint16_t *)qos = *(uint16_t *)
1782			    ((struct ieee80211_qosframe_addr4 *)wh)->i_qos;
1783		else
1784			*(uint16_t *)qos = *(uint16_t *)
1785			    ((struct ieee80211_qosframe *)wh)->i_qos;
1786
1787		/*
1788		 * NB: The mesh STA sets the Mesh Control Present
1789		 * subfield to 1 in the Mesh Data frame containing
1790		 * an unfragmented MSDU, an A-MSDU, or the first
1791		 * fragment of an MSDU.
1792		 * After defrag it should always be present.
1793		 */
1794		if (!(qos[1] & IEEE80211_QOS_MC)) {
1795			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
1796			    ni->ni_macaddr, NULL,
1797			    "%s", "Mesh control field not present");
1798			vap->iv_stats.is_rx_elem_missing++; /* XXX: kinda */
1799			goto err;
1800		}
1801
1802		/* pull up enough to get to the mesh control */
1803		if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) &&
1804		    (m = m_pullup(m, hdrspace +
1805		        sizeof(struct ieee80211_meshcntl))) == NULL) {
1806			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1807			    ni->ni_macaddr, NULL,
1808			    "data too short: expecting %u", hdrspace);
1809			vap->iv_stats.is_rx_tooshort++;
1810			goto out;		/* XXX */
1811		}
1812		/*
1813		 * Now calculate the full extent of the headers. Note
1814		 * mesh_decap will pull up anything we didn't get
1815		 * above when it strips the 802.11 headers.
1816		 */
1817		mc = (const struct ieee80211_meshcntl *)
1818		    (mtod(m, const uint8_t *) + hdrspace);
1819		ae = mc->mc_flags & IEEE80211_MESH_AE_MASK;
1820		meshdrlen = sizeof(struct ieee80211_meshcntl) +
1821		    ae * IEEE80211_ADDR_LEN;
1822		hdrspace += meshdrlen;
1823
1824		/* pull complete hdrspace = ieee80211_hdrspace + meshcontrol */
1825		if ((meshdrlen > sizeof(struct ieee80211_meshcntl)) &&
1826		    (m->m_len < hdrspace) &&
1827		    ((m = m_pullup(m, hdrspace)) == NULL)) {
1828			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1829			    ni->ni_macaddr, NULL,
1830			    "data too short: expecting %u", hdrspace);
1831			vap->iv_stats.is_rx_tooshort++;
1832			goto out;		/* XXX */
1833		}
1834		/* XXX: are we sure there is no reallocating after m_pullup? */
1835
1836		seq = LE_READ_4(mc->mc_seq);
1837		if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1838			addr = wh->i_addr3;
1839		else if (ae == IEEE80211_MESH_AE_01)
1840			addr = MC01(mc)->mc_addr4;
1841		else
1842			addr = ((struct ieee80211_qosframe_addr4 *)wh)->i_addr4;
1843		if (IEEE80211_ADDR_EQ(vap->iv_myaddr, addr)) {
1844			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1845			    addr, "data", "%s", "not to me");
1846			vap->iv_stats.is_rx_wrongbss++;	/* XXX kinda */
1847			goto out;
1848		}
1849		if (mesh_checkpseq(vap, addr, seq) != 0) {
1850			vap->iv_stats.is_rx_dup++;
1851			goto out;
1852		}
1853
1854		/* This code "routes" the frame to the right control path */
1855		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1856			if (IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr3))
1857				error =
1858				    mesh_recv_indiv_data_to_me(vap, m, wh, mc);
1859			else if (IEEE80211_IS_MULTICAST(wh->i_addr3))
1860				error = mesh_recv_group_data(vap, m, wh, mc);
1861			else
1862				error = mesh_recv_indiv_data_to_fwrd(vap, m,
1863				    wh, mc);
1864		} else
1865			error = mesh_recv_group_data(vap, m, wh, mc);
1866		if (error < 0)
1867			goto err;
1868		else if (error > 0)
1869			goto out;
1870
1871		if (ieee80211_radiotap_active_vap(vap))
1872			ieee80211_radiotap_rx(vap, m);
1873		need_tap = 0;
1874
1875		/*
1876		 * Finally, strip the 802.11 header.
1877		 */
1878		m = mesh_decap(vap, m, hdrspace, meshdrlen);
1879		if (m == NULL) {
1880			/* XXX mask bit to check for both */
1881			/* don't count Null data frames as errors */
1882			if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
1883			    subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
1884				goto out;
1885			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1886			    ni->ni_macaddr, "data", "%s", "decap error");
1887			vap->iv_stats.is_rx_decap++;
1888			IEEE80211_NODE_STAT(ni, rx_decap);
1889			goto err;
1890		}
1891		if (qos[0] & IEEE80211_QOS_AMSDU) {
1892			m = ieee80211_decap_amsdu(ni, m);
1893			if (m == NULL)
1894				return IEEE80211_FC0_TYPE_DATA;
1895		}
1896		ieee80211_deliver_data(vap, ni, m);
1897		return type;
1898	case IEEE80211_FC0_TYPE_MGT:
1899		vap->iv_stats.is_rx_mgmt++;
1900		IEEE80211_NODE_STAT(ni, rx_mgmt);
1901		if (dir != IEEE80211_FC1_DIR_NODS) {
1902			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1903			    wh, "mgt", "incorrect dir 0x%x", dir);
1904			vap->iv_stats.is_rx_wrongdir++;
1905			goto err;
1906		}
1907		if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
1908			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1909			    ni->ni_macaddr, "mgt", "too short: len %u",
1910			    m->m_pkthdr.len);
1911			vap->iv_stats.is_rx_tooshort++;
1912			goto out;
1913		}
1914#ifdef IEEE80211_DEBUG
1915		if ((ieee80211_msg_debug(vap) &&
1916		    (vap->iv_ic->ic_flags & IEEE80211_F_SCAN)) ||
1917		    ieee80211_msg_dumppkts(vap)) {
1918			if_printf(ifp, "received %s from %s rssi %d\n",
1919			    ieee80211_mgt_subtype_name[subtype >>
1920			    IEEE80211_FC0_SUBTYPE_SHIFT],
1921			    ether_sprintf(wh->i_addr2), rssi);
1922		}
1923#endif
1924		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1925			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1926			    wh, NULL, "%s", "WEP set but not permitted");
1927			vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
1928			goto out;
1929		}
1930		vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
1931		goto out;
1932	case IEEE80211_FC0_TYPE_CTL:
1933		vap->iv_stats.is_rx_ctl++;
1934		IEEE80211_NODE_STAT(ni, rx_ctrl);
1935		goto out;
1936	default:
1937		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1938		    wh, "bad", "frame type 0x%x", type);
1939		/* should not come here */
1940		break;
1941	}
1942err:
1943	ifp->if_ierrors++;
1944out:
1945	if (m != NULL) {
1946		if (need_tap && ieee80211_radiotap_active_vap(vap))
1947			ieee80211_radiotap_rx(vap, m);
1948		m_freem(m);
1949	}
1950	return type;
1951#undef	HAS_SEQ
1952#undef	MC01
1953#undef	MC10
1954}
1955
1956static void
1957mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
1958    int rssi, int nf)
1959{
1960	struct ieee80211vap *vap = ni->ni_vap;
1961	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1962	struct ieee80211com *ic = ni->ni_ic;
1963	struct ieee80211_frame *wh;
1964	struct ieee80211_mesh_route *rt;
1965	uint8_t *frm, *efrm;
1966
1967	wh = mtod(m0, struct ieee80211_frame *);
1968	frm = (uint8_t *)&wh[1];
1969	efrm = mtod(m0, uint8_t *) + m0->m_len;
1970	switch (subtype) {
1971	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1972	case IEEE80211_FC0_SUBTYPE_BEACON:
1973	{
1974		struct ieee80211_scanparams scan;
1975		/*
1976		 * We process beacon/probe response
1977		 * frames to discover neighbors.
1978		 */
1979		if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
1980			return;
1981		/*
1982		 * Count frame now that we know it's to be processed.
1983		 */
1984		if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1985			vap->iv_stats.is_rx_beacon++;	/* XXX remove */
1986			IEEE80211_NODE_STAT(ni, rx_beacons);
1987		} else
1988			IEEE80211_NODE_STAT(ni, rx_proberesp);
1989		/*
1990		 * If scanning, just pass information to the scan module.
1991		 */
1992		if (ic->ic_flags & IEEE80211_F_SCAN) {
1993			if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
1994				/*
1995				 * Actively scanning a channel marked passive;
1996				 * send a probe request now that we know there
1997				 * is 802.11 traffic present.
1998				 *
1999				 * XXX check if the beacon we recv'd gives
2000				 * us what we need and suppress the probe req
2001				 */
2002				ieee80211_probe_curchan(vap, 1);
2003				ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
2004			}
2005			ieee80211_add_scan(vap, &scan, wh,
2006			    subtype, rssi, nf);
2007			return;
2008		}
2009
2010		/* The rest of this code assumes we are running */
2011		if (vap->iv_state != IEEE80211_S_RUN)
2012			return;
2013		/*
2014		 * Ignore non-mesh STAs.
2015		 */
2016		if ((scan.capinfo &
2017		     (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) ||
2018		    scan.meshid == NULL || scan.meshconf == NULL) {
2019			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2020			    wh, "beacon", "%s", "not a mesh sta");
2021			vap->iv_stats.is_mesh_wrongmesh++;
2022			return;
2023		}
2024		/*
2025		 * Ignore STAs for other mesh networks.
2026		 */
2027		if (memcmp(scan.meshid+2, ms->ms_id, ms->ms_idlen) != 0 ||
2028		    mesh_verify_meshconf(vap, scan.meshconf)) {
2029			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2030			    wh, "beacon", "%s", "not for our mesh");
2031			vap->iv_stats.is_mesh_wrongmesh++;
2032			return;
2033		}
2034		/*
2035		 * Peer only based on the current ACL policy.
2036		 */
2037		if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) {
2038			IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL,
2039			    wh, NULL, "%s", "disallowed by ACL");
2040			vap->iv_stats.is_rx_acl++;
2041			return;
2042		}
2043		/*
2044		 * Do neighbor discovery.
2045		 */
2046		if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
2047			/*
2048			 * Create a new entry in the neighbor table.
2049			 */
2050			ni = ieee80211_add_neighbor(vap, wh, &scan);
2051		}
2052		/*
2053		 * Automatically peer with discovered nodes if possible.
2054		 */
2055		if (ni != vap->iv_bss &&
2056		    (ms->ms_flags & IEEE80211_MESHFLAGS_AP)) {
2057			switch (ni->ni_mlstate) {
2058			case IEEE80211_NODE_MESH_IDLE:
2059			{
2060				uint16_t args[1];
2061
2062				/* Wait for backoff callout to reset counter */
2063				if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding)
2064					return;
2065
2066				ni->ni_mlpid = mesh_generateid(vap);
2067				if (ni->ni_mlpid == 0)
2068					return;
2069				mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT);
2070				args[0] = ni->ni_mlpid;
2071				ieee80211_send_action(ni,
2072				IEEE80211_ACTION_CAT_SELF_PROT,
2073				IEEE80211_ACTION_MESHPEERING_OPEN, args);
2074				ni->ni_mlrcnt = 0;
2075				mesh_peer_timeout_setup(ni);
2076				break;
2077			}
2078			case IEEE80211_NODE_MESH_ESTABLISHED:
2079			{
2080				/*
2081				 * Valid beacon from a peer mesh STA
2082				 * bump TA lifetime
2083				 */
2084				rt = ieee80211_mesh_rt_find(vap, wh->i_addr2);
2085				if(rt != NULL) {
2086					ieee80211_mesh_rt_update(rt,
2087					    ticks_to_msecs(
2088					    ms->ms_ppath->mpp_inact));
2089				}
2090				break;
2091			}
2092			default:
2093				break; /* ignore */
2094			}
2095		}
2096		break;
2097	}
2098	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2099	{
2100		uint8_t *ssid, *meshid, *rates, *xrates;
2101		uint8_t *sfrm;
2102
2103		if (vap->iv_state != IEEE80211_S_RUN) {
2104			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2105			    wh, NULL, "wrong state %s",
2106			    ieee80211_state_name[vap->iv_state]);
2107			vap->iv_stats.is_rx_mgtdiscard++;
2108			return;
2109		}
2110		if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
2111			/* frame must be directed */
2112			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2113			    wh, NULL, "%s", "not unicast");
2114			vap->iv_stats.is_rx_mgtdiscard++;	/* XXX stat */
2115			return;
2116		}
2117		/*
2118		 * prreq frame format
2119		 *      [tlv] ssid
2120		 *      [tlv] supported rates
2121		 *      [tlv] extended supported rates
2122		 *	[tlv] mesh id
2123		 */
2124		ssid = meshid = rates = xrates = NULL;
2125		sfrm = frm;
2126		while (efrm - frm > 1) {
2127			IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
2128			switch (*frm) {
2129			case IEEE80211_ELEMID_SSID:
2130				ssid = frm;
2131				break;
2132			case IEEE80211_ELEMID_RATES:
2133				rates = frm;
2134				break;
2135			case IEEE80211_ELEMID_XRATES:
2136				xrates = frm;
2137				break;
2138			case IEEE80211_ELEMID_MESHID:
2139				meshid = frm;
2140				break;
2141			}
2142			frm += frm[1] + 2;
2143		}
2144		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return);
2145		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
2146		if (xrates != NULL)
2147			IEEE80211_VERIFY_ELEMENT(xrates,
2148			    IEEE80211_RATE_MAXSIZE - rates[1], return);
2149		if (meshid != NULL) {
2150			IEEE80211_VERIFY_ELEMENT(meshid,
2151			    IEEE80211_MESHID_LEN, return);
2152			/* NB: meshid, not ssid */
2153			IEEE80211_VERIFY_SSID(vap->iv_bss, meshid, return);
2154		}
2155
2156		/* XXX find a better class or define it's own */
2157		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
2158		    "%s", "recv probe req");
2159		/*
2160		 * Some legacy 11b clients cannot hack a complete
2161		 * probe response frame.  When the request includes
2162		 * only a bare-bones rate set, communicate this to
2163		 * the transmit side.
2164		 */
2165		ieee80211_send_proberesp(vap, wh->i_addr2, 0);
2166		break;
2167	}
2168
2169	case IEEE80211_FC0_SUBTYPE_ACTION:
2170	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
2171		if (ni == vap->iv_bss) {
2172			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2173			    wh, NULL, "%s", "unknown node");
2174			vap->iv_stats.is_rx_mgtdiscard++;
2175		} else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
2176		    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2177			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2178			    wh, NULL, "%s", "not for us");
2179			vap->iv_stats.is_rx_mgtdiscard++;
2180		} else if (vap->iv_state != IEEE80211_S_RUN) {
2181			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2182			    wh, NULL, "wrong state %s",
2183			    ieee80211_state_name[vap->iv_state]);
2184			vap->iv_stats.is_rx_mgtdiscard++;
2185		} else {
2186			if (ieee80211_parse_action(ni, m0) == 0)
2187				(void)ic->ic_recv_action(ni, wh, frm, efrm);
2188		}
2189		break;
2190
2191	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2192	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2193	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
2194	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
2195	case IEEE80211_FC0_SUBTYPE_ATIM:
2196	case IEEE80211_FC0_SUBTYPE_DISASSOC:
2197	case IEEE80211_FC0_SUBTYPE_AUTH:
2198	case IEEE80211_FC0_SUBTYPE_DEAUTH:
2199		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2200		    wh, NULL, "%s", "not handled");
2201		vap->iv_stats.is_rx_mgtdiscard++;
2202		break;
2203
2204	default:
2205		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
2206		    wh, "mgt", "subtype 0x%x not handled", subtype);
2207		vap->iv_stats.is_rx_badsubtype++;
2208		break;
2209	}
2210}
2211
2212static void
2213mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
2214{
2215
2216	switch (subtype) {
2217	case IEEE80211_FC0_SUBTYPE_BAR:
2218		ieee80211_recv_bar(ni, m);
2219		break;
2220	}
2221}
2222
2223/*
2224 * Parse meshpeering action ie's for MPM frames
2225 */
2226static const struct ieee80211_meshpeer_ie *
2227mesh_parse_meshpeering_action(struct ieee80211_node *ni,
2228	const struct ieee80211_frame *wh,	/* XXX for VERIFY_LENGTH */
2229	const uint8_t *frm, const uint8_t *efrm,
2230	struct ieee80211_meshpeer_ie *mp, uint8_t subtype)
2231{
2232	struct ieee80211vap *vap = ni->ni_vap;
2233	const struct ieee80211_meshpeer_ie *mpie;
2234	uint16_t args[3];
2235	const uint8_t *meshid, *meshconf, *meshpeer;
2236	uint8_t sendclose = 0; /* 1 = MPM frame rejected, close will be sent */
2237
2238	meshid = meshconf = meshpeer = NULL;
2239	while (efrm - frm > 1) {
2240		IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL);
2241		switch (*frm) {
2242		case IEEE80211_ELEMID_MESHID:
2243			meshid = frm;
2244			break;
2245		case IEEE80211_ELEMID_MESHCONF:
2246			meshconf = frm;
2247			break;
2248		case IEEE80211_ELEMID_MESHPEER:
2249			meshpeer = frm;
2250			mpie = (const struct ieee80211_meshpeer_ie *) frm;
2251			memset(mp, 0, sizeof(*mp));
2252			mp->peer_len = mpie->peer_len;
2253			mp->peer_proto = LE_READ_2(&mpie->peer_proto);
2254			mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
2255			switch (subtype) {
2256			case IEEE80211_ACTION_MESHPEERING_CONFIRM:
2257				mp->peer_linkid =
2258				    LE_READ_2(&mpie->peer_linkid);
2259				break;
2260			case IEEE80211_ACTION_MESHPEERING_CLOSE:
2261				/* NB: peer link ID is optional */
2262				if (mpie->peer_len ==
2263				    (IEEE80211_MPM_BASE_SZ + 2)) {
2264					mp->peer_linkid = 0;
2265					mp->peer_rcode =
2266					    LE_READ_2(&mpie->peer_linkid);
2267				} else {
2268					mp->peer_linkid =
2269					    LE_READ_2(&mpie->peer_linkid);
2270					mp->peer_rcode =
2271					    LE_READ_2(&mpie->peer_rcode);
2272				}
2273				break;
2274			}
2275			break;
2276		}
2277		frm += frm[1] + 2;
2278	}
2279
2280	/*
2281	 * Verify the contents of the frame.
2282	 * If it fails validation, close the peer link.
2283	 */
2284	if (mesh_verify_meshpeer(vap, subtype, (const uint8_t *)mp)) {
2285		sendclose = 1;
2286		IEEE80211_DISCARD(vap,
2287		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2288		    wh, NULL, "%s", "MPM validation failed");
2289	}
2290
2291	/* If meshid is not the same reject any frames type. */
2292	if (sendclose == 0 && mesh_verify_meshid(vap, meshid)) {
2293		sendclose = 1;
2294		IEEE80211_DISCARD(vap,
2295		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2296		    wh, NULL, "%s", "not for our mesh");
2297		if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE) {
2298			/*
2299			 * Standard not clear about this, if we dont ignore
2300			 * there will be an endless loop between nodes sending
2301			 * CLOSE frames between each other with wrong meshid.
2302			 * Discard and timers will bring FSM to IDLE state.
2303			 */
2304			return NULL;
2305		}
2306	}
2307
2308	/*
2309	 * Close frames are accepted if meshid is the same.
2310	 * Verify the other two types.
2311	 */
2312	if (sendclose == 0 && subtype != IEEE80211_ACTION_MESHPEERING_CLOSE &&
2313	    mesh_verify_meshconf(vap, meshconf)) {
2314		sendclose = 1;
2315		IEEE80211_DISCARD(vap,
2316		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2317		    wh, NULL, "%s", "configuration missmatch");
2318	}
2319
2320	if (sendclose) {
2321		vap->iv_stats.is_rx_mgtdiscard++;
2322		switch (ni->ni_mlstate) {
2323		case IEEE80211_NODE_MESH_IDLE:
2324		case IEEE80211_NODE_MESH_ESTABLISHED:
2325		case IEEE80211_NODE_MESH_HOLDING:
2326			/* ignore */
2327			break;
2328		case IEEE80211_NODE_MESH_OPENSNT:
2329		case IEEE80211_NODE_MESH_OPENRCV:
2330		case IEEE80211_NODE_MESH_CONFIRMRCV:
2331			args[0] = ni->ni_mlpid;
2332			args[1] = ni->ni_mllid;
2333			/* Reason codes for rejection */
2334			switch (subtype) {
2335			case IEEE80211_ACTION_MESHPEERING_OPEN:
2336				args[2] = IEEE80211_REASON_MESH_CPVIOLATION;
2337				break;
2338			case IEEE80211_ACTION_MESHPEERING_CONFIRM:
2339				args[2] = IEEE80211_REASON_MESH_INCONS_PARAMS;
2340				break;
2341			}
2342			ieee80211_send_action(ni,
2343			    IEEE80211_ACTION_CAT_SELF_PROT,
2344			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2345			    args);
2346			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2347			mesh_peer_timeout_setup(ni);
2348			break;
2349		}
2350		return NULL;
2351	}
2352
2353	return (const struct ieee80211_meshpeer_ie *) mp;
2354}
2355
2356static int
2357mesh_recv_action_meshpeering_open(struct ieee80211_node *ni,
2358	const struct ieee80211_frame *wh,
2359	const uint8_t *frm, const uint8_t *efrm)
2360{
2361	struct ieee80211vap *vap = ni->ni_vap;
2362	struct ieee80211_mesh_state *ms = vap->iv_mesh;
2363	struct ieee80211_meshpeer_ie ie;
2364	const struct ieee80211_meshpeer_ie *meshpeer;
2365	uint16_t args[3];
2366
2367	/* +2+2 for action + code + capabilites */
2368	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie,
2369	    IEEE80211_ACTION_MESHPEERING_OPEN);
2370	if (meshpeer == NULL) {
2371		return 0;
2372	}
2373
2374	/* XXX move up */
2375	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2376	    "recv PEER OPEN, lid 0x%x", meshpeer->peer_llinkid);
2377
2378	switch (ni->ni_mlstate) {
2379	case IEEE80211_NODE_MESH_IDLE:
2380		/* Reject open request if reached our maximum neighbor count */
2381		if (ms->ms_neighbors >= IEEE80211_MESH_MAX_NEIGHBORS) {
2382			args[0] = meshpeer->peer_llinkid;
2383			args[1] = 0;
2384			args[2] = IEEE80211_REASON_MESH_MAX_PEERS;
2385			ieee80211_send_action(ni,
2386			    IEEE80211_ACTION_CAT_SELF_PROT,
2387			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2388			    args);
2389			/* stay in IDLE state */
2390			return (0);
2391		}
2392		/* Open frame accepted */
2393		mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV);
2394		ni->ni_mllid = meshpeer->peer_llinkid;
2395		ni->ni_mlpid = mesh_generateid(vap);
2396		if (ni->ni_mlpid == 0)
2397			return 0;		/* XXX */
2398		args[0] = ni->ni_mlpid;
2399		/* Announce we're open too... */
2400		ieee80211_send_action(ni,
2401		    IEEE80211_ACTION_CAT_SELF_PROT,
2402		    IEEE80211_ACTION_MESHPEERING_OPEN, args);
2403		/* ...and confirm the link. */
2404		args[0] = ni->ni_mlpid;
2405		args[1] = ni->ni_mllid;
2406		ieee80211_send_action(ni,
2407		    IEEE80211_ACTION_CAT_SELF_PROT,
2408		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2409		    args);
2410		mesh_peer_timeout_setup(ni);
2411		break;
2412	case IEEE80211_NODE_MESH_OPENRCV:
2413		/* Wrong Link ID */
2414		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2415			args[0] = ni->ni_mllid;
2416			args[1] = ni->ni_mlpid;
2417			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2418			ieee80211_send_action(ni,
2419			    IEEE80211_ACTION_CAT_SELF_PROT,
2420			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2421			    args);
2422			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2423			mesh_peer_timeout_setup(ni);
2424			break;
2425		}
2426		/* Duplicate open, confirm again. */
2427		args[0] = ni->ni_mlpid;
2428		args[1] = ni->ni_mllid;
2429		ieee80211_send_action(ni,
2430		    IEEE80211_ACTION_CAT_SELF_PROT,
2431		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2432		    args);
2433		break;
2434	case IEEE80211_NODE_MESH_OPENSNT:
2435		ni->ni_mllid = meshpeer->peer_llinkid;
2436		mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV);
2437		args[0] = ni->ni_mlpid;
2438		args[1] = ni->ni_mllid;
2439		ieee80211_send_action(ni,
2440		    IEEE80211_ACTION_CAT_SELF_PROT,
2441		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2442		    args);
2443		/* NB: don't setup/clear any timeout */
2444		break;
2445	case IEEE80211_NODE_MESH_CONFIRMRCV:
2446		if (ni->ni_mlpid != meshpeer->peer_linkid ||
2447		    ni->ni_mllid != meshpeer->peer_llinkid) {
2448			args[0] = ni->ni_mlpid;
2449			args[1] = ni->ni_mllid;
2450			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2451			ieee80211_send_action(ni,
2452			    IEEE80211_ACTION_CAT_SELF_PROT,
2453			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2454			    args);
2455			mesh_linkchange(ni,
2456			    IEEE80211_NODE_MESH_HOLDING);
2457			mesh_peer_timeout_setup(ni);
2458			break;
2459		}
2460		mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED);
2461		ni->ni_mllid = meshpeer->peer_llinkid;
2462		args[0] = ni->ni_mlpid;
2463		args[1] = ni->ni_mllid;
2464		ieee80211_send_action(ni,
2465		    IEEE80211_ACTION_CAT_SELF_PROT,
2466		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2467		    args);
2468		mesh_peer_timeout_stop(ni);
2469		break;
2470	case IEEE80211_NODE_MESH_ESTABLISHED:
2471		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2472			args[0] = ni->ni_mllid;
2473			args[1] = ni->ni_mlpid;
2474			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2475			ieee80211_send_action(ni,
2476			    IEEE80211_ACTION_CAT_SELF_PROT,
2477			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2478			    args);
2479			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2480			mesh_peer_timeout_setup(ni);
2481			break;
2482		}
2483		args[0] = ni->ni_mlpid;
2484		args[1] = ni->ni_mllid;
2485		ieee80211_send_action(ni,
2486		    IEEE80211_ACTION_CAT_SELF_PROT,
2487		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2488		    args);
2489		break;
2490	case IEEE80211_NODE_MESH_HOLDING:
2491		args[0] = ni->ni_mlpid;
2492		args[1] = meshpeer->peer_llinkid;
2493		/* Standard not clear about what the reaason code should be */
2494		args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2495		ieee80211_send_action(ni,
2496		    IEEE80211_ACTION_CAT_SELF_PROT,
2497		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2498		    args);
2499		break;
2500	}
2501	return 0;
2502}
2503
2504static int
2505mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni,
2506	const struct ieee80211_frame *wh,
2507	const uint8_t *frm, const uint8_t *efrm)
2508{
2509	struct ieee80211vap *vap = ni->ni_vap;
2510	struct ieee80211_meshpeer_ie ie;
2511	const struct ieee80211_meshpeer_ie *meshpeer;
2512	uint16_t args[3];
2513
2514	/* +2+2+2+2 for action + code + capabilites + status code + AID */
2515	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie,
2516	    IEEE80211_ACTION_MESHPEERING_CONFIRM);
2517	if (meshpeer == NULL) {
2518		return 0;
2519	}
2520
2521	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2522	    "recv PEER CONFIRM, local id 0x%x, peer id 0x%x",
2523	    meshpeer->peer_llinkid, meshpeer->peer_linkid);
2524
2525	switch (ni->ni_mlstate) {
2526	case IEEE80211_NODE_MESH_OPENRCV:
2527		mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED);
2528		mesh_peer_timeout_stop(ni);
2529		break;
2530	case IEEE80211_NODE_MESH_OPENSNT:
2531		mesh_linkchange(ni, IEEE80211_NODE_MESH_CONFIRMRCV);
2532		mesh_peer_timeout_setup(ni);
2533		break;
2534	case IEEE80211_NODE_MESH_HOLDING:
2535		args[0] = ni->ni_mlpid;
2536		args[1] = meshpeer->peer_llinkid;
2537		/* Standard not clear about what the reaason code should be */
2538		args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2539		ieee80211_send_action(ni,
2540		    IEEE80211_ACTION_CAT_SELF_PROT,
2541		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2542		    args);
2543		break;
2544	case IEEE80211_NODE_MESH_CONFIRMRCV:
2545		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2546			args[0] = ni->ni_mlpid;
2547			args[1] = ni->ni_mllid;
2548			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2549			ieee80211_send_action(ni,
2550			    IEEE80211_ACTION_CAT_SELF_PROT,
2551			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2552			    args);
2553			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2554			mesh_peer_timeout_setup(ni);
2555		}
2556		break;
2557	default:
2558		IEEE80211_DISCARD(vap,
2559		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2560		    wh, NULL, "received confirm in invalid state %d",
2561		    ni->ni_mlstate);
2562		vap->iv_stats.is_rx_mgtdiscard++;
2563		break;
2564	}
2565	return 0;
2566}
2567
2568static int
2569mesh_recv_action_meshpeering_close(struct ieee80211_node *ni,
2570	const struct ieee80211_frame *wh,
2571	const uint8_t *frm, const uint8_t *efrm)
2572{
2573	struct ieee80211_meshpeer_ie ie;
2574	const struct ieee80211_meshpeer_ie *meshpeer;
2575	uint16_t args[3];
2576
2577	/* +2 for action + code */
2578	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2, efrm, &ie,
2579	    IEEE80211_ACTION_MESHPEERING_CLOSE);
2580	if (meshpeer == NULL) {
2581		return 0;
2582	}
2583
2584	/*
2585	 * XXX: check reason code, for example we could receive
2586	 * IEEE80211_REASON_MESH_MAX_PEERS then we should not attempt
2587	 * to peer again.
2588	 */
2589
2590	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2591	    ni, "%s", "recv PEER CLOSE");
2592
2593	switch (ni->ni_mlstate) {
2594	case IEEE80211_NODE_MESH_IDLE:
2595		/* ignore */
2596		break;
2597	case IEEE80211_NODE_MESH_OPENRCV:
2598	case IEEE80211_NODE_MESH_OPENSNT:
2599	case IEEE80211_NODE_MESH_CONFIRMRCV:
2600	case IEEE80211_NODE_MESH_ESTABLISHED:
2601		args[0] = ni->ni_mlpid;
2602		args[1] = ni->ni_mllid;
2603		args[2] = IEEE80211_REASON_MESH_CLOSE_RCVD;
2604		ieee80211_send_action(ni,
2605		    IEEE80211_ACTION_CAT_SELF_PROT,
2606		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2607		    args);
2608		mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2609		mesh_peer_timeout_setup(ni);
2610		break;
2611	case IEEE80211_NODE_MESH_HOLDING:
2612		mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE);
2613		mesh_peer_timeout_stop(ni);
2614		break;
2615	}
2616	return 0;
2617}
2618
2619/*
2620 * Link Metric handling.
2621 */
2622static int
2623mesh_recv_action_meshlmetric(struct ieee80211_node *ni,
2624	const struct ieee80211_frame *wh,
2625	const uint8_t *frm, const uint8_t *efrm)
2626{
2627	const struct ieee80211_meshlmetric_ie *ie =
2628	    (const struct ieee80211_meshlmetric_ie *)
2629	    (frm+2); /* action + code */
2630	struct ieee80211_meshlmetric_ie lm_rep;
2631
2632	if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
2633		lm_rep.lm_flags = 0;
2634		lm_rep.lm_metric = mesh_airtime_calc(ni);
2635		ieee80211_send_action(ni,
2636		    IEEE80211_ACTION_CAT_MESH,
2637		    IEEE80211_ACTION_MESH_LMETRIC,
2638		    &lm_rep);
2639	}
2640	/* XXX: else do nothing for now */
2641	return 0;
2642}
2643
2644/*
2645 * Parse meshgate action ie's for GANN frames.
2646 * Returns -1 if parsing fails, otherwise 0.
2647 */
2648static int
2649mesh_parse_meshgate_action(struct ieee80211_node *ni,
2650    const struct ieee80211_frame *wh,	/* XXX for VERIFY_LENGTH */
2651    struct ieee80211_meshgann_ie *ie, const uint8_t *frm, const uint8_t *efrm)
2652{
2653	struct ieee80211vap *vap = ni->ni_vap;
2654	const struct ieee80211_meshgann_ie *gannie;
2655
2656	while (efrm - frm > 1) {
2657		IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return -1);
2658		switch (*frm) {
2659		case IEEE80211_ELEMID_MESHGANN:
2660			gannie = (const struct ieee80211_meshgann_ie *) frm;
2661			memset(ie, 0, sizeof(*ie));
2662			ie->gann_ie = gannie->gann_ie;
2663			ie->gann_len = gannie->gann_len;
2664			ie->gann_flags = gannie->gann_flags;
2665			ie->gann_hopcount = gannie->gann_hopcount;
2666			ie->gann_ttl = gannie->gann_ttl;
2667			IEEE80211_ADDR_COPY(ie->gann_addr, gannie->gann_addr);
2668			ie->gann_seq = LE_READ_4(&gannie->gann_seq);
2669			ie->gann_interval = LE_READ_2(&gannie->gann_interval);
2670			break;
2671		}
2672		frm += frm[1] + 2;
2673	}
2674
2675	return 0;
2676}
2677
2678/*
2679 * Mesh Gate Announcement handling.
2680 */
2681static int
2682mesh_recv_action_meshgate(struct ieee80211_node *ni,
2683	const struct ieee80211_frame *wh,
2684	const uint8_t *frm, const uint8_t *efrm)
2685{
2686	struct ieee80211vap *vap = ni->ni_vap;
2687	struct ieee80211_mesh_state *ms = vap->iv_mesh;
2688	struct ieee80211_mesh_gate_route *gr, *next;
2689	struct ieee80211_mesh_route *rt_gate;
2690	struct ieee80211_meshgann_ie pgann;
2691	struct ieee80211_meshgann_ie ie;
2692	int found = 0;
2693
2694	/* +2 for action + code */
2695	if (mesh_parse_meshgate_action(ni, wh, &ie, frm+2, efrm) != 0) {
2696		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
2697		    ni->ni_macaddr, NULL, "%s",
2698		    "GANN parsing failed");
2699		vap->iv_stats.is_rx_mgtdiscard++;
2700		return (0);
2701	}
2702
2703	if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ie.gann_addr))
2704		return 0;
2705
2706	IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ni->ni_macaddr,
2707	    "received GANN, meshgate: %6D (seq %u)", ie.gann_addr, ":",
2708	    ie.gann_seq);
2709
2710	if (ms == NULL)
2711		return (0);
2712	MESH_RT_LOCK(ms);
2713	TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, next) {
2714		if (!IEEE80211_ADDR_EQ(gr->gr_addr, ie.gann_addr))
2715			continue;
2716		if (ie.gann_seq <= gr->gr_lastseq) {
2717			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
2718			    ni->ni_macaddr, NULL,
2719			    "GANN old seqno %u <= %u",
2720			    ie.gann_seq, gr->gr_lastseq);
2721			MESH_RT_UNLOCK(ms);
2722			return (0);
2723		}
2724		/* corresponding mesh gate found & GANN accepted */
2725		found = 1;
2726		break;
2727
2728	}
2729	if (found == 0) {
2730		/* this GANN is from a new mesh Gate add it to known table. */
2731		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
2732		    "stored new GANN information, seq %u.", ie.gann_seq);
2733		gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
2734		    M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
2735		IEEE80211_ADDR_COPY(gr->gr_addr, ie.gann_addr);
2736		TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
2737	}
2738	gr->gr_lastseq = ie.gann_seq;
2739
2740	/* check if we have a path to this gate */
2741	rt_gate = mesh_rt_find_locked(ms, gr->gr_addr);
2742	if (rt_gate != NULL &&
2743	    rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) {
2744		gr->gr_route = rt_gate;
2745		rt_gate->rt_flags |= IEEE80211_MESHRT_FLAGS_GATE;
2746	}
2747
2748	MESH_RT_UNLOCK(ms);
2749
2750	/* popagate only if decremented ttl >= 1 && forwarding is enabled */
2751	if ((ie.gann_ttl - 1) < 1 && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
2752		return 0;
2753		pgann.gann_flags = ie.gann_flags; /* Reserved */
2754	pgann.gann_hopcount = ie.gann_hopcount + 1;
2755	pgann.gann_ttl = ie.gann_ttl - 1;
2756	IEEE80211_ADDR_COPY(pgann.gann_addr, ie.gann_addr);
2757	pgann.gann_seq = ie.gann_seq;
2758	pgann.gann_interval = ie.gann_interval;
2759
2760	IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
2761	    "%s", "propagate GANN");
2762
2763	ieee80211_send_action(vap->iv_bss, IEEE80211_ACTION_CAT_MESH,
2764	    IEEE80211_ACTION_MESH_GANN, &pgann);
2765
2766	return 0;
2767}
2768
2769static int
2770mesh_send_action(struct ieee80211_node *ni,
2771    const uint8_t sa[IEEE80211_ADDR_LEN],
2772    const uint8_t da[IEEE80211_ADDR_LEN],
2773    struct mbuf *m)
2774{
2775	struct ieee80211vap *vap = ni->ni_vap;
2776	struct ieee80211com *ic = ni->ni_ic;
2777	struct ieee80211_bpf_params params;
2778	struct ieee80211_frame *wh;
2779	int ret;
2780
2781	KASSERT(ni != NULL, ("null node"));
2782
2783	if (vap->iv_state == IEEE80211_S_CAC) {
2784		IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
2785		    "block %s frame in CAC state", "Mesh action");
2786		vap->iv_stats.is_tx_badstate++;
2787		ieee80211_free_node(ni);
2788		m_freem(m);
2789		return EIO;		/* XXX */
2790	}
2791
2792	M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
2793	if (m == NULL) {
2794		ieee80211_free_node(ni);
2795		return ENOMEM;
2796	}
2797
2798	IEEE80211_TX_LOCK(ic);
2799	wh = mtod(m, struct ieee80211_frame *);
2800	ieee80211_send_setup(ni, m,
2801	     IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
2802	     IEEE80211_NONQOS_TID, sa, da, sa);
2803	m->m_flags |= M_ENCAP;		/* mark encapsulated */
2804
2805	memset(&params, 0, sizeof(params));
2806	params.ibp_pri = WME_AC_VO;
2807	params.ibp_rate0 = ni->ni_txparms->mgmtrate;
2808	if (IEEE80211_IS_MULTICAST(da))
2809		params.ibp_try0 = 1;
2810	else
2811		params.ibp_try0 = ni->ni_txparms->maxretry;
2812	params.ibp_power = ni->ni_txpower;
2813
2814	IEEE80211_NODE_STAT(ni, tx_mgmt);
2815
2816	ret = ieee80211_raw_output(vap, ni, m, &params);
2817	IEEE80211_TX_UNLOCK(ic);
2818	return (ret);
2819}
2820
2821#define	ADDSHORT(frm, v) do {			\
2822	frm[0] = (v) & 0xff;			\
2823	frm[1] = (v) >> 8;			\
2824	frm += 2;				\
2825} while (0)
2826#define	ADDWORD(frm, v) do {			\
2827	frm[0] = (v) & 0xff;			\
2828	frm[1] = ((v) >> 8) & 0xff;		\
2829	frm[2] = ((v) >> 16) & 0xff;		\
2830	frm[3] = ((v) >> 24) & 0xff;		\
2831	frm += 4;				\
2832} while (0)
2833
2834static int
2835mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
2836	int category, int action, void *args0)
2837{
2838	struct ieee80211vap *vap = ni->ni_vap;
2839	struct ieee80211com *ic = ni->ni_ic;
2840	uint16_t *args = args0;
2841	const struct ieee80211_rateset *rs;
2842	struct mbuf *m;
2843	uint8_t *frm;
2844
2845	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2846	    "send PEER OPEN action: localid 0x%x", args[0]);
2847
2848	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2849	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2850	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2851	ieee80211_ref_node(ni);
2852
2853	m = ieee80211_getmgtframe(&frm,
2854	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2855	    sizeof(uint16_t)	/* action+category */
2856	    + sizeof(uint16_t)	/* capabilites */
2857	    + 2 + IEEE80211_RATE_SIZE
2858	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2859	    + 2 + IEEE80211_MESHID_LEN
2860	    + sizeof(struct ieee80211_meshconf_ie)
2861	    + sizeof(struct ieee80211_meshpeer_ie)
2862	);
2863	if (m != NULL) {
2864		/*
2865		 * mesh peer open action frame format:
2866		 *   [1] category
2867		 *   [1] action
2868		 *   [2] capabilities
2869		 *   [tlv] rates
2870		 *   [tlv] xrates
2871		 *   [tlv] mesh id
2872		 *   [tlv] mesh conf
2873		 *   [tlv] mesh peer link mgmt
2874		 */
2875		*frm++ = category;
2876		*frm++ = action;
2877		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
2878		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
2879		frm = ieee80211_add_rates(frm, rs);
2880		frm = ieee80211_add_xrates(frm, rs);
2881		frm = ieee80211_add_meshid(frm, vap);
2882		frm = ieee80211_add_meshconf(frm, vap);
2883		frm = ieee80211_add_meshpeer(frm, IEEE80211_ACTION_MESHPEERING_OPEN,
2884		    args[0], 0, 0);
2885		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2886		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
2887	} else {
2888		vap->iv_stats.is_tx_nobuf++;
2889		ieee80211_free_node(ni);
2890		return ENOMEM;
2891	}
2892}
2893
2894static int
2895mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
2896	int category, int action, void *args0)
2897{
2898	struct ieee80211vap *vap = ni->ni_vap;
2899	struct ieee80211com *ic = ni->ni_ic;
2900	uint16_t *args = args0;
2901	const struct ieee80211_rateset *rs;
2902	struct mbuf *m;
2903	uint8_t *frm;
2904
2905	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2906	    "send PEER CONFIRM action: localid 0x%x, peerid 0x%x",
2907	    args[0], args[1]);
2908
2909	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2910	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2911	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2912	ieee80211_ref_node(ni);
2913
2914	m = ieee80211_getmgtframe(&frm,
2915	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2916	    sizeof(uint16_t)	/* action+category */
2917	    + sizeof(uint16_t)	/* capabilites */
2918	    + sizeof(uint16_t)	/* status code */
2919	    + sizeof(uint16_t)	/* AID */
2920	    + 2 + IEEE80211_RATE_SIZE
2921	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2922	    + 2 + IEEE80211_MESHID_LEN
2923	    + sizeof(struct ieee80211_meshconf_ie)
2924	    + sizeof(struct ieee80211_meshpeer_ie)
2925	);
2926	if (m != NULL) {
2927		/*
2928		 * mesh peer confirm action frame format:
2929		 *   [1] category
2930		 *   [1] action
2931		 *   [2] capabilities
2932		 *   [2] status code
2933		 *   [2] association id (peer ID)
2934		 *   [tlv] rates
2935		 *   [tlv] xrates
2936		 *   [tlv] mesh id
2937		 *   [tlv] mesh conf
2938		 *   [tlv] mesh peer link mgmt
2939		 */
2940		*frm++ = category;
2941		*frm++ = action;
2942		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
2943		ADDSHORT(frm, 0);		/* status code */
2944		ADDSHORT(frm, args[1]);		/* AID */
2945		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
2946		frm = ieee80211_add_rates(frm, rs);
2947		frm = ieee80211_add_xrates(frm, rs);
2948		frm = ieee80211_add_meshid(frm, vap);
2949		frm = ieee80211_add_meshconf(frm, vap);
2950		frm = ieee80211_add_meshpeer(frm,
2951		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2952		    args[0], args[1], 0);
2953		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2954		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
2955	} else {
2956		vap->iv_stats.is_tx_nobuf++;
2957		ieee80211_free_node(ni);
2958		return ENOMEM;
2959	}
2960}
2961
2962static int
2963mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
2964	int category, int action, void *args0)
2965{
2966	struct ieee80211vap *vap = ni->ni_vap;
2967	struct ieee80211com *ic = ni->ni_ic;
2968	uint16_t *args = args0;
2969	struct mbuf *m;
2970	uint8_t *frm;
2971
2972	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2973	    "send PEER CLOSE action: localid 0x%x, peerid 0x%x reason %d",
2974	    args[0], args[1], args[2]);
2975
2976	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2977	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2978	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2979	ieee80211_ref_node(ni);
2980
2981	m = ieee80211_getmgtframe(&frm,
2982	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2983	    sizeof(uint16_t)	/* action+category */
2984	    + sizeof(uint16_t)	/* reason code */
2985	    + 2 + IEEE80211_MESHID_LEN
2986	    + sizeof(struct ieee80211_meshpeer_ie)
2987	);
2988	if (m != NULL) {
2989		/*
2990		 * mesh peer close action frame format:
2991		 *   [1] category
2992		 *   [1] action
2993		 *   [tlv] mesh id
2994		 *   [tlv] mesh peer link mgmt
2995		 */
2996		*frm++ = category;
2997		*frm++ = action;
2998		frm = ieee80211_add_meshid(frm, vap);
2999		frm = ieee80211_add_meshpeer(frm,
3000		    IEEE80211_ACTION_MESHPEERING_CLOSE,
3001		    args[0], args[1], args[2]);
3002		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
3003		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
3004	} else {
3005		vap->iv_stats.is_tx_nobuf++;
3006		ieee80211_free_node(ni);
3007		return ENOMEM;
3008	}
3009}
3010
3011static int
3012mesh_send_action_meshlmetric(struct ieee80211_node *ni,
3013	int category, int action, void *arg0)
3014{
3015	struct ieee80211vap *vap = ni->ni_vap;
3016	struct ieee80211com *ic = ni->ni_ic;
3017	struct ieee80211_meshlmetric_ie *ie = arg0;
3018	struct mbuf *m;
3019	uint8_t *frm;
3020
3021	if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
3022		IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
3023		    ni, "%s", "send LINK METRIC REQUEST action");
3024	} else {
3025		IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
3026		    ni, "send LINK METRIC REPLY action: metric 0x%x",
3027		    ie->lm_metric);
3028	}
3029	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
3030	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
3031	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
3032	ieee80211_ref_node(ni);
3033
3034	m = ieee80211_getmgtframe(&frm,
3035	    ic->ic_headroom + sizeof(struct ieee80211_frame),
3036	    sizeof(uint16_t) +	/* action+category */
3037	    sizeof(struct ieee80211_meshlmetric_ie)
3038	);
3039	if (m != NULL) {
3040		/*
3041		 * mesh link metric
3042		 *   [1] category
3043		 *   [1] action
3044		 *   [tlv] mesh link metric
3045		 */
3046		*frm++ = category;
3047		*frm++ = action;
3048		frm = ieee80211_add_meshlmetric(frm,
3049		    ie->lm_flags, ie->lm_metric);
3050		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
3051		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
3052	} else {
3053		vap->iv_stats.is_tx_nobuf++;
3054		ieee80211_free_node(ni);
3055		return ENOMEM;
3056	}
3057}
3058
3059static int
3060mesh_send_action_meshgate(struct ieee80211_node *ni,
3061	int category, int action, void *arg0)
3062{
3063	struct ieee80211vap *vap = ni->ni_vap;
3064	struct ieee80211com *ic = ni->ni_ic;
3065	struct ieee80211_meshgann_ie *ie = arg0;
3066	struct mbuf *m;
3067	uint8_t *frm;
3068
3069	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
3070	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
3071	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
3072	ieee80211_ref_node(ni);
3073
3074	m = ieee80211_getmgtframe(&frm,
3075	    ic->ic_headroom + sizeof(struct ieee80211_frame),
3076	    sizeof(uint16_t) +	/* action+category */
3077	    IEEE80211_MESHGANN_BASE_SZ
3078	);
3079	if (m != NULL) {
3080		/*
3081		 * mesh link metric
3082		 *   [1] category
3083		 *   [1] action
3084		 *   [tlv] mesh gate annoucement
3085		 */
3086		*frm++ = category;
3087		*frm++ = action;
3088		frm = ieee80211_add_meshgate(frm, ie);
3089		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
3090		return mesh_send_action(ni, vap->iv_myaddr, broadcastaddr, m);
3091	} else {
3092		vap->iv_stats.is_tx_nobuf++;
3093		ieee80211_free_node(ni);
3094		return ENOMEM;
3095	}
3096}
3097
3098static void
3099mesh_peer_timeout_setup(struct ieee80211_node *ni)
3100{
3101	switch (ni->ni_mlstate) {
3102	case IEEE80211_NODE_MESH_HOLDING:
3103		ni->ni_mltval = ieee80211_mesh_holdingtimeout;
3104		break;
3105	case IEEE80211_NODE_MESH_CONFIRMRCV:
3106		ni->ni_mltval = ieee80211_mesh_confirmtimeout;
3107		break;
3108	case IEEE80211_NODE_MESH_IDLE:
3109		ni->ni_mltval = 0;
3110		break;
3111	default:
3112		ni->ni_mltval = ieee80211_mesh_retrytimeout;
3113		break;
3114	}
3115	if (ni->ni_mltval)
3116		callout_reset(&ni->ni_mltimer, ni->ni_mltval,
3117		    mesh_peer_timeout_cb, ni);
3118}
3119
3120/*
3121 * Same as above but backoffs timer statisically 50%.
3122 */
3123static void
3124mesh_peer_timeout_backoff(struct ieee80211_node *ni)
3125{
3126	uint32_t r;
3127
3128	r = arc4random();
3129	ni->ni_mltval += r % ni->ni_mltval;
3130	callout_reset(&ni->ni_mltimer, ni->ni_mltval, mesh_peer_timeout_cb,
3131	    ni);
3132}
3133
3134static __inline void
3135mesh_peer_timeout_stop(struct ieee80211_node *ni)
3136{
3137	callout_drain(&ni->ni_mltimer);
3138}
3139
3140static void
3141mesh_peer_backoff_cb(void *arg)
3142{
3143	struct ieee80211_node *ni = (struct ieee80211_node *)arg;
3144
3145	/* After backoff timeout, try to peer automatically again. */
3146	ni->ni_mlhcnt = 0;
3147}
3148
3149/*
3150 * Mesh Peer Link Management FSM timeout handling.
3151 */
3152static void
3153mesh_peer_timeout_cb(void *arg)
3154{
3155	struct ieee80211_node *ni = (struct ieee80211_node *)arg;
3156	uint16_t args[3];
3157
3158	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_MESH,
3159	    ni, "mesh link timeout, state %d, retry counter %d",
3160	    ni->ni_mlstate, ni->ni_mlrcnt);
3161
3162	switch (ni->ni_mlstate) {
3163	case IEEE80211_NODE_MESH_IDLE:
3164	case IEEE80211_NODE_MESH_ESTABLISHED:
3165		break;
3166	case IEEE80211_NODE_MESH_OPENSNT:
3167	case IEEE80211_NODE_MESH_OPENRCV:
3168		if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) {
3169			args[0] = ni->ni_mlpid;
3170			args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
3171			ieee80211_send_action(ni,
3172			    IEEE80211_ACTION_CAT_SELF_PROT,
3173			    IEEE80211_ACTION_MESHPEERING_CLOSE, args);
3174			ni->ni_mlrcnt = 0;
3175			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
3176			mesh_peer_timeout_setup(ni);
3177		} else {
3178			args[0] = ni->ni_mlpid;
3179			ieee80211_send_action(ni,
3180			    IEEE80211_ACTION_CAT_SELF_PROT,
3181			    IEEE80211_ACTION_MESHPEERING_OPEN, args);
3182			ni->ni_mlrcnt++;
3183			mesh_peer_timeout_backoff(ni);
3184		}
3185		break;
3186	case IEEE80211_NODE_MESH_CONFIRMRCV:
3187		args[0] = ni->ni_mlpid;
3188		args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT;
3189		ieee80211_send_action(ni,
3190		    IEEE80211_ACTION_CAT_SELF_PROT,
3191		    IEEE80211_ACTION_MESHPEERING_CLOSE, args);
3192		mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
3193		mesh_peer_timeout_setup(ni);
3194		break;
3195	case IEEE80211_NODE_MESH_HOLDING:
3196		ni->ni_mlhcnt++;
3197		if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding)
3198			callout_reset(&ni->ni_mlhtimer,
3199			    ieee80211_mesh_backofftimeout,
3200			    mesh_peer_backoff_cb, ni);
3201		mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE);
3202		break;
3203	}
3204}
3205
3206static int
3207mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie)
3208{
3209	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3210
3211	if (ie == NULL || ie[1] != ms->ms_idlen)
3212		return 1;
3213	return memcmp(ms->ms_id, ie + 2, ms->ms_idlen);
3214}
3215
3216/*
3217 * Check if we are using the same algorithms for this mesh.
3218 */
3219static int
3220mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie)
3221{
3222	const struct ieee80211_meshconf_ie *meshconf =
3223	    (const struct ieee80211_meshconf_ie *) ie;
3224	const struct ieee80211_mesh_state *ms = vap->iv_mesh;
3225
3226	if (meshconf == NULL)
3227		return 1;
3228	if (meshconf->conf_pselid != ms->ms_ppath->mpp_ie) {
3229		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3230		    "unknown path selection algorithm: 0x%x\n",
3231		    meshconf->conf_pselid);
3232		return 1;
3233	}
3234	if (meshconf->conf_pmetid != ms->ms_pmetric->mpm_ie) {
3235		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3236		    "unknown path metric algorithm: 0x%x\n",
3237		    meshconf->conf_pmetid);
3238		return 1;
3239	}
3240	if (meshconf->conf_ccid != 0) {
3241		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3242		    "unknown congestion control algorithm: 0x%x\n",
3243		    meshconf->conf_ccid);
3244		return 1;
3245	}
3246	if (meshconf->conf_syncid != IEEE80211_MESHCONF_SYNC_NEIGHOFF) {
3247		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3248		    "unknown sync algorithm: 0x%x\n",
3249		    meshconf->conf_syncid);
3250		return 1;
3251	}
3252	if (meshconf->conf_authid != 0) {
3253		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3254		    "unknown auth auth algorithm: 0x%x\n",
3255		    meshconf->conf_pselid);
3256		return 1;
3257	}
3258	/* Not accepting peers */
3259	if (!(meshconf->conf_cap & IEEE80211_MESHCONF_CAP_AP)) {
3260		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3261		    "not accepting peers: 0x%x\n", meshconf->conf_cap);
3262		return 1;
3263	}
3264	return 0;
3265}
3266
3267static int
3268mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
3269    const uint8_t *ie)
3270{
3271	const struct ieee80211_meshpeer_ie *meshpeer =
3272	    (const struct ieee80211_meshpeer_ie *) ie;
3273
3274	if (meshpeer == NULL ||
3275	    meshpeer->peer_len < IEEE80211_MPM_BASE_SZ ||
3276	    meshpeer->peer_len > IEEE80211_MPM_MAX_SZ)
3277		return 1;
3278	if (meshpeer->peer_proto != IEEE80211_MPPID_MPM) {
3279		IEEE80211_DPRINTF(vap,
3280		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
3281		    "Only MPM protocol is supported (proto: 0x%02X)",
3282		    meshpeer->peer_proto);
3283		return 1;
3284	}
3285	switch (subtype) {
3286	case IEEE80211_ACTION_MESHPEERING_OPEN:
3287		if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ)
3288			return 1;
3289		break;
3290	case IEEE80211_ACTION_MESHPEERING_CONFIRM:
3291		if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2)
3292			return 1;
3293		break;
3294	case IEEE80211_ACTION_MESHPEERING_CLOSE:
3295		if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2)
3296			return 1;
3297		if (meshpeer->peer_len == (IEEE80211_MPM_BASE_SZ + 2) &&
3298		    meshpeer->peer_linkid != 0)
3299			return 1;
3300		if (meshpeer->peer_rcode == 0)
3301			return 1;
3302		break;
3303	}
3304	return 0;
3305}
3306
3307/*
3308 * Add a Mesh ID IE to a frame.
3309 */
3310uint8_t *
3311ieee80211_add_meshid(uint8_t *frm, struct ieee80211vap *vap)
3312{
3313	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3314
3315	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a mbss vap"));
3316
3317	*frm++ = IEEE80211_ELEMID_MESHID;
3318	*frm++ = ms->ms_idlen;
3319	memcpy(frm, ms->ms_id, ms->ms_idlen);
3320	return frm + ms->ms_idlen;
3321}
3322
3323/*
3324 * Add a Mesh Configuration IE to a frame.
3325 * For now just use HWMP routing, Airtime link metric, Null Congestion
3326 * Signaling, Null Sync Protocol and Null Authentication.
3327 */
3328uint8_t *
3329ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap)
3330{
3331	const struct ieee80211_mesh_state *ms = vap->iv_mesh;
3332	uint16_t caps;
3333
3334	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
3335
3336	*frm++ = IEEE80211_ELEMID_MESHCONF;
3337	*frm++ = IEEE80211_MESH_CONF_SZ;
3338	*frm++ = ms->ms_ppath->mpp_ie;		/* path selection */
3339	*frm++ = ms->ms_pmetric->mpm_ie;	/* link metric */
3340	*frm++ = IEEE80211_MESHCONF_CC_DISABLED;
3341	*frm++ = IEEE80211_MESHCONF_SYNC_NEIGHOFF;
3342	*frm++ = IEEE80211_MESHCONF_AUTH_DISABLED;
3343	/* NB: set the number of neighbors before the rest */
3344	*frm = (ms->ms_neighbors > IEEE80211_MESH_MAX_NEIGHBORS ?
3345	    IEEE80211_MESH_MAX_NEIGHBORS : ms->ms_neighbors) << 1;
3346	if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE)
3347		*frm |= IEEE80211_MESHCONF_FORM_GATE;
3348	frm += 1;
3349	caps = 0;
3350	if (ms->ms_flags & IEEE80211_MESHFLAGS_AP)
3351		caps |= IEEE80211_MESHCONF_CAP_AP;
3352	if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)
3353		caps |= IEEE80211_MESHCONF_CAP_FWRD;
3354	*frm++ = caps;
3355	return frm;
3356}
3357
3358/*
3359 * Add a Mesh Peer Management IE to a frame.
3360 */
3361uint8_t *
3362ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
3363    uint16_t peerid, uint16_t reason)
3364{
3365
3366	KASSERT(localid != 0, ("localid == 0"));
3367
3368	*frm++ = IEEE80211_ELEMID_MESHPEER;
3369	switch (subtype) {
3370	case IEEE80211_ACTION_MESHPEERING_OPEN:
3371		*frm++ = IEEE80211_MPM_BASE_SZ;		/* length */
3372		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3373		ADDSHORT(frm, localid);			/* local ID */
3374		break;
3375	case IEEE80211_ACTION_MESHPEERING_CONFIRM:
3376		KASSERT(peerid != 0, ("sending peer confirm without peer id"));
3377		*frm++ = IEEE80211_MPM_BASE_SZ + 2;	/* length */
3378		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3379		ADDSHORT(frm, localid);			/* local ID */
3380		ADDSHORT(frm, peerid);			/* peer ID */
3381		break;
3382	case IEEE80211_ACTION_MESHPEERING_CLOSE:
3383		if (peerid)
3384			*frm++ = IEEE80211_MPM_MAX_SZ;	/* length */
3385		else
3386			*frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
3387		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3388		ADDSHORT(frm, localid);	/* local ID */
3389		if (peerid)
3390			ADDSHORT(frm, peerid);	/* peer ID */
3391		ADDSHORT(frm, reason);
3392		break;
3393	}
3394	return frm;
3395}
3396
3397/*
3398 * Compute an Airtime Link Metric for the link with this node.
3399 *
3400 * Based on Draft 3.0 spec (11B.10, p.149).
3401 */
3402/*
3403 * Max 802.11s overhead.
3404 */
3405#define IEEE80211_MESH_MAXOVERHEAD \
3406	(sizeof(struct ieee80211_qosframe_addr4) \
3407	 + sizeof(struct ieee80211_meshcntl_ae10) \
3408	+ sizeof(struct llc) \
3409	+ IEEE80211_ADDR_LEN \
3410	+ IEEE80211_WEP_IVLEN \
3411	+ IEEE80211_WEP_KIDLEN \
3412	+ IEEE80211_WEP_CRCLEN \
3413	+ IEEE80211_WEP_MICLEN \
3414	+ IEEE80211_CRC_LEN)
3415uint32_t
3416mesh_airtime_calc(struct ieee80211_node *ni)
3417{
3418#define M_BITS 8
3419#define S_FACTOR (2 * M_BITS)
3420	struct ieee80211com *ic = ni->ni_ic;
3421	struct ifnet *ifp = ni->ni_vap->iv_ifp;
3422	const static int nbits = 8192 << M_BITS;
3423	uint32_t overhead, rate, errrate;
3424	uint64_t res;
3425
3426	/* Time to transmit a frame */
3427	rate = ni->ni_txrate;
3428	overhead = ieee80211_compute_duration(ic->ic_rt,
3429	    ifp->if_mtu + IEEE80211_MESH_MAXOVERHEAD, rate, 0) << M_BITS;
3430	/* Error rate in percentage */
3431	/* XXX assuming small failures are ok */
3432	errrate = (((ifp->if_oerrors +
3433	    ifp->if_ierrors) / 100) << M_BITS) / 100;
3434	res = (overhead + (nbits / rate)) *
3435	    ((1 << S_FACTOR) / ((1 << M_BITS) - errrate));
3436
3437	return (uint32_t)(res >> S_FACTOR);
3438#undef M_BITS
3439#undef S_FACTOR
3440}
3441
3442/*
3443 * Add a Mesh Link Metric report IE to a frame.
3444 */
3445uint8_t *
3446ieee80211_add_meshlmetric(uint8_t *frm, uint8_t flags, uint32_t metric)
3447{
3448	*frm++ = IEEE80211_ELEMID_MESHLINK;
3449	*frm++ = 5;
3450	*frm++ = flags;
3451	ADDWORD(frm, metric);
3452	return frm;
3453}
3454
3455/*
3456 * Add a Mesh Gate Announcement IE to a frame.
3457 */
3458uint8_t *
3459ieee80211_add_meshgate(uint8_t *frm, struct ieee80211_meshgann_ie *ie)
3460{
3461	*frm++ = IEEE80211_ELEMID_MESHGANN; /* ie */
3462	*frm++ = IEEE80211_MESHGANN_BASE_SZ; /* len */
3463	*frm++ = ie->gann_flags;
3464	*frm++ = ie->gann_hopcount;
3465	*frm++ = ie->gann_ttl;
3466	IEEE80211_ADDR_COPY(frm, ie->gann_addr);
3467	frm += 6;
3468	ADDWORD(frm, ie->gann_seq);
3469	ADDSHORT(frm, ie->gann_interval);
3470	return frm;
3471}
3472#undef ADDSHORT
3473#undef ADDWORD
3474
3475/*
3476 * Initialize any mesh-specific node state.
3477 */
3478void
3479ieee80211_mesh_node_init(struct ieee80211vap *vap, struct ieee80211_node *ni)
3480{
3481	ni->ni_flags |= IEEE80211_NODE_QOS;
3482	callout_init(&ni->ni_mltimer, CALLOUT_MPSAFE);
3483	callout_init(&ni->ni_mlhtimer, CALLOUT_MPSAFE);
3484}
3485
3486/*
3487 * Cleanup any mesh-specific node state.
3488 */
3489void
3490ieee80211_mesh_node_cleanup(struct ieee80211_node *ni)
3491{
3492	struct ieee80211vap *vap = ni->ni_vap;
3493	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3494
3495	callout_drain(&ni->ni_mltimer);
3496	callout_drain(&ni->ni_mlhtimer);
3497	/* NB: short-circuit callbacks after mesh_vdetach */
3498	if (vap->iv_mesh != NULL)
3499		ms->ms_ppath->mpp_peerdown(ni);
3500}
3501
3502void
3503ieee80211_parse_meshid(struct ieee80211_node *ni, const uint8_t *ie)
3504{
3505	ni->ni_meshidlen = ie[1];
3506	memcpy(ni->ni_meshid, ie + 2, ie[1]);
3507}
3508
3509/*
3510 * Setup mesh-specific node state on neighbor discovery.
3511 */
3512void
3513ieee80211_mesh_init_neighbor(struct ieee80211_node *ni,
3514	const struct ieee80211_frame *wh,
3515	const struct ieee80211_scanparams *sp)
3516{
3517	ieee80211_parse_meshid(ni, sp->meshid);
3518}
3519
3520void
3521ieee80211_mesh_update_beacon(struct ieee80211vap *vap,
3522	struct ieee80211_beacon_offsets *bo)
3523{
3524	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
3525
3526	if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) {
3527		(void)ieee80211_add_meshconf(bo->bo_meshconf, vap);
3528		clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF);
3529	}
3530}
3531
3532static int
3533mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
3534{
3535	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3536	uint8_t tmpmeshid[IEEE80211_NWID_LEN];
3537	struct ieee80211_mesh_route *rt;
3538	struct ieee80211req_mesh_route *imr;
3539	size_t len, off;
3540	uint8_t *p;
3541	int error;
3542
3543	if (vap->iv_opmode != IEEE80211_M_MBSS)
3544		return ENOSYS;
3545
3546	error = 0;
3547	switch (ireq->i_type) {
3548	case IEEE80211_IOC_MESH_ID:
3549		ireq->i_len = ms->ms_idlen;
3550		memcpy(tmpmeshid, ms->ms_id, ireq->i_len);
3551		error = copyout(tmpmeshid, ireq->i_data, ireq->i_len);
3552		break;
3553	case IEEE80211_IOC_MESH_AP:
3554		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_AP) != 0;
3555		break;
3556	case IEEE80211_IOC_MESH_FWRD:
3557		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) != 0;
3558		break;
3559	case IEEE80211_IOC_MESH_GATE:
3560		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) != 0;
3561		break;
3562	case IEEE80211_IOC_MESH_TTL:
3563		ireq->i_val = ms->ms_ttl;
3564		break;
3565	case IEEE80211_IOC_MESH_RTCMD:
3566		switch (ireq->i_val) {
3567		case IEEE80211_MESH_RTCMD_LIST:
3568			len = 0;
3569			MESH_RT_LOCK(ms);
3570			TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
3571				len += sizeof(*imr);
3572			}
3573			MESH_RT_UNLOCK(ms);
3574			if (len > ireq->i_len || ireq->i_len < sizeof(*imr)) {
3575				ireq->i_len = len;
3576				return ENOMEM;
3577			}
3578			ireq->i_len = len;
3579			/* XXX M_WAIT? */
3580			p = malloc(len, M_TEMP, M_NOWAIT | M_ZERO);
3581			if (p == NULL)
3582				return ENOMEM;
3583			off = 0;
3584			MESH_RT_LOCK(ms);
3585			TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
3586				if (off >= len)
3587					break;
3588				imr = (struct ieee80211req_mesh_route *)
3589				    (p + off);
3590				IEEE80211_ADDR_COPY(imr->imr_dest,
3591				    rt->rt_dest);
3592				IEEE80211_ADDR_COPY(imr->imr_nexthop,
3593				    rt->rt_nexthop);
3594				imr->imr_metric = rt->rt_metric;
3595				imr->imr_nhops = rt->rt_nhops;
3596				imr->imr_lifetime =
3597				    ieee80211_mesh_rt_update(rt, 0);
3598				imr->imr_lastmseq = rt->rt_lastmseq;
3599				imr->imr_flags = rt->rt_flags; /* last */
3600				off += sizeof(*imr);
3601			}
3602			MESH_RT_UNLOCK(ms);
3603			error = copyout(p, (uint8_t *)ireq->i_data,
3604			    ireq->i_len);
3605			free(p, M_TEMP);
3606			break;
3607		case IEEE80211_MESH_RTCMD_FLUSH:
3608		case IEEE80211_MESH_RTCMD_ADD:
3609		case IEEE80211_MESH_RTCMD_DELETE:
3610			return EINVAL;
3611		default:
3612			return ENOSYS;
3613		}
3614		break;
3615	case IEEE80211_IOC_MESH_PR_METRIC:
3616		len = strlen(ms->ms_pmetric->mpm_descr);
3617		if (ireq->i_len < len)
3618			return EINVAL;
3619		ireq->i_len = len;
3620		error = copyout(ms->ms_pmetric->mpm_descr,
3621		    (uint8_t *)ireq->i_data, len);
3622		break;
3623	case IEEE80211_IOC_MESH_PR_PATH:
3624		len = strlen(ms->ms_ppath->mpp_descr);
3625		if (ireq->i_len < len)
3626			return EINVAL;
3627		ireq->i_len = len;
3628		error = copyout(ms->ms_ppath->mpp_descr,
3629		    (uint8_t *)ireq->i_data, len);
3630		break;
3631	default:
3632		return ENOSYS;
3633	}
3634
3635	return error;
3636}
3637IEEE80211_IOCTL_GET(mesh, mesh_ioctl_get80211);
3638
3639static int
3640mesh_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
3641{
3642	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3643	uint8_t tmpmeshid[IEEE80211_NWID_LEN];
3644	uint8_t tmpaddr[IEEE80211_ADDR_LEN];
3645	char tmpproto[IEEE80211_MESH_PROTO_DSZ];
3646	int error;
3647
3648	if (vap->iv_opmode != IEEE80211_M_MBSS)
3649		return ENOSYS;
3650
3651	error = 0;
3652	switch (ireq->i_type) {
3653	case IEEE80211_IOC_MESH_ID:
3654		if (ireq->i_val != 0 || ireq->i_len > IEEE80211_MESHID_LEN)
3655			return EINVAL;
3656		error = copyin(ireq->i_data, tmpmeshid, ireq->i_len);
3657		if (error != 0)
3658			break;
3659		memset(ms->ms_id, 0, IEEE80211_NWID_LEN);
3660		ms->ms_idlen = ireq->i_len;
3661		memcpy(ms->ms_id, tmpmeshid, ireq->i_len);
3662		error = ENETRESET;
3663		break;
3664	case IEEE80211_IOC_MESH_AP:
3665		if (ireq->i_val)
3666			ms->ms_flags |= IEEE80211_MESHFLAGS_AP;
3667		else
3668			ms->ms_flags &= ~IEEE80211_MESHFLAGS_AP;
3669		error = ENETRESET;
3670		break;
3671	case IEEE80211_IOC_MESH_FWRD:
3672		if (ireq->i_val)
3673			ms->ms_flags |= IEEE80211_MESHFLAGS_FWD;
3674		else
3675			ms->ms_flags &= ~IEEE80211_MESHFLAGS_FWD;
3676		mesh_gatemode_setup(vap);
3677		break;
3678	case IEEE80211_IOC_MESH_GATE:
3679		if (ireq->i_val)
3680			ms->ms_flags |= IEEE80211_MESHFLAGS_GATE;
3681		else
3682			ms->ms_flags &= ~IEEE80211_MESHFLAGS_GATE;
3683		break;
3684	case IEEE80211_IOC_MESH_TTL:
3685		ms->ms_ttl = (uint8_t) ireq->i_val;
3686		break;
3687	case IEEE80211_IOC_MESH_RTCMD:
3688		switch (ireq->i_val) {
3689		case IEEE80211_MESH_RTCMD_LIST:
3690			return EINVAL;
3691		case IEEE80211_MESH_RTCMD_FLUSH:
3692			ieee80211_mesh_rt_flush(vap);
3693			break;
3694		case IEEE80211_MESH_RTCMD_ADD:
3695			if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ireq->i_data) ||
3696			    IEEE80211_ADDR_EQ(broadcastaddr, ireq->i_data))
3697				return EINVAL;
3698			error = copyin(ireq->i_data, &tmpaddr,
3699			    IEEE80211_ADDR_LEN);
3700			if (error == 0)
3701				ieee80211_mesh_discover(vap, tmpaddr, NULL);
3702			break;
3703		case IEEE80211_MESH_RTCMD_DELETE:
3704			ieee80211_mesh_rt_del(vap, ireq->i_data);
3705			break;
3706		default:
3707			return ENOSYS;
3708		}
3709		break;
3710	case IEEE80211_IOC_MESH_PR_METRIC:
3711		error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto));
3712		if (error == 0) {
3713			error = mesh_select_proto_metric(vap, tmpproto);
3714			if (error == 0)
3715				error = ENETRESET;
3716		}
3717		break;
3718	case IEEE80211_IOC_MESH_PR_PATH:
3719		error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto));
3720		if (error == 0) {
3721			error = mesh_select_proto_path(vap, tmpproto);
3722			if (error == 0)
3723				error = ENETRESET;
3724		}
3725		break;
3726	default:
3727		return ENOSYS;
3728	}
3729	return error;
3730}
3731IEEE80211_IOCTL_SET(mesh, mesh_ioctl_set80211);
3732