ieee80211_mesh.c revision 262007
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: stable/10/sys/net80211/ieee80211_mesh.c 262007 2014-02-17 01:36:53Z kevlo $");
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 ieee80211_node *ni;
1044
1045	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1046
1047	ni = ieee80211_mesh_find_txnode(vap, rt_gate->rt_dest);
1048	if (ni == NULL) {
1049		ifp->if_oerrors++;
1050		m_freem(m);
1051		return;
1052	}
1053
1054	/*
1055	 * Send through the VAP packet transmit path.
1056	 * This consumes the node ref grabbed above and
1057	 * the mbuf, regardless of whether there's a problem
1058	 * or not.
1059	 */
1060	(void) ieee80211_vap_pkt_send_dest(vap, m, ni);
1061}
1062
1063/*
1064 * Forward the queued frames to known valid mesh gates.
1065 * Assume destination to be outside the MBSS (i.e. proxy entry),
1066 * If no valid mesh gates are known silently discard queued frames.
1067 * After transmitting frames to all known valid mesh gates, this route
1068 * will be marked invalid, and a new path discovery will happen in the hopes
1069 * that (at least) one of the mesh gates have a new proxy entry for us to use.
1070 */
1071void
1072ieee80211_mesh_forward_to_gates(struct ieee80211vap *vap,
1073    struct ieee80211_mesh_route *rt_dest)
1074{
1075	struct ieee80211com *ic = vap->iv_ic;
1076	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1077	struct ieee80211_mesh_route *rt_gate;
1078	struct ieee80211_mesh_gate_route *gr = NULL, *gr_next;
1079	struct mbuf *m, *mcopy, *next;
1080
1081	IEEE80211_TX_UNLOCK_ASSERT(ic);
1082
1083	KASSERT( rt_dest->rt_flags == IEEE80211_MESHRT_FLAGS_DISCOVER,
1084	    ("Route is not marked with IEEE80211_MESHRT_FLAGS_DISCOVER"));
1085
1086	/* XXX: send to more than one valid mash gate */
1087	MESH_RT_LOCK(ms);
1088
1089	m = ieee80211_ageq_remove(&ic->ic_stageq,
1090	    (struct ieee80211_node *)(uintptr_t)
1091	    ieee80211_mac_hash(ic, rt_dest->rt_dest));
1092
1093	TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, gr_next) {
1094		rt_gate = gr->gr_route;
1095		if (rt_gate == NULL) {
1096			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP,
1097				rt_dest->rt_dest,
1098				"mesh gate with no path %6D",
1099				gr->gr_addr, ":");
1100			continue;
1101		}
1102		if ((rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0)
1103			continue;
1104		KASSERT(rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_GATE,
1105		    ("route not marked as a mesh gate"));
1106		KASSERT((rt_gate->rt_flags &
1107			IEEE80211_MESHRT_FLAGS_PROXY) == 0,
1108			("found mesh gate that is also marked porxy"));
1109		/*
1110		 * convert route to a proxy route gated by the current
1111		 * mesh gate, this is needed so encap can built data
1112		 * frame with correct address.
1113		 */
1114		rt_dest->rt_flags = IEEE80211_MESHRT_FLAGS_PROXY |
1115			IEEE80211_MESHRT_FLAGS_VALID;
1116		rt_dest->rt_ext_seq = 1; /* random value */
1117		IEEE80211_ADDR_COPY(rt_dest->rt_mesh_gate, rt_gate->rt_dest);
1118		IEEE80211_ADDR_COPY(rt_dest->rt_nexthop, rt_gate->rt_nexthop);
1119		rt_dest->rt_metric = rt_gate->rt_metric;
1120		rt_dest->rt_nhops = rt_gate->rt_nhops;
1121		ieee80211_mesh_rt_update(rt_dest, ms->ms_ppath->mpp_inact);
1122		MESH_RT_UNLOCK(ms);
1123		/* XXX: lock?? */
1124		mcopy = m_dup(m, M_NOWAIT);
1125		for (; mcopy != NULL; mcopy = next) {
1126			next = mcopy->m_nextpkt;
1127			mcopy->m_nextpkt = NULL;
1128			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP,
1129			    rt_dest->rt_dest,
1130			    "flush queued frame %p len %d", mcopy,
1131			    mcopy->m_pkthdr.len);
1132			mesh_transmit_to_gate(vap, mcopy, rt_gate);
1133		}
1134		MESH_RT_LOCK(ms);
1135	}
1136	rt_dest->rt_flags = 0; /* Mark invalid */
1137	m_freem(m);
1138	MESH_RT_UNLOCK(ms);
1139}
1140
1141/*
1142 * Forward the specified frame.
1143 * Decrement the TTL and set TA to our MAC address.
1144 */
1145static void
1146mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
1147    const struct ieee80211_meshcntl *mc)
1148{
1149	struct ieee80211com *ic = vap->iv_ic;
1150	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1151	struct ifnet *ifp = vap->iv_ifp;
1152	const struct ieee80211_frame *wh =
1153	    mtod(m, const struct ieee80211_frame *);
1154	struct mbuf *mcopy;
1155	struct ieee80211_meshcntl *mccopy;
1156	struct ieee80211_frame *whcopy;
1157	struct ieee80211_node *ni;
1158	int err;
1159
1160	/* This is called from the RX path - don't hold this lock */
1161	IEEE80211_TX_UNLOCK_ASSERT(ic);
1162
1163	/*
1164	 * mesh ttl of 1 means we are the last one receving it,
1165	 * according to amendment we decrement and then check if
1166	 * 0, if so we dont forward.
1167	 */
1168	if (mc->mc_ttl < 1) {
1169		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1170		    "%s", "frame not fwd'd, ttl 1");
1171		vap->iv_stats.is_mesh_fwd_ttl++;
1172		return;
1173	}
1174	if (!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
1175		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1176		    "%s", "frame not fwd'd, fwding disabled");
1177		vap->iv_stats.is_mesh_fwd_disabled++;
1178		return;
1179	}
1180	mcopy = m_dup(m, M_NOWAIT);
1181	if (mcopy == NULL) {
1182		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1183		    "%s", "frame not fwd'd, cannot dup");
1184		vap->iv_stats.is_mesh_fwd_nobuf++;
1185		ifp->if_oerrors++;
1186		return;
1187	}
1188	mcopy = m_pullup(mcopy, ieee80211_hdrspace(ic, wh) +
1189	    sizeof(struct ieee80211_meshcntl));
1190	if (mcopy == NULL) {
1191		IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1192		    "%s", "frame not fwd'd, too short");
1193		vap->iv_stats.is_mesh_fwd_tooshort++;
1194		ifp->if_oerrors++;
1195		m_freem(mcopy);
1196		return;
1197	}
1198	whcopy = mtod(mcopy, struct ieee80211_frame *);
1199	mccopy = (struct ieee80211_meshcntl *)
1200	    (mtod(mcopy, uint8_t *) + ieee80211_hdrspace(ic, wh));
1201	/* XXX clear other bits? */
1202	whcopy->i_fc[1] &= ~IEEE80211_FC1_RETRY;
1203	IEEE80211_ADDR_COPY(whcopy->i_addr2, vap->iv_myaddr);
1204	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1205		ni = ieee80211_ref_node(vap->iv_bss);
1206		mcopy->m_flags |= M_MCAST;
1207	} else {
1208		ni = ieee80211_mesh_find_txnode(vap, whcopy->i_addr3);
1209		if (ni == NULL) {
1210			/*
1211			 * [Optional] any of the following three actions:
1212			 * o silently discard
1213			 * o trigger a path discovery
1214			 * o inform TA that meshDA is unknown.
1215			 */
1216			IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
1217			    "%s", "frame not fwd'd, no path");
1218			ms->ms_ppath->mpp_senderror(vap, whcopy->i_addr3, NULL,
1219			    IEEE80211_REASON_MESH_PERR_NO_FI);
1220			vap->iv_stats.is_mesh_fwd_nopath++;
1221			m_freem(mcopy);
1222			return;
1223		}
1224		IEEE80211_ADDR_COPY(whcopy->i_addr1, ni->ni_macaddr);
1225	}
1226	KASSERT(mccopy->mc_ttl > 0, ("%s called with wrong ttl", __func__));
1227	mccopy->mc_ttl--;
1228
1229	/* XXX calculate priority so drivers can find the tx queue */
1230	M_WME_SETAC(mcopy, WME_AC_BE);
1231
1232	/* XXX do we know m_nextpkt is NULL? */
1233	mcopy->m_pkthdr.rcvif = (void *) ni;
1234
1235	/*
1236	 * XXX this bypasses all of the VAP TX handling; it passes frames
1237	 * directly to the parent interface.
1238	 *
1239	 * Because of this, there's no TX lock being held as there's no
1240	 * encaps state being used.
1241	 *
1242	 * Doing a direct parent transmit may not be the correct thing
1243	 * to do here; we'll have to re-think this soon.
1244	 */
1245	IEEE80211_TX_LOCK(ic);
1246	err = ieee80211_parent_xmitpkt(ic, mcopy);
1247	IEEE80211_TX_UNLOCK(ic);
1248	if (err != 0) {
1249		/* NB: IFQ_HANDOFF reclaims mbuf */
1250		ieee80211_free_node(ni);
1251	} else {
1252		ifp->if_opackets++;
1253	}
1254}
1255
1256static struct mbuf *
1257mesh_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen, int meshdrlen)
1258{
1259#define	WHDIR(wh)	((wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK)
1260#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1261	uint8_t b[sizeof(struct ieee80211_qosframe_addr4) +
1262		  sizeof(struct ieee80211_meshcntl_ae10)];
1263	const struct ieee80211_qosframe_addr4 *wh;
1264	const struct ieee80211_meshcntl_ae10 *mc;
1265	struct ether_header *eh;
1266	struct llc *llc;
1267	int ae;
1268
1269	if (m->m_len < hdrlen + sizeof(*llc) &&
1270	    (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) {
1271		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ANY,
1272		    "discard data frame: %s", "m_pullup failed");
1273		vap->iv_stats.is_rx_tooshort++;
1274		return NULL;
1275	}
1276	memcpy(b, mtod(m, caddr_t), hdrlen);
1277	wh = (const struct ieee80211_qosframe_addr4 *)&b[0];
1278	mc = (const struct ieee80211_meshcntl_ae10 *)&b[hdrlen - meshdrlen];
1279	KASSERT(WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS ||
1280		WHDIR(wh) == IEEE80211_FC1_DIR_DSTODS,
1281	    ("bogus dir, fc 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1]));
1282
1283	llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
1284	if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
1285	    llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
1286	    llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 &&
1287	    /* NB: preserve AppleTalk frames that have a native SNAP hdr */
1288	    !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) ||
1289	      llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) {
1290		m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
1291		llc = NULL;
1292	} else {
1293		m_adj(m, hdrlen - sizeof(*eh));
1294	}
1295	eh = mtod(m, struct ether_header *);
1296	ae = mc->mc_flags & IEEE80211_MESH_AE_MASK;
1297	if (WHDIR(wh) == IEEE80211_FC1_DIR_FROMDS) {
1298		IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr1);
1299		if (ae == IEEE80211_MESH_AE_00) {
1300			IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr3);
1301		} else if (ae == IEEE80211_MESH_AE_01) {
1302			IEEE80211_ADDR_COPY(eh->ether_shost,
1303			    MC01(mc)->mc_addr4);
1304		} else {
1305			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1306			    (const struct ieee80211_frame *)wh, NULL,
1307			    "bad AE %d", ae);
1308			vap->iv_stats.is_mesh_badae++;
1309			m_freem(m);
1310			return NULL;
1311		}
1312	} else {
1313		if (ae == IEEE80211_MESH_AE_00) {
1314			IEEE80211_ADDR_COPY(eh->ether_dhost, wh->i_addr3);
1315			IEEE80211_ADDR_COPY(eh->ether_shost, wh->i_addr4);
1316		} else if (ae == IEEE80211_MESH_AE_10) {
1317			IEEE80211_ADDR_COPY(eh->ether_dhost, mc->mc_addr5);
1318			IEEE80211_ADDR_COPY(eh->ether_shost, mc->mc_addr6);
1319		} else {
1320			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1321			    (const struct ieee80211_frame *)wh, NULL,
1322			    "bad AE %d", ae);
1323			vap->iv_stats.is_mesh_badae++;
1324			m_freem(m);
1325			return NULL;
1326		}
1327	}
1328#ifndef __NO_STRICT_ALIGNMENT
1329	if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), uint32_t)) {
1330		m = ieee80211_realign(vap, m, sizeof(*eh));
1331		if (m == NULL)
1332			return NULL;
1333	}
1334#endif /* !__NO_STRICT_ALIGNMENT */
1335	if (llc != NULL) {
1336		eh = mtod(m, struct ether_header *);
1337		eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh));
1338	}
1339	return m;
1340#undef	WDIR
1341#undef	MC01
1342}
1343
1344/*
1345 * Return non-zero if the unicast mesh data frame should be processed
1346 * locally.  Frames that are not proxy'd have our address, otherwise
1347 * we need to consult the routing table to look for a proxy entry.
1348 */
1349static __inline int
1350mesh_isucastforme(struct ieee80211vap *vap, const struct ieee80211_frame *wh,
1351    const struct ieee80211_meshcntl *mc)
1352{
1353	int ae = mc->mc_flags & 3;
1354
1355	KASSERT((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS,
1356	    ("bad dir 0x%x:0x%x", wh->i_fc[0], wh->i_fc[1]));
1357	KASSERT(ae == IEEE80211_MESH_AE_00 || ae == IEEE80211_MESH_AE_10,
1358	    ("bad AE %d", ae));
1359	if (ae == IEEE80211_MESH_AE_10) {	/* ucast w/ proxy */
1360		const struct ieee80211_meshcntl_ae10 *mc10 =
1361		    (const struct ieee80211_meshcntl_ae10 *) mc;
1362		struct ieee80211_mesh_route *rt =
1363		    ieee80211_mesh_rt_find(vap, mc10->mc_addr5);
1364		/* check for proxy route to ourself */
1365		return (rt != NULL &&
1366		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY));
1367	} else					/* ucast w/o proxy */
1368		return IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr);
1369}
1370
1371/*
1372 * Verifies transmitter, updates lifetime, precursor list and forwards data.
1373 * > 0 means we have forwarded data and no need to process locally
1374 * == 0 means we want to process locally (and we may have forwarded data
1375 * < 0 means there was an error and data should be discarded
1376 */
1377static int
1378mesh_recv_indiv_data_to_fwrd(struct ieee80211vap *vap, struct mbuf *m,
1379    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1380{
1381	struct ieee80211_qosframe_addr4 *qwh;
1382	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1383	struct ieee80211_mesh_route *rt_meshda, *rt_meshsa;
1384
1385	/* This is called from the RX path - don't hold this lock */
1386	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1387
1388	qwh = (struct ieee80211_qosframe_addr4 *)wh;
1389
1390	/*
1391	 * TODO:
1392	 * o verify addr2 is  a legitimate transmitter
1393	 * o lifetime of precursor of addr3 (addr2) is max(init, curr)
1394	 * o lifetime of precursor of addr4 (nexthop) is max(init, curr)
1395	 */
1396
1397	/* set lifetime of addr3 (meshDA) to initial value */
1398	rt_meshda = ieee80211_mesh_rt_find(vap, qwh->i_addr3);
1399	if (rt_meshda == NULL) {
1400		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, qwh->i_addr2,
1401		    "no route to meshDA(%6D)", qwh->i_addr3, ":");
1402		/*
1403		 * [Optional] any of the following three actions:
1404		 * o silently discard 				[X]
1405		 * o trigger a path discovery			[ ]
1406		 * o inform TA that meshDA is unknown.		[ ]
1407		 */
1408		/* XXX: stats */
1409		return (-1);
1410	}
1411
1412	ieee80211_mesh_rt_update(rt_meshda, ticks_to_msecs(
1413	    ms->ms_ppath->mpp_inact));
1414
1415	/* set lifetime of addr4 (meshSA) to initial value */
1416	rt_meshsa = ieee80211_mesh_rt_find(vap, qwh->i_addr4);
1417	KASSERT(rt_meshsa != NULL, ("no route"));
1418	ieee80211_mesh_rt_update(rt_meshsa, ticks_to_msecs(
1419	    ms->ms_ppath->mpp_inact));
1420
1421	mesh_forward(vap, m, mc);
1422	return (1); /* dont process locally */
1423}
1424
1425/*
1426 * Verifies transmitter, updates lifetime, precursor list and process data
1427 * locally, if data is proxy with AE = 10 it could mean data should go
1428 * on another mesh path or data should be forwarded to the DS.
1429 *
1430 * > 0 means we have forwarded data and no need to process locally
1431 * == 0 means we want to process locally (and we may have forwarded data
1432 * < 0 means there was an error and data should be discarded
1433 */
1434static int
1435mesh_recv_indiv_data_to_me(struct ieee80211vap *vap, struct mbuf *m,
1436    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1437{
1438	struct ieee80211_qosframe_addr4 *qwh;
1439	const struct ieee80211_meshcntl_ae10 *mc10;
1440	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1441	struct ieee80211_mesh_route *rt;
1442	int ae;
1443
1444	/* This is called from the RX path - don't hold this lock */
1445	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1446
1447	qwh = (struct ieee80211_qosframe_addr4 *)wh;
1448	mc10 = (const struct ieee80211_meshcntl_ae10 *)mc;
1449
1450	/*
1451	 * TODO:
1452	 * o verify addr2 is  a legitimate transmitter
1453	 * o lifetime of precursor entry is max(init, curr)
1454	 */
1455
1456	/* set lifetime of addr4 (meshSA) to initial value */
1457	rt = ieee80211_mesh_rt_find(vap, qwh->i_addr4);
1458	KASSERT(rt != NULL, ("no route"));
1459	ieee80211_mesh_rt_update(rt, ticks_to_msecs(ms->ms_ppath->mpp_inact));
1460	rt = NULL;
1461
1462	ae = mc10->mc_flags & IEEE80211_MESH_AE_MASK;
1463	KASSERT(ae == IEEE80211_MESH_AE_00 ||
1464	    ae == IEEE80211_MESH_AE_10, ("bad AE %d", ae));
1465	if (ae == IEEE80211_MESH_AE_10) {
1466		if (IEEE80211_ADDR_EQ(mc10->mc_addr5, qwh->i_addr3)) {
1467			return (0); /* process locally */
1468		}
1469
1470		rt =  ieee80211_mesh_rt_find(vap, mc10->mc_addr5);
1471		if (rt != NULL &&
1472		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) &&
1473		    (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) == 0) {
1474			/*
1475			 * Forward on another mesh-path, according to
1476			 * amendment as specified in 9.32.4.1
1477			 */
1478			IEEE80211_ADDR_COPY(qwh->i_addr3, mc10->mc_addr5);
1479			mesh_forward(vap, m,
1480			    (const struct ieee80211_meshcntl *)mc10);
1481			return (1); /* dont process locally */
1482		}
1483		/*
1484		 * All other cases: forward of MSDUs from the MBSS to DS indiv.
1485		 * addressed according to 13.11.3.2.
1486		 */
1487		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_OUTPUT, qwh->i_addr2,
1488		    "forward frame to DS, SA(%6D) DA(%6D)",
1489		    mc10->mc_addr6, ":", mc10->mc_addr5, ":");
1490	}
1491	return (0); /* process locally */
1492}
1493
1494/*
1495 * Try to forward the group addressed data on to other mesh STAs, and
1496 * also to the DS.
1497 *
1498 * > 0 means we have forwarded data and no need to process locally
1499 * == 0 means we want to process locally (and we may have forwarded data
1500 * < 0 means there was an error and data should be discarded
1501 */
1502static int
1503mesh_recv_group_data(struct ieee80211vap *vap, struct mbuf *m,
1504    struct ieee80211_frame *wh, const struct ieee80211_meshcntl *mc)
1505{
1506#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1507	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1508
1509	/* This is called from the RX path - don't hold this lock */
1510	IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
1511
1512	mesh_forward(vap, m, mc);
1513
1514	if(mc->mc_ttl > 0) {
1515		if (mc->mc_flags & IEEE80211_MESH_AE_01) {
1516			/*
1517			 * Forward of MSDUs from the MBSS to DS group addressed
1518			 * (according to 13.11.3.2)
1519			 * This happens by delivering the packet, and a bridge
1520			 * will sent it on another port member.
1521			 */
1522			if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE &&
1523			    ms->ms_flags & IEEE80211_MESHFLAGS_FWD)
1524				IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH,
1525				    MC01(mc)->mc_addr4, "%s",
1526				    "forward from MBSS to the DS");
1527		}
1528	}
1529	return (0); /* process locally */
1530#undef	MC01
1531}
1532
1533static int
1534mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
1535{
1536#define	HAS_SEQ(type)	((type & 0x4) == 0)
1537#define	MC01(mc)	((const struct ieee80211_meshcntl_ae01 *)mc)
1538#define	MC10(mc)	((const struct ieee80211_meshcntl_ae10 *)mc)
1539	struct ieee80211vap *vap = ni->ni_vap;
1540	struct ieee80211com *ic = ni->ni_ic;
1541	struct ifnet *ifp = vap->iv_ifp;
1542	struct ieee80211_frame *wh;
1543	const struct ieee80211_meshcntl *mc;
1544	int hdrspace, meshdrlen, need_tap, error;
1545	uint8_t dir, type, subtype, ae;
1546	uint32_t seq;
1547	const uint8_t *addr;
1548	uint8_t qos[2];
1549	ieee80211_seq rxseq;
1550
1551	KASSERT(ni != NULL, ("null node"));
1552	ni->ni_inact = ni->ni_inact_reload;
1553
1554	need_tap = 1;			/* mbuf need to be tapped. */
1555	type = -1;			/* undefined */
1556
1557	/* This is called from the RX path - don't hold this lock */
1558	IEEE80211_TX_UNLOCK_ASSERT(ic);
1559
1560	if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
1561		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1562		    ni->ni_macaddr, NULL,
1563		    "too short (1): len %u", m->m_pkthdr.len);
1564		vap->iv_stats.is_rx_tooshort++;
1565		goto out;
1566	}
1567	/*
1568	 * Bit of a cheat here, we use a pointer for a 3-address
1569	 * frame format but don't reference fields past outside
1570	 * ieee80211_frame_min w/o first validating the data is
1571	 * present.
1572	*/
1573	wh = mtod(m, struct ieee80211_frame *);
1574
1575	if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
1576	    IEEE80211_FC0_VERSION_0) {
1577		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1578		    ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
1579		vap->iv_stats.is_rx_badversion++;
1580		goto err;
1581	}
1582	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1583	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1584	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1585	if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
1586		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
1587		ni->ni_noise = nf;
1588		if (HAS_SEQ(type)) {
1589			uint8_t tid = ieee80211_gettid(wh);
1590
1591			if (IEEE80211_QOS_HAS_SEQ(wh) &&
1592			    TID_TO_WME_AC(tid) >= WME_AC_VI)
1593				ic->ic_wme.wme_hipri_traffic++;
1594			rxseq = le16toh(*(uint16_t *)wh->i_seq);
1595			if (! ieee80211_check_rxseq(ni, wh)) {
1596				/* duplicate, discard */
1597				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1598				    wh->i_addr1, "duplicate",
1599				    "seqno <%u,%u> fragno <%u,%u> tid %u",
1600				    rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
1601				    ni->ni_rxseqs[tid] >>
1602				    IEEE80211_SEQ_SEQ_SHIFT,
1603				    rxseq & IEEE80211_SEQ_FRAG_MASK,
1604				    ni->ni_rxseqs[tid] &
1605				    IEEE80211_SEQ_FRAG_MASK,
1606				    tid);
1607				vap->iv_stats.is_rx_dup++;
1608				IEEE80211_NODE_STAT(ni, rx_dup);
1609				goto out;
1610			}
1611			ni->ni_rxseqs[tid] = rxseq;
1612		}
1613	}
1614#ifdef IEEE80211_DEBUG
1615	/*
1616	 * It's easier, but too expensive, to simulate different mesh
1617	 * topologies by consulting the ACL policy very early, so do this
1618	 * only under DEBUG.
1619	 *
1620	 * NB: this check is also done upon peering link initiation.
1621	 */
1622	if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) {
1623		IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL,
1624		    wh, NULL, "%s", "disallowed by ACL");
1625		vap->iv_stats.is_rx_acl++;
1626		goto out;
1627	}
1628#endif
1629	switch (type) {
1630	case IEEE80211_FC0_TYPE_DATA:
1631		if (ni == vap->iv_bss)
1632			goto out;
1633		if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
1634			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
1635			    ni->ni_macaddr, NULL,
1636			    "peer link not yet established (%d)",
1637			    ni->ni_mlstate);
1638			vap->iv_stats.is_mesh_nolink++;
1639			goto out;
1640		}
1641		if (dir != IEEE80211_FC1_DIR_FROMDS &&
1642		    dir != IEEE80211_FC1_DIR_DSTODS) {
1643			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1644			    wh, "data", "incorrect dir 0x%x", dir);
1645			vap->iv_stats.is_rx_wrongdir++;
1646			goto err;
1647		}
1648
1649		/* All Mesh data frames are QoS subtype */
1650		if (!HAS_SEQ(type)) {
1651			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1652			    wh, "data", "incorrect subtype 0x%x", subtype);
1653			vap->iv_stats.is_rx_badsubtype++;
1654			goto err;
1655		}
1656
1657		/*
1658		 * Next up, any fragmentation.
1659		 * XXX: we defrag before we even try to forward,
1660		 * Mesh Control field is not present in sub-sequent
1661		 * fragmented frames. This is in contrast to Draft 4.0.
1662		 */
1663		hdrspace = ieee80211_hdrspace(ic, wh);
1664		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1665			m = ieee80211_defrag(ni, m, hdrspace);
1666			if (m == NULL) {
1667				/* Fragment dropped or frame not complete yet */
1668				goto out;
1669			}
1670		}
1671		wh = mtod(m, struct ieee80211_frame *); /* NB: after defrag */
1672
1673		/*
1674		 * Now we have a complete Mesh Data frame.
1675		 */
1676
1677		/*
1678		 * Only fromDStoDS data frames use 4 address qos frames
1679		 * as specified in amendment. Otherwise addr4 is located
1680		 * in the Mesh Control field and a 3 address qos frame
1681		 * is used.
1682		 */
1683		if (IEEE80211_IS_DSTODS(wh))
1684			*(uint16_t *)qos = *(uint16_t *)
1685			    ((struct ieee80211_qosframe_addr4 *)wh)->i_qos;
1686		else
1687			*(uint16_t *)qos = *(uint16_t *)
1688			    ((struct ieee80211_qosframe *)wh)->i_qos;
1689
1690		/*
1691		 * NB: The mesh STA sets the Mesh Control Present
1692		 * subfield to 1 in the Mesh Data frame containing
1693		 * an unfragmented MSDU, an A-MSDU, or the first
1694		 * fragment of an MSDU.
1695		 * After defrag it should always be present.
1696		 */
1697		if (!(qos[1] & IEEE80211_QOS_MC)) {
1698			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
1699			    ni->ni_macaddr, NULL,
1700			    "%s", "Mesh control field not present");
1701			vap->iv_stats.is_rx_elem_missing++; /* XXX: kinda */
1702			goto err;
1703		}
1704
1705		/* pull up enough to get to the mesh control */
1706		if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) &&
1707		    (m = m_pullup(m, hdrspace +
1708		        sizeof(struct ieee80211_meshcntl))) == NULL) {
1709			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1710			    ni->ni_macaddr, NULL,
1711			    "data too short: expecting %u", hdrspace);
1712			vap->iv_stats.is_rx_tooshort++;
1713			goto out;		/* XXX */
1714		}
1715		/*
1716		 * Now calculate the full extent of the headers. Note
1717		 * mesh_decap will pull up anything we didn't get
1718		 * above when it strips the 802.11 headers.
1719		 */
1720		mc = (const struct ieee80211_meshcntl *)
1721		    (mtod(m, const uint8_t *) + hdrspace);
1722		ae = mc->mc_flags & IEEE80211_MESH_AE_MASK;
1723		meshdrlen = sizeof(struct ieee80211_meshcntl) +
1724		    ae * IEEE80211_ADDR_LEN;
1725		hdrspace += meshdrlen;
1726
1727		/* pull complete hdrspace = ieee80211_hdrspace + meshcontrol */
1728		if ((meshdrlen > sizeof(struct ieee80211_meshcntl)) &&
1729		    (m->m_len < hdrspace) &&
1730		    ((m = m_pullup(m, hdrspace)) == NULL)) {
1731			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1732			    ni->ni_macaddr, NULL,
1733			    "data too short: expecting %u", hdrspace);
1734			vap->iv_stats.is_rx_tooshort++;
1735			goto out;		/* XXX */
1736		}
1737		/* XXX: are we sure there is no reallocating after m_pullup? */
1738
1739		seq = LE_READ_4(mc->mc_seq);
1740		if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1741			addr = wh->i_addr3;
1742		else if (ae == IEEE80211_MESH_AE_01)
1743			addr = MC01(mc)->mc_addr4;
1744		else
1745			addr = ((struct ieee80211_qosframe_addr4 *)wh)->i_addr4;
1746		if (IEEE80211_ADDR_EQ(vap->iv_myaddr, addr)) {
1747			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1748			    addr, "data", "%s", "not to me");
1749			vap->iv_stats.is_rx_wrongbss++;	/* XXX kinda */
1750			goto out;
1751		}
1752		if (mesh_checkpseq(vap, addr, seq) != 0) {
1753			vap->iv_stats.is_rx_dup++;
1754			goto out;
1755		}
1756
1757		/* This code "routes" the frame to the right control path */
1758		if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1759			if (IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr3))
1760				error =
1761				    mesh_recv_indiv_data_to_me(vap, m, wh, mc);
1762			else if (IEEE80211_IS_MULTICAST(wh->i_addr3))
1763				error = mesh_recv_group_data(vap, m, wh, mc);
1764			else
1765				error = mesh_recv_indiv_data_to_fwrd(vap, m,
1766				    wh, mc);
1767		} else
1768			error = mesh_recv_group_data(vap, m, wh, mc);
1769		if (error < 0)
1770			goto err;
1771		else if (error > 0)
1772			goto out;
1773
1774		if (ieee80211_radiotap_active_vap(vap))
1775			ieee80211_radiotap_rx(vap, m);
1776		need_tap = 0;
1777
1778		/*
1779		 * Finally, strip the 802.11 header.
1780		 */
1781		m = mesh_decap(vap, m, hdrspace, meshdrlen);
1782		if (m == NULL) {
1783			/* XXX mask bit to check for both */
1784			/* don't count Null data frames as errors */
1785			if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
1786			    subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
1787				goto out;
1788			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
1789			    ni->ni_macaddr, "data", "%s", "decap error");
1790			vap->iv_stats.is_rx_decap++;
1791			IEEE80211_NODE_STAT(ni, rx_decap);
1792			goto err;
1793		}
1794		if (qos[0] & IEEE80211_QOS_AMSDU) {
1795			m = ieee80211_decap_amsdu(ni, m);
1796			if (m == NULL)
1797				return IEEE80211_FC0_TYPE_DATA;
1798		}
1799		ieee80211_deliver_data(vap, ni, m);
1800		return type;
1801	case IEEE80211_FC0_TYPE_MGT:
1802		vap->iv_stats.is_rx_mgmt++;
1803		IEEE80211_NODE_STAT(ni, rx_mgmt);
1804		if (dir != IEEE80211_FC1_DIR_NODS) {
1805			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1806			    wh, "mgt", "incorrect dir 0x%x", dir);
1807			vap->iv_stats.is_rx_wrongdir++;
1808			goto err;
1809		}
1810		if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
1811			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
1812			    ni->ni_macaddr, "mgt", "too short: len %u",
1813			    m->m_pkthdr.len);
1814			vap->iv_stats.is_rx_tooshort++;
1815			goto out;
1816		}
1817#ifdef IEEE80211_DEBUG
1818		if ((ieee80211_msg_debug(vap) &&
1819		    (vap->iv_ic->ic_flags & IEEE80211_F_SCAN)) ||
1820		    ieee80211_msg_dumppkts(vap)) {
1821			if_printf(ifp, "received %s from %s rssi %d\n",
1822			    ieee80211_mgt_subtype_name[subtype >>
1823			    IEEE80211_FC0_SUBTYPE_SHIFT],
1824			    ether_sprintf(wh->i_addr2), rssi);
1825		}
1826#endif
1827		if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1828			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1829			    wh, NULL, "%s", "WEP set but not permitted");
1830			vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
1831			goto out;
1832		}
1833		vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
1834		goto out;
1835	case IEEE80211_FC0_TYPE_CTL:
1836		vap->iv_stats.is_rx_ctl++;
1837		IEEE80211_NODE_STAT(ni, rx_ctrl);
1838		goto out;
1839	default:
1840		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
1841		    wh, "bad", "frame type 0x%x", type);
1842		/* should not come here */
1843		break;
1844	}
1845err:
1846	ifp->if_ierrors++;
1847out:
1848	if (m != NULL) {
1849		if (need_tap && ieee80211_radiotap_active_vap(vap))
1850			ieee80211_radiotap_rx(vap, m);
1851		m_freem(m);
1852	}
1853	return type;
1854#undef	HAS_SEQ
1855#undef	MC01
1856#undef	MC10
1857}
1858
1859static void
1860mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
1861    int rssi, int nf)
1862{
1863	struct ieee80211vap *vap = ni->ni_vap;
1864	struct ieee80211_mesh_state *ms = vap->iv_mesh;
1865	struct ieee80211com *ic = ni->ni_ic;
1866	struct ieee80211_frame *wh;
1867	struct ieee80211_mesh_route *rt;
1868	uint8_t *frm, *efrm;
1869
1870	wh = mtod(m0, struct ieee80211_frame *);
1871	frm = (uint8_t *)&wh[1];
1872	efrm = mtod(m0, uint8_t *) + m0->m_len;
1873	switch (subtype) {
1874	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1875	case IEEE80211_FC0_SUBTYPE_BEACON:
1876	{
1877		struct ieee80211_scanparams scan;
1878		/*
1879		 * We process beacon/probe response
1880		 * frames to discover neighbors.
1881		 */
1882		if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
1883			return;
1884		/*
1885		 * Count frame now that we know it's to be processed.
1886		 */
1887		if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1888			vap->iv_stats.is_rx_beacon++;	/* XXX remove */
1889			IEEE80211_NODE_STAT(ni, rx_beacons);
1890		} else
1891			IEEE80211_NODE_STAT(ni, rx_proberesp);
1892		/*
1893		 * If scanning, just pass information to the scan module.
1894		 */
1895		if (ic->ic_flags & IEEE80211_F_SCAN) {
1896			if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
1897				/*
1898				 * Actively scanning a channel marked passive;
1899				 * send a probe request now that we know there
1900				 * is 802.11 traffic present.
1901				 *
1902				 * XXX check if the beacon we recv'd gives
1903				 * us what we need and suppress the probe req
1904				 */
1905				ieee80211_probe_curchan(vap, 1);
1906				ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
1907			}
1908			ieee80211_add_scan(vap, &scan, wh,
1909			    subtype, rssi, nf);
1910			return;
1911		}
1912
1913		/* The rest of this code assumes we are running */
1914		if (vap->iv_state != IEEE80211_S_RUN)
1915			return;
1916		/*
1917		 * Ignore non-mesh STAs.
1918		 */
1919		if ((scan.capinfo &
1920		     (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) ||
1921		    scan.meshid == NULL || scan.meshconf == NULL) {
1922			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1923			    wh, "beacon", "%s", "not a mesh sta");
1924			vap->iv_stats.is_mesh_wrongmesh++;
1925			return;
1926		}
1927		/*
1928		 * Ignore STAs for other mesh networks.
1929		 */
1930		if (memcmp(scan.meshid+2, ms->ms_id, ms->ms_idlen) != 0 ||
1931		    mesh_verify_meshconf(vap, scan.meshconf)) {
1932			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
1933			    wh, "beacon", "%s", "not for our mesh");
1934			vap->iv_stats.is_mesh_wrongmesh++;
1935			return;
1936		}
1937		/*
1938		 * Peer only based on the current ACL policy.
1939		 */
1940		if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) {
1941			IEEE80211_DISCARD(vap, IEEE80211_MSG_ACL,
1942			    wh, NULL, "%s", "disallowed by ACL");
1943			vap->iv_stats.is_rx_acl++;
1944			return;
1945		}
1946		/*
1947		 * Do neighbor discovery.
1948		 */
1949		if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
1950			/*
1951			 * Create a new entry in the neighbor table.
1952			 */
1953			ni = ieee80211_add_neighbor(vap, wh, &scan);
1954		}
1955		/*
1956		 * Automatically peer with discovered nodes if possible.
1957		 */
1958		if (ni != vap->iv_bss &&
1959		    (ms->ms_flags & IEEE80211_MESHFLAGS_AP)) {
1960			switch (ni->ni_mlstate) {
1961			case IEEE80211_NODE_MESH_IDLE:
1962			{
1963				uint16_t args[1];
1964
1965				/* Wait for backoff callout to reset counter */
1966				if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding)
1967					return;
1968
1969				ni->ni_mlpid = mesh_generateid(vap);
1970				if (ni->ni_mlpid == 0)
1971					return;
1972				mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT);
1973				args[0] = ni->ni_mlpid;
1974				ieee80211_send_action(ni,
1975				IEEE80211_ACTION_CAT_SELF_PROT,
1976				IEEE80211_ACTION_MESHPEERING_OPEN, args);
1977				ni->ni_mlrcnt = 0;
1978				mesh_peer_timeout_setup(ni);
1979				break;
1980			}
1981			case IEEE80211_NODE_MESH_ESTABLISHED:
1982			{
1983				/*
1984				 * Valid beacon from a peer mesh STA
1985				 * bump TA lifetime
1986				 */
1987				rt = ieee80211_mesh_rt_find(vap, wh->i_addr2);
1988				if(rt != NULL) {
1989					ieee80211_mesh_rt_update(rt,
1990					    ticks_to_msecs(
1991					    ms->ms_ppath->mpp_inact));
1992				}
1993				break;
1994			}
1995			default:
1996				break; /* ignore */
1997			}
1998		}
1999		break;
2000	}
2001	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
2002	{
2003		uint8_t *ssid, *meshid, *rates, *xrates;
2004		uint8_t *sfrm;
2005
2006		if (vap->iv_state != IEEE80211_S_RUN) {
2007			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2008			    wh, NULL, "wrong state %s",
2009			    ieee80211_state_name[vap->iv_state]);
2010			vap->iv_stats.is_rx_mgtdiscard++;
2011			return;
2012		}
2013		if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
2014			/* frame must be directed */
2015			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2016			    wh, NULL, "%s", "not unicast");
2017			vap->iv_stats.is_rx_mgtdiscard++;	/* XXX stat */
2018			return;
2019		}
2020		/*
2021		 * prreq frame format
2022		 *      [tlv] ssid
2023		 *      [tlv] supported rates
2024		 *      [tlv] extended supported rates
2025		 *	[tlv] mesh id
2026		 */
2027		ssid = meshid = rates = xrates = NULL;
2028		sfrm = frm;
2029		while (efrm - frm > 1) {
2030			IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
2031			switch (*frm) {
2032			case IEEE80211_ELEMID_SSID:
2033				ssid = frm;
2034				break;
2035			case IEEE80211_ELEMID_RATES:
2036				rates = frm;
2037				break;
2038			case IEEE80211_ELEMID_XRATES:
2039				xrates = frm;
2040				break;
2041			case IEEE80211_ELEMID_MESHID:
2042				meshid = frm;
2043				break;
2044			}
2045			frm += frm[1] + 2;
2046		}
2047		IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return);
2048		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
2049		if (xrates != NULL)
2050			IEEE80211_VERIFY_ELEMENT(xrates,
2051			    IEEE80211_RATE_MAXSIZE - rates[1], return);
2052		if (meshid != NULL) {
2053			IEEE80211_VERIFY_ELEMENT(meshid,
2054			    IEEE80211_MESHID_LEN, return);
2055			/* NB: meshid, not ssid */
2056			IEEE80211_VERIFY_SSID(vap->iv_bss, meshid, return);
2057		}
2058
2059		/* XXX find a better class or define it's own */
2060		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
2061		    "%s", "recv probe req");
2062		/*
2063		 * Some legacy 11b clients cannot hack a complete
2064		 * probe response frame.  When the request includes
2065		 * only a bare-bones rate set, communicate this to
2066		 * the transmit side.
2067		 */
2068		ieee80211_send_proberesp(vap, wh->i_addr2, 0);
2069		break;
2070	}
2071
2072	case IEEE80211_FC0_SUBTYPE_ACTION:
2073	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
2074		if (ni == vap->iv_bss) {
2075			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2076			    wh, NULL, "%s", "unknown node");
2077			vap->iv_stats.is_rx_mgtdiscard++;
2078		} else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
2079		    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2080			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2081			    wh, NULL, "%s", "not for us");
2082			vap->iv_stats.is_rx_mgtdiscard++;
2083		} else if (vap->iv_state != IEEE80211_S_RUN) {
2084			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2085			    wh, NULL, "wrong state %s",
2086			    ieee80211_state_name[vap->iv_state]);
2087			vap->iv_stats.is_rx_mgtdiscard++;
2088		} else {
2089			if (ieee80211_parse_action(ni, m0) == 0)
2090				(void)ic->ic_recv_action(ni, wh, frm, efrm);
2091		}
2092		break;
2093
2094	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2095	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2096	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
2097	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
2098	case IEEE80211_FC0_SUBTYPE_ATIM:
2099	case IEEE80211_FC0_SUBTYPE_DISASSOC:
2100	case IEEE80211_FC0_SUBTYPE_AUTH:
2101	case IEEE80211_FC0_SUBTYPE_DEAUTH:
2102		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
2103		    wh, NULL, "%s", "not handled");
2104		vap->iv_stats.is_rx_mgtdiscard++;
2105		break;
2106
2107	default:
2108		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
2109		    wh, "mgt", "subtype 0x%x not handled", subtype);
2110		vap->iv_stats.is_rx_badsubtype++;
2111		break;
2112	}
2113}
2114
2115static void
2116mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
2117{
2118
2119	switch (subtype) {
2120	case IEEE80211_FC0_SUBTYPE_BAR:
2121		ieee80211_recv_bar(ni, m);
2122		break;
2123	}
2124}
2125
2126/*
2127 * Parse meshpeering action ie's for MPM frames
2128 */
2129static const struct ieee80211_meshpeer_ie *
2130mesh_parse_meshpeering_action(struct ieee80211_node *ni,
2131	const struct ieee80211_frame *wh,	/* XXX for VERIFY_LENGTH */
2132	const uint8_t *frm, const uint8_t *efrm,
2133	struct ieee80211_meshpeer_ie *mp, uint8_t subtype)
2134{
2135	struct ieee80211vap *vap = ni->ni_vap;
2136	const struct ieee80211_meshpeer_ie *mpie;
2137	uint16_t args[3];
2138	const uint8_t *meshid, *meshconf, *meshpeer;
2139	uint8_t sendclose = 0; /* 1 = MPM frame rejected, close will be sent */
2140
2141	meshid = meshconf = meshpeer = NULL;
2142	while (efrm - frm > 1) {
2143		IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL);
2144		switch (*frm) {
2145		case IEEE80211_ELEMID_MESHID:
2146			meshid = frm;
2147			break;
2148		case IEEE80211_ELEMID_MESHCONF:
2149			meshconf = frm;
2150			break;
2151		case IEEE80211_ELEMID_MESHPEER:
2152			meshpeer = frm;
2153			mpie = (const struct ieee80211_meshpeer_ie *) frm;
2154			memset(mp, 0, sizeof(*mp));
2155			mp->peer_len = mpie->peer_len;
2156			mp->peer_proto = LE_READ_2(&mpie->peer_proto);
2157			mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
2158			switch (subtype) {
2159			case IEEE80211_ACTION_MESHPEERING_CONFIRM:
2160				mp->peer_linkid =
2161				    LE_READ_2(&mpie->peer_linkid);
2162				break;
2163			case IEEE80211_ACTION_MESHPEERING_CLOSE:
2164				/* NB: peer link ID is optional */
2165				if (mpie->peer_len ==
2166				    (IEEE80211_MPM_BASE_SZ + 2)) {
2167					mp->peer_linkid = 0;
2168					mp->peer_rcode =
2169					    LE_READ_2(&mpie->peer_linkid);
2170				} else {
2171					mp->peer_linkid =
2172					    LE_READ_2(&mpie->peer_linkid);
2173					mp->peer_rcode =
2174					    LE_READ_2(&mpie->peer_rcode);
2175				}
2176				break;
2177			}
2178			break;
2179		}
2180		frm += frm[1] + 2;
2181	}
2182
2183	/*
2184	 * Verify the contents of the frame.
2185	 * If it fails validation, close the peer link.
2186	 */
2187	if (mesh_verify_meshpeer(vap, subtype, (const uint8_t *)mp)) {
2188		sendclose = 1;
2189		IEEE80211_DISCARD(vap,
2190		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2191		    wh, NULL, "%s", "MPM validation failed");
2192	}
2193
2194	/* If meshid is not the same reject any frames type. */
2195	if (sendclose == 0 && mesh_verify_meshid(vap, meshid)) {
2196		sendclose = 1;
2197		IEEE80211_DISCARD(vap,
2198		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2199		    wh, NULL, "%s", "not for our mesh");
2200		if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE) {
2201			/*
2202			 * Standard not clear about this, if we dont ignore
2203			 * there will be an endless loop between nodes sending
2204			 * CLOSE frames between each other with wrong meshid.
2205			 * Discard and timers will bring FSM to IDLE state.
2206			 */
2207			return NULL;
2208		}
2209	}
2210
2211	/*
2212	 * Close frames are accepted if meshid is the same.
2213	 * Verify the other two types.
2214	 */
2215	if (sendclose == 0 && subtype != IEEE80211_ACTION_MESHPEERING_CLOSE &&
2216	    mesh_verify_meshconf(vap, meshconf)) {
2217		sendclose = 1;
2218		IEEE80211_DISCARD(vap,
2219		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2220		    wh, NULL, "%s", "configuration missmatch");
2221	}
2222
2223	if (sendclose) {
2224		vap->iv_stats.is_rx_mgtdiscard++;
2225		switch (ni->ni_mlstate) {
2226		case IEEE80211_NODE_MESH_IDLE:
2227		case IEEE80211_NODE_MESH_ESTABLISHED:
2228		case IEEE80211_NODE_MESH_HOLDING:
2229			/* ignore */
2230			break;
2231		case IEEE80211_NODE_MESH_OPENSNT:
2232		case IEEE80211_NODE_MESH_OPENRCV:
2233		case IEEE80211_NODE_MESH_CONFIRMRCV:
2234			args[0] = ni->ni_mlpid;
2235			args[1] = ni->ni_mllid;
2236			/* Reason codes for rejection */
2237			switch (subtype) {
2238			case IEEE80211_ACTION_MESHPEERING_OPEN:
2239				args[2] = IEEE80211_REASON_MESH_CPVIOLATION;
2240				break;
2241			case IEEE80211_ACTION_MESHPEERING_CONFIRM:
2242				args[2] = IEEE80211_REASON_MESH_INCONS_PARAMS;
2243				break;
2244			}
2245			ieee80211_send_action(ni,
2246			    IEEE80211_ACTION_CAT_SELF_PROT,
2247			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2248			    args);
2249			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2250			mesh_peer_timeout_setup(ni);
2251			break;
2252		}
2253		return NULL;
2254	}
2255
2256	return (const struct ieee80211_meshpeer_ie *) mp;
2257}
2258
2259static int
2260mesh_recv_action_meshpeering_open(struct ieee80211_node *ni,
2261	const struct ieee80211_frame *wh,
2262	const uint8_t *frm, const uint8_t *efrm)
2263{
2264	struct ieee80211vap *vap = ni->ni_vap;
2265	struct ieee80211_mesh_state *ms = vap->iv_mesh;
2266	struct ieee80211_meshpeer_ie ie;
2267	const struct ieee80211_meshpeer_ie *meshpeer;
2268	uint16_t args[3];
2269
2270	/* +2+2 for action + code + capabilites */
2271	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie,
2272	    IEEE80211_ACTION_MESHPEERING_OPEN);
2273	if (meshpeer == NULL) {
2274		return 0;
2275	}
2276
2277	/* XXX move up */
2278	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2279	    "recv PEER OPEN, lid 0x%x", meshpeer->peer_llinkid);
2280
2281	switch (ni->ni_mlstate) {
2282	case IEEE80211_NODE_MESH_IDLE:
2283		/* Reject open request if reached our maximum neighbor count */
2284		if (ms->ms_neighbors >= IEEE80211_MESH_MAX_NEIGHBORS) {
2285			args[0] = meshpeer->peer_llinkid;
2286			args[1] = 0;
2287			args[2] = IEEE80211_REASON_MESH_MAX_PEERS;
2288			ieee80211_send_action(ni,
2289			    IEEE80211_ACTION_CAT_SELF_PROT,
2290			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2291			    args);
2292			/* stay in IDLE state */
2293			return (0);
2294		}
2295		/* Open frame accepted */
2296		mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV);
2297		ni->ni_mllid = meshpeer->peer_llinkid;
2298		ni->ni_mlpid = mesh_generateid(vap);
2299		if (ni->ni_mlpid == 0)
2300			return 0;		/* XXX */
2301		args[0] = ni->ni_mlpid;
2302		/* Announce we're open too... */
2303		ieee80211_send_action(ni,
2304		    IEEE80211_ACTION_CAT_SELF_PROT,
2305		    IEEE80211_ACTION_MESHPEERING_OPEN, args);
2306		/* ...and confirm the link. */
2307		args[0] = ni->ni_mlpid;
2308		args[1] = ni->ni_mllid;
2309		ieee80211_send_action(ni,
2310		    IEEE80211_ACTION_CAT_SELF_PROT,
2311		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2312		    args);
2313		mesh_peer_timeout_setup(ni);
2314		break;
2315	case IEEE80211_NODE_MESH_OPENRCV:
2316		/* Wrong Link ID */
2317		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2318			args[0] = ni->ni_mllid;
2319			args[1] = ni->ni_mlpid;
2320			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2321			ieee80211_send_action(ni,
2322			    IEEE80211_ACTION_CAT_SELF_PROT,
2323			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2324			    args);
2325			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2326			mesh_peer_timeout_setup(ni);
2327			break;
2328		}
2329		/* Duplicate open, confirm again. */
2330		args[0] = ni->ni_mlpid;
2331		args[1] = ni->ni_mllid;
2332		ieee80211_send_action(ni,
2333		    IEEE80211_ACTION_CAT_SELF_PROT,
2334		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2335		    args);
2336		break;
2337	case IEEE80211_NODE_MESH_OPENSNT:
2338		ni->ni_mllid = meshpeer->peer_llinkid;
2339		mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENRCV);
2340		args[0] = ni->ni_mlpid;
2341		args[1] = ni->ni_mllid;
2342		ieee80211_send_action(ni,
2343		    IEEE80211_ACTION_CAT_SELF_PROT,
2344		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2345		    args);
2346		/* NB: don't setup/clear any timeout */
2347		break;
2348	case IEEE80211_NODE_MESH_CONFIRMRCV:
2349		if (ni->ni_mlpid != meshpeer->peer_linkid ||
2350		    ni->ni_mllid != meshpeer->peer_llinkid) {
2351			args[0] = ni->ni_mlpid;
2352			args[1] = ni->ni_mllid;
2353			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2354			ieee80211_send_action(ni,
2355			    IEEE80211_ACTION_CAT_SELF_PROT,
2356			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2357			    args);
2358			mesh_linkchange(ni,
2359			    IEEE80211_NODE_MESH_HOLDING);
2360			mesh_peer_timeout_setup(ni);
2361			break;
2362		}
2363		mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED);
2364		ni->ni_mllid = meshpeer->peer_llinkid;
2365		args[0] = ni->ni_mlpid;
2366		args[1] = ni->ni_mllid;
2367		ieee80211_send_action(ni,
2368		    IEEE80211_ACTION_CAT_SELF_PROT,
2369		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2370		    args);
2371		mesh_peer_timeout_stop(ni);
2372		break;
2373	case IEEE80211_NODE_MESH_ESTABLISHED:
2374		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2375			args[0] = ni->ni_mllid;
2376			args[1] = ni->ni_mlpid;
2377			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2378			ieee80211_send_action(ni,
2379			    IEEE80211_ACTION_CAT_SELF_PROT,
2380			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2381			    args);
2382			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2383			mesh_peer_timeout_setup(ni);
2384			break;
2385		}
2386		args[0] = ni->ni_mlpid;
2387		args[1] = ni->ni_mllid;
2388		ieee80211_send_action(ni,
2389		    IEEE80211_ACTION_CAT_SELF_PROT,
2390		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2391		    args);
2392		break;
2393	case IEEE80211_NODE_MESH_HOLDING:
2394		args[0] = ni->ni_mlpid;
2395		args[1] = meshpeer->peer_llinkid;
2396		/* Standard not clear about what the reaason code should be */
2397		args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2398		ieee80211_send_action(ni,
2399		    IEEE80211_ACTION_CAT_SELF_PROT,
2400		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2401		    args);
2402		break;
2403	}
2404	return 0;
2405}
2406
2407static int
2408mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni,
2409	const struct ieee80211_frame *wh,
2410	const uint8_t *frm, const uint8_t *efrm)
2411{
2412	struct ieee80211vap *vap = ni->ni_vap;
2413	struct ieee80211_meshpeer_ie ie;
2414	const struct ieee80211_meshpeer_ie *meshpeer;
2415	uint16_t args[3];
2416
2417	/* +2+2+2+2 for action + code + capabilites + status code + AID */
2418	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie,
2419	    IEEE80211_ACTION_MESHPEERING_CONFIRM);
2420	if (meshpeer == NULL) {
2421		return 0;
2422	}
2423
2424	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2425	    "recv PEER CONFIRM, local id 0x%x, peer id 0x%x",
2426	    meshpeer->peer_llinkid, meshpeer->peer_linkid);
2427
2428	switch (ni->ni_mlstate) {
2429	case IEEE80211_NODE_MESH_OPENRCV:
2430		mesh_linkchange(ni, IEEE80211_NODE_MESH_ESTABLISHED);
2431		mesh_peer_timeout_stop(ni);
2432		break;
2433	case IEEE80211_NODE_MESH_OPENSNT:
2434		mesh_linkchange(ni, IEEE80211_NODE_MESH_CONFIRMRCV);
2435		mesh_peer_timeout_setup(ni);
2436		break;
2437	case IEEE80211_NODE_MESH_HOLDING:
2438		args[0] = ni->ni_mlpid;
2439		args[1] = meshpeer->peer_llinkid;
2440		/* Standard not clear about what the reaason code should be */
2441		args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2442		ieee80211_send_action(ni,
2443		    IEEE80211_ACTION_CAT_SELF_PROT,
2444		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2445		    args);
2446		break;
2447	case IEEE80211_NODE_MESH_CONFIRMRCV:
2448		if (ni->ni_mllid != meshpeer->peer_llinkid) {
2449			args[0] = ni->ni_mlpid;
2450			args[1] = ni->ni_mllid;
2451			args[2] = IEEE80211_REASON_PEER_LINK_CANCELED;
2452			ieee80211_send_action(ni,
2453			    IEEE80211_ACTION_CAT_SELF_PROT,
2454			    IEEE80211_ACTION_MESHPEERING_CLOSE,
2455			    args);
2456			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2457			mesh_peer_timeout_setup(ni);
2458		}
2459		break;
2460	default:
2461		IEEE80211_DISCARD(vap,
2462		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2463		    wh, NULL, "received confirm in invalid state %d",
2464		    ni->ni_mlstate);
2465		vap->iv_stats.is_rx_mgtdiscard++;
2466		break;
2467	}
2468	return 0;
2469}
2470
2471static int
2472mesh_recv_action_meshpeering_close(struct ieee80211_node *ni,
2473	const struct ieee80211_frame *wh,
2474	const uint8_t *frm, const uint8_t *efrm)
2475{
2476	struct ieee80211_meshpeer_ie ie;
2477	const struct ieee80211_meshpeer_ie *meshpeer;
2478	uint16_t args[3];
2479
2480	/* +2 for action + code */
2481	meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2, efrm, &ie,
2482	    IEEE80211_ACTION_MESHPEERING_CLOSE);
2483	if (meshpeer == NULL) {
2484		return 0;
2485	}
2486
2487	/*
2488	 * XXX: check reason code, for example we could receive
2489	 * IEEE80211_REASON_MESH_MAX_PEERS then we should not attempt
2490	 * to peer again.
2491	 */
2492
2493	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2494	    ni, "%s", "recv PEER CLOSE");
2495
2496	switch (ni->ni_mlstate) {
2497	case IEEE80211_NODE_MESH_IDLE:
2498		/* ignore */
2499		break;
2500	case IEEE80211_NODE_MESH_OPENRCV:
2501	case IEEE80211_NODE_MESH_OPENSNT:
2502	case IEEE80211_NODE_MESH_CONFIRMRCV:
2503	case IEEE80211_NODE_MESH_ESTABLISHED:
2504		args[0] = ni->ni_mlpid;
2505		args[1] = ni->ni_mllid;
2506		args[2] = IEEE80211_REASON_MESH_CLOSE_RCVD;
2507		ieee80211_send_action(ni,
2508		    IEEE80211_ACTION_CAT_SELF_PROT,
2509		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2510		    args);
2511		mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
2512		mesh_peer_timeout_setup(ni);
2513		break;
2514	case IEEE80211_NODE_MESH_HOLDING:
2515		mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE);
2516		mesh_peer_timeout_stop(ni);
2517		break;
2518	}
2519	return 0;
2520}
2521
2522/*
2523 * Link Metric handling.
2524 */
2525static int
2526mesh_recv_action_meshlmetric(struct ieee80211_node *ni,
2527	const struct ieee80211_frame *wh,
2528	const uint8_t *frm, const uint8_t *efrm)
2529{
2530	const struct ieee80211_meshlmetric_ie *ie =
2531	    (const struct ieee80211_meshlmetric_ie *)
2532	    (frm+2); /* action + code */
2533	struct ieee80211_meshlmetric_ie lm_rep;
2534
2535	if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
2536		lm_rep.lm_flags = 0;
2537		lm_rep.lm_metric = mesh_airtime_calc(ni);
2538		ieee80211_send_action(ni,
2539		    IEEE80211_ACTION_CAT_MESH,
2540		    IEEE80211_ACTION_MESH_LMETRIC,
2541		    &lm_rep);
2542	}
2543	/* XXX: else do nothing for now */
2544	return 0;
2545}
2546
2547/*
2548 * Parse meshgate action ie's for GANN frames.
2549 * Returns -1 if parsing fails, otherwise 0.
2550 */
2551static int
2552mesh_parse_meshgate_action(struct ieee80211_node *ni,
2553    const struct ieee80211_frame *wh,	/* XXX for VERIFY_LENGTH */
2554    struct ieee80211_meshgann_ie *ie, const uint8_t *frm, const uint8_t *efrm)
2555{
2556	struct ieee80211vap *vap = ni->ni_vap;
2557	const struct ieee80211_meshgann_ie *gannie;
2558
2559	while (efrm - frm > 1) {
2560		IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return -1);
2561		switch (*frm) {
2562		case IEEE80211_ELEMID_MESHGANN:
2563			gannie = (const struct ieee80211_meshgann_ie *) frm;
2564			memset(ie, 0, sizeof(*ie));
2565			ie->gann_ie = gannie->gann_ie;
2566			ie->gann_len = gannie->gann_len;
2567			ie->gann_flags = gannie->gann_flags;
2568			ie->gann_hopcount = gannie->gann_hopcount;
2569			ie->gann_ttl = gannie->gann_ttl;
2570			IEEE80211_ADDR_COPY(ie->gann_addr, gannie->gann_addr);
2571			ie->gann_seq = LE_READ_4(&gannie->gann_seq);
2572			ie->gann_interval = LE_READ_2(&gannie->gann_interval);
2573			break;
2574		}
2575		frm += frm[1] + 2;
2576	}
2577
2578	return 0;
2579}
2580
2581/*
2582 * Mesh Gate Announcement handling.
2583 */
2584static int
2585mesh_recv_action_meshgate(struct ieee80211_node *ni,
2586	const struct ieee80211_frame *wh,
2587	const uint8_t *frm, const uint8_t *efrm)
2588{
2589	struct ieee80211vap *vap = ni->ni_vap;
2590	struct ieee80211_mesh_state *ms = vap->iv_mesh;
2591	struct ieee80211_mesh_gate_route *gr, *next;
2592	struct ieee80211_mesh_route *rt_gate;
2593	struct ieee80211_meshgann_ie pgann;
2594	struct ieee80211_meshgann_ie ie;
2595	int found = 0;
2596
2597	/* +2 for action + code */
2598	if (mesh_parse_meshgate_action(ni, wh, &ie, frm+2, efrm) != 0) {
2599		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
2600		    ni->ni_macaddr, NULL, "%s",
2601		    "GANN parsing failed");
2602		vap->iv_stats.is_rx_mgtdiscard++;
2603		return (0);
2604	}
2605
2606	if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ie.gann_addr))
2607		return 0;
2608
2609	IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ni->ni_macaddr,
2610	    "received GANN, meshgate: %6D (seq %u)", ie.gann_addr, ":",
2611	    ie.gann_seq);
2612
2613	if (ms == NULL)
2614		return (0);
2615	MESH_RT_LOCK(ms);
2616	TAILQ_FOREACH_SAFE(gr, &ms->ms_known_gates, gr_next, next) {
2617		if (!IEEE80211_ADDR_EQ(gr->gr_addr, ie.gann_addr))
2618			continue;
2619		if (ie.gann_seq <= gr->gr_lastseq) {
2620			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
2621			    ni->ni_macaddr, NULL,
2622			    "GANN old seqno %u <= %u",
2623			    ie.gann_seq, gr->gr_lastseq);
2624			MESH_RT_UNLOCK(ms);
2625			return (0);
2626		}
2627		/* corresponding mesh gate found & GANN accepted */
2628		found = 1;
2629		break;
2630
2631	}
2632	if (found == 0) {
2633		/* this GANN is from a new mesh Gate add it to known table. */
2634		IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
2635		    "stored new GANN information, seq %u.", ie.gann_seq);
2636		gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
2637		    M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
2638		IEEE80211_ADDR_COPY(gr->gr_addr, ie.gann_addr);
2639		TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
2640	}
2641	gr->gr_lastseq = ie.gann_seq;
2642
2643	/* check if we have a path to this gate */
2644	rt_gate = mesh_rt_find_locked(ms, gr->gr_addr);
2645	if (rt_gate != NULL &&
2646	    rt_gate->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) {
2647		gr->gr_route = rt_gate;
2648		rt_gate->rt_flags |= IEEE80211_MESHRT_FLAGS_GATE;
2649	}
2650
2651	MESH_RT_UNLOCK(ms);
2652
2653	/* popagate only if decremented ttl >= 1 && forwarding is enabled */
2654	if ((ie.gann_ttl - 1) < 1 && !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
2655		return 0;
2656		pgann.gann_flags = ie.gann_flags; /* Reserved */
2657	pgann.gann_hopcount = ie.gann_hopcount + 1;
2658	pgann.gann_ttl = ie.gann_ttl - 1;
2659	IEEE80211_ADDR_COPY(pgann.gann_addr, ie.gann_addr);
2660	pgann.gann_seq = ie.gann_seq;
2661	pgann.gann_interval = ie.gann_interval;
2662
2663	IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
2664	    "%s", "propagate GANN");
2665
2666	ieee80211_send_action(vap->iv_bss, IEEE80211_ACTION_CAT_MESH,
2667	    IEEE80211_ACTION_MESH_GANN, &pgann);
2668
2669	return 0;
2670}
2671
2672static int
2673mesh_send_action(struct ieee80211_node *ni,
2674    const uint8_t sa[IEEE80211_ADDR_LEN],
2675    const uint8_t da[IEEE80211_ADDR_LEN],
2676    struct mbuf *m)
2677{
2678	struct ieee80211vap *vap = ni->ni_vap;
2679	struct ieee80211com *ic = ni->ni_ic;
2680	struct ieee80211_bpf_params params;
2681	struct ieee80211_frame *wh;
2682	int ret;
2683
2684	KASSERT(ni != NULL, ("null node"));
2685
2686	if (vap->iv_state == IEEE80211_S_CAC) {
2687		IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
2688		    "block %s frame in CAC state", "Mesh action");
2689		vap->iv_stats.is_tx_badstate++;
2690		ieee80211_free_node(ni);
2691		m_freem(m);
2692		return EIO;		/* XXX */
2693	}
2694
2695	M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
2696	if (m == NULL) {
2697		ieee80211_free_node(ni);
2698		return ENOMEM;
2699	}
2700
2701	IEEE80211_TX_LOCK(ic);
2702	wh = mtod(m, struct ieee80211_frame *);
2703	ieee80211_send_setup(ni, m,
2704	     IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
2705	     IEEE80211_NONQOS_TID, sa, da, sa);
2706	m->m_flags |= M_ENCAP;		/* mark encapsulated */
2707
2708	memset(&params, 0, sizeof(params));
2709	params.ibp_pri = WME_AC_VO;
2710	params.ibp_rate0 = ni->ni_txparms->mgmtrate;
2711	if (IEEE80211_IS_MULTICAST(da))
2712		params.ibp_try0 = 1;
2713	else
2714		params.ibp_try0 = ni->ni_txparms->maxretry;
2715	params.ibp_power = ni->ni_txpower;
2716
2717	IEEE80211_NODE_STAT(ni, tx_mgmt);
2718
2719	ret = ieee80211_raw_output(vap, ni, m, &params);
2720	IEEE80211_TX_UNLOCK(ic);
2721	return (ret);
2722}
2723
2724#define	ADDSHORT(frm, v) do {			\
2725	frm[0] = (v) & 0xff;			\
2726	frm[1] = (v) >> 8;			\
2727	frm += 2;				\
2728} while (0)
2729#define	ADDWORD(frm, v) do {			\
2730	frm[0] = (v) & 0xff;			\
2731	frm[1] = ((v) >> 8) & 0xff;		\
2732	frm[2] = ((v) >> 16) & 0xff;		\
2733	frm[3] = ((v) >> 24) & 0xff;		\
2734	frm += 4;				\
2735} while (0)
2736
2737static int
2738mesh_send_action_meshpeering_open(struct ieee80211_node *ni,
2739	int category, int action, void *args0)
2740{
2741	struct ieee80211vap *vap = ni->ni_vap;
2742	struct ieee80211com *ic = ni->ni_ic;
2743	uint16_t *args = args0;
2744	const struct ieee80211_rateset *rs;
2745	struct mbuf *m;
2746	uint8_t *frm;
2747
2748	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2749	    "send PEER OPEN action: localid 0x%x", args[0]);
2750
2751	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2752	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2753	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2754	ieee80211_ref_node(ni);
2755
2756	m = ieee80211_getmgtframe(&frm,
2757	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2758	    sizeof(uint16_t)	/* action+category */
2759	    + sizeof(uint16_t)	/* capabilites */
2760	    + 2 + IEEE80211_RATE_SIZE
2761	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2762	    + 2 + IEEE80211_MESHID_LEN
2763	    + sizeof(struct ieee80211_meshconf_ie)
2764	    + sizeof(struct ieee80211_meshpeer_ie)
2765	);
2766	if (m != NULL) {
2767		/*
2768		 * mesh peer open action frame format:
2769		 *   [1] category
2770		 *   [1] action
2771		 *   [2] capabilities
2772		 *   [tlv] rates
2773		 *   [tlv] xrates
2774		 *   [tlv] mesh id
2775		 *   [tlv] mesh conf
2776		 *   [tlv] mesh peer link mgmt
2777		 */
2778		*frm++ = category;
2779		*frm++ = action;
2780		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
2781		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
2782		frm = ieee80211_add_rates(frm, rs);
2783		frm = ieee80211_add_xrates(frm, rs);
2784		frm = ieee80211_add_meshid(frm, vap);
2785		frm = ieee80211_add_meshconf(frm, vap);
2786		frm = ieee80211_add_meshpeer(frm, IEEE80211_ACTION_MESHPEERING_OPEN,
2787		    args[0], 0, 0);
2788		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2789		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
2790	} else {
2791		vap->iv_stats.is_tx_nobuf++;
2792		ieee80211_free_node(ni);
2793		return ENOMEM;
2794	}
2795}
2796
2797static int
2798mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni,
2799	int category, int action, void *args0)
2800{
2801	struct ieee80211vap *vap = ni->ni_vap;
2802	struct ieee80211com *ic = ni->ni_ic;
2803	uint16_t *args = args0;
2804	const struct ieee80211_rateset *rs;
2805	struct mbuf *m;
2806	uint8_t *frm;
2807
2808	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2809	    "send PEER CONFIRM action: localid 0x%x, peerid 0x%x",
2810	    args[0], args[1]);
2811
2812	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2813	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2814	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2815	ieee80211_ref_node(ni);
2816
2817	m = ieee80211_getmgtframe(&frm,
2818	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2819	    sizeof(uint16_t)	/* action+category */
2820	    + sizeof(uint16_t)	/* capabilites */
2821	    + sizeof(uint16_t)	/* status code */
2822	    + sizeof(uint16_t)	/* AID */
2823	    + 2 + IEEE80211_RATE_SIZE
2824	    + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
2825	    + 2 + IEEE80211_MESHID_LEN
2826	    + sizeof(struct ieee80211_meshconf_ie)
2827	    + sizeof(struct ieee80211_meshpeer_ie)
2828	);
2829	if (m != NULL) {
2830		/*
2831		 * mesh peer confirm action frame format:
2832		 *   [1] category
2833		 *   [1] action
2834		 *   [2] capabilities
2835		 *   [2] status code
2836		 *   [2] association id (peer ID)
2837		 *   [tlv] rates
2838		 *   [tlv] xrates
2839		 *   [tlv] mesh id
2840		 *   [tlv] mesh conf
2841		 *   [tlv] mesh peer link mgmt
2842		 */
2843		*frm++ = category;
2844		*frm++ = action;
2845		ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
2846		ADDSHORT(frm, 0);		/* status code */
2847		ADDSHORT(frm, args[1]);		/* AID */
2848		rs = ieee80211_get_suprates(ic, ic->ic_curchan);
2849		frm = ieee80211_add_rates(frm, rs);
2850		frm = ieee80211_add_xrates(frm, rs);
2851		frm = ieee80211_add_meshid(frm, vap);
2852		frm = ieee80211_add_meshconf(frm, vap);
2853		frm = ieee80211_add_meshpeer(frm,
2854		    IEEE80211_ACTION_MESHPEERING_CONFIRM,
2855		    args[0], args[1], 0);
2856		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2857		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
2858	} else {
2859		vap->iv_stats.is_tx_nobuf++;
2860		ieee80211_free_node(ni);
2861		return ENOMEM;
2862	}
2863}
2864
2865static int
2866mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
2867	int category, int action, void *args0)
2868{
2869	struct ieee80211vap *vap = ni->ni_vap;
2870	struct ieee80211com *ic = ni->ni_ic;
2871	uint16_t *args = args0;
2872	struct mbuf *m;
2873	uint8_t *frm;
2874
2875	IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
2876	    "send PEER CLOSE action: localid 0x%x, peerid 0x%x reason %d",
2877	    args[0], args[1], args[2]);
2878
2879	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2880	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2881	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2882	ieee80211_ref_node(ni);
2883
2884	m = ieee80211_getmgtframe(&frm,
2885	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2886	    sizeof(uint16_t)	/* action+category */
2887	    + sizeof(uint16_t)	/* reason code */
2888	    + 2 + IEEE80211_MESHID_LEN
2889	    + sizeof(struct ieee80211_meshpeer_ie)
2890	);
2891	if (m != NULL) {
2892		/*
2893		 * mesh peer close action frame format:
2894		 *   [1] category
2895		 *   [1] action
2896		 *   [tlv] mesh id
2897		 *   [tlv] mesh peer link mgmt
2898		 */
2899		*frm++ = category;
2900		*frm++ = action;
2901		frm = ieee80211_add_meshid(frm, vap);
2902		frm = ieee80211_add_meshpeer(frm,
2903		    IEEE80211_ACTION_MESHPEERING_CLOSE,
2904		    args[0], args[1], args[2]);
2905		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2906		return mesh_send_action(ni, vap->iv_myaddr, ni->ni_macaddr, m);
2907	} else {
2908		vap->iv_stats.is_tx_nobuf++;
2909		ieee80211_free_node(ni);
2910		return ENOMEM;
2911	}
2912}
2913
2914static int
2915mesh_send_action_meshlmetric(struct ieee80211_node *ni,
2916	int category, int action, void *arg0)
2917{
2918	struct ieee80211vap *vap = ni->ni_vap;
2919	struct ieee80211com *ic = ni->ni_ic;
2920	struct ieee80211_meshlmetric_ie *ie = arg0;
2921	struct mbuf *m;
2922	uint8_t *frm;
2923
2924	if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
2925		IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2926		    ni, "%s", "send LINK METRIC REQUEST action");
2927	} else {
2928		IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
2929		    ni, "send LINK METRIC REPLY action: metric 0x%x",
2930		    ie->lm_metric);
2931	}
2932	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2933	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2934	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2935	ieee80211_ref_node(ni);
2936
2937	m = ieee80211_getmgtframe(&frm,
2938	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2939	    sizeof(uint16_t) +	/* action+category */
2940	    sizeof(struct ieee80211_meshlmetric_ie)
2941	);
2942	if (m != NULL) {
2943		/*
2944		 * mesh link metric
2945		 *   [1] category
2946		 *   [1] action
2947		 *   [tlv] mesh link metric
2948		 */
2949		*frm++ = category;
2950		*frm++ = action;
2951		frm = ieee80211_add_meshlmetric(frm,
2952		    ie->lm_flags, ie->lm_metric);
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_meshgate(struct ieee80211_node *ni,
2964	int category, int action, void *arg0)
2965{
2966	struct ieee80211vap *vap = ni->ni_vap;
2967	struct ieee80211com *ic = ni->ni_ic;
2968	struct ieee80211_meshgann_ie *ie = arg0;
2969	struct mbuf *m;
2970	uint8_t *frm;
2971
2972	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2973	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2974	    ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2975	ieee80211_ref_node(ni);
2976
2977	m = ieee80211_getmgtframe(&frm,
2978	    ic->ic_headroom + sizeof(struct ieee80211_frame),
2979	    sizeof(uint16_t) +	/* action+category */
2980	    IEEE80211_MESHGANN_BASE_SZ
2981	);
2982	if (m != NULL) {
2983		/*
2984		 * mesh link metric
2985		 *   [1] category
2986		 *   [1] action
2987		 *   [tlv] mesh gate annoucement
2988		 */
2989		*frm++ = category;
2990		*frm++ = action;
2991		frm = ieee80211_add_meshgate(frm, ie);
2992		m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2993		return mesh_send_action(ni, vap->iv_myaddr, broadcastaddr, m);
2994	} else {
2995		vap->iv_stats.is_tx_nobuf++;
2996		ieee80211_free_node(ni);
2997		return ENOMEM;
2998	}
2999}
3000
3001static void
3002mesh_peer_timeout_setup(struct ieee80211_node *ni)
3003{
3004	switch (ni->ni_mlstate) {
3005	case IEEE80211_NODE_MESH_HOLDING:
3006		ni->ni_mltval = ieee80211_mesh_holdingtimeout;
3007		break;
3008	case IEEE80211_NODE_MESH_CONFIRMRCV:
3009		ni->ni_mltval = ieee80211_mesh_confirmtimeout;
3010		break;
3011	case IEEE80211_NODE_MESH_IDLE:
3012		ni->ni_mltval = 0;
3013		break;
3014	default:
3015		ni->ni_mltval = ieee80211_mesh_retrytimeout;
3016		break;
3017	}
3018	if (ni->ni_mltval)
3019		callout_reset(&ni->ni_mltimer, ni->ni_mltval,
3020		    mesh_peer_timeout_cb, ni);
3021}
3022
3023/*
3024 * Same as above but backoffs timer statisically 50%.
3025 */
3026static void
3027mesh_peer_timeout_backoff(struct ieee80211_node *ni)
3028{
3029	uint32_t r;
3030
3031	r = arc4random();
3032	ni->ni_mltval += r % ni->ni_mltval;
3033	callout_reset(&ni->ni_mltimer, ni->ni_mltval, mesh_peer_timeout_cb,
3034	    ni);
3035}
3036
3037static __inline void
3038mesh_peer_timeout_stop(struct ieee80211_node *ni)
3039{
3040	callout_drain(&ni->ni_mltimer);
3041}
3042
3043static void
3044mesh_peer_backoff_cb(void *arg)
3045{
3046	struct ieee80211_node *ni = (struct ieee80211_node *)arg;
3047
3048	/* After backoff timeout, try to peer automatically again. */
3049	ni->ni_mlhcnt = 0;
3050}
3051
3052/*
3053 * Mesh Peer Link Management FSM timeout handling.
3054 */
3055static void
3056mesh_peer_timeout_cb(void *arg)
3057{
3058	struct ieee80211_node *ni = (struct ieee80211_node *)arg;
3059	uint16_t args[3];
3060
3061	IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_MESH,
3062	    ni, "mesh link timeout, state %d, retry counter %d",
3063	    ni->ni_mlstate, ni->ni_mlrcnt);
3064
3065	switch (ni->ni_mlstate) {
3066	case IEEE80211_NODE_MESH_IDLE:
3067	case IEEE80211_NODE_MESH_ESTABLISHED:
3068		break;
3069	case IEEE80211_NODE_MESH_OPENSNT:
3070	case IEEE80211_NODE_MESH_OPENRCV:
3071		if (ni->ni_mlrcnt == ieee80211_mesh_maxretries) {
3072			args[0] = ni->ni_mlpid;
3073			args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
3074			ieee80211_send_action(ni,
3075			    IEEE80211_ACTION_CAT_SELF_PROT,
3076			    IEEE80211_ACTION_MESHPEERING_CLOSE, args);
3077			ni->ni_mlrcnt = 0;
3078			mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
3079			mesh_peer_timeout_setup(ni);
3080		} else {
3081			args[0] = ni->ni_mlpid;
3082			ieee80211_send_action(ni,
3083			    IEEE80211_ACTION_CAT_SELF_PROT,
3084			    IEEE80211_ACTION_MESHPEERING_OPEN, args);
3085			ni->ni_mlrcnt++;
3086			mesh_peer_timeout_backoff(ni);
3087		}
3088		break;
3089	case IEEE80211_NODE_MESH_CONFIRMRCV:
3090		args[0] = ni->ni_mlpid;
3091		args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT;
3092		ieee80211_send_action(ni,
3093		    IEEE80211_ACTION_CAT_SELF_PROT,
3094		    IEEE80211_ACTION_MESHPEERING_CLOSE, args);
3095		mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING);
3096		mesh_peer_timeout_setup(ni);
3097		break;
3098	case IEEE80211_NODE_MESH_HOLDING:
3099		ni->ni_mlhcnt++;
3100		if (ni->ni_mlhcnt >= ieee80211_mesh_maxholding)
3101			callout_reset(&ni->ni_mlhtimer,
3102			    ieee80211_mesh_backofftimeout,
3103			    mesh_peer_backoff_cb, ni);
3104		mesh_linkchange(ni, IEEE80211_NODE_MESH_IDLE);
3105		break;
3106	}
3107}
3108
3109static int
3110mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie)
3111{
3112	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3113
3114	if (ie == NULL || ie[1] != ms->ms_idlen)
3115		return 1;
3116	return memcmp(ms->ms_id, ie + 2, ms->ms_idlen);
3117}
3118
3119/*
3120 * Check if we are using the same algorithms for this mesh.
3121 */
3122static int
3123mesh_verify_meshconf(struct ieee80211vap *vap, const uint8_t *ie)
3124{
3125	const struct ieee80211_meshconf_ie *meshconf =
3126	    (const struct ieee80211_meshconf_ie *) ie;
3127	const struct ieee80211_mesh_state *ms = vap->iv_mesh;
3128
3129	if (meshconf == NULL)
3130		return 1;
3131	if (meshconf->conf_pselid != ms->ms_ppath->mpp_ie) {
3132		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3133		    "unknown path selection algorithm: 0x%x\n",
3134		    meshconf->conf_pselid);
3135		return 1;
3136	}
3137	if (meshconf->conf_pmetid != ms->ms_pmetric->mpm_ie) {
3138		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3139		    "unknown path metric algorithm: 0x%x\n",
3140		    meshconf->conf_pmetid);
3141		return 1;
3142	}
3143	if (meshconf->conf_ccid != 0) {
3144		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3145		    "unknown congestion control algorithm: 0x%x\n",
3146		    meshconf->conf_ccid);
3147		return 1;
3148	}
3149	if (meshconf->conf_syncid != IEEE80211_MESHCONF_SYNC_NEIGHOFF) {
3150		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3151		    "unknown sync algorithm: 0x%x\n",
3152		    meshconf->conf_syncid);
3153		return 1;
3154	}
3155	if (meshconf->conf_authid != 0) {
3156		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3157		    "unknown auth auth algorithm: 0x%x\n",
3158		    meshconf->conf_pselid);
3159		return 1;
3160	}
3161	/* Not accepting peers */
3162	if (!(meshconf->conf_cap & IEEE80211_MESHCONF_CAP_AP)) {
3163		IEEE80211_DPRINTF(vap, IEEE80211_MSG_MESH,
3164		    "not accepting peers: 0x%x\n", meshconf->conf_cap);
3165		return 1;
3166	}
3167	return 0;
3168}
3169
3170static int
3171mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
3172    const uint8_t *ie)
3173{
3174	const struct ieee80211_meshpeer_ie *meshpeer =
3175	    (const struct ieee80211_meshpeer_ie *) ie;
3176
3177	if (meshpeer == NULL ||
3178	    meshpeer->peer_len < IEEE80211_MPM_BASE_SZ ||
3179	    meshpeer->peer_len > IEEE80211_MPM_MAX_SZ)
3180		return 1;
3181	if (meshpeer->peer_proto != IEEE80211_MPPID_MPM) {
3182		IEEE80211_DPRINTF(vap,
3183		    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
3184		    "Only MPM protocol is supported (proto: 0x%02X)",
3185		    meshpeer->peer_proto);
3186		return 1;
3187	}
3188	switch (subtype) {
3189	case IEEE80211_ACTION_MESHPEERING_OPEN:
3190		if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ)
3191			return 1;
3192		break;
3193	case IEEE80211_ACTION_MESHPEERING_CONFIRM:
3194		if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2)
3195			return 1;
3196		break;
3197	case IEEE80211_ACTION_MESHPEERING_CLOSE:
3198		if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2)
3199			return 1;
3200		if (meshpeer->peer_len == (IEEE80211_MPM_BASE_SZ + 2) &&
3201		    meshpeer->peer_linkid != 0)
3202			return 1;
3203		if (meshpeer->peer_rcode == 0)
3204			return 1;
3205		break;
3206	}
3207	return 0;
3208}
3209
3210/*
3211 * Add a Mesh ID IE to a frame.
3212 */
3213uint8_t *
3214ieee80211_add_meshid(uint8_t *frm, struct ieee80211vap *vap)
3215{
3216	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3217
3218	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a mbss vap"));
3219
3220	*frm++ = IEEE80211_ELEMID_MESHID;
3221	*frm++ = ms->ms_idlen;
3222	memcpy(frm, ms->ms_id, ms->ms_idlen);
3223	return frm + ms->ms_idlen;
3224}
3225
3226/*
3227 * Add a Mesh Configuration IE to a frame.
3228 * For now just use HWMP routing, Airtime link metric, Null Congestion
3229 * Signaling, Null Sync Protocol and Null Authentication.
3230 */
3231uint8_t *
3232ieee80211_add_meshconf(uint8_t *frm, struct ieee80211vap *vap)
3233{
3234	const struct ieee80211_mesh_state *ms = vap->iv_mesh;
3235	uint16_t caps;
3236
3237	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
3238
3239	*frm++ = IEEE80211_ELEMID_MESHCONF;
3240	*frm++ = IEEE80211_MESH_CONF_SZ;
3241	*frm++ = ms->ms_ppath->mpp_ie;		/* path selection */
3242	*frm++ = ms->ms_pmetric->mpm_ie;	/* link metric */
3243	*frm++ = IEEE80211_MESHCONF_CC_DISABLED;
3244	*frm++ = IEEE80211_MESHCONF_SYNC_NEIGHOFF;
3245	*frm++ = IEEE80211_MESHCONF_AUTH_DISABLED;
3246	/* NB: set the number of neighbors before the rest */
3247	*frm = (ms->ms_neighbors > IEEE80211_MESH_MAX_NEIGHBORS ?
3248	    IEEE80211_MESH_MAX_NEIGHBORS : ms->ms_neighbors) << 1;
3249	if (ms->ms_flags & IEEE80211_MESHFLAGS_GATE)
3250		*frm |= IEEE80211_MESHCONF_FORM_GATE;
3251	frm += 1;
3252	caps = 0;
3253	if (ms->ms_flags & IEEE80211_MESHFLAGS_AP)
3254		caps |= IEEE80211_MESHCONF_CAP_AP;
3255	if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)
3256		caps |= IEEE80211_MESHCONF_CAP_FWRD;
3257	*frm++ = caps;
3258	return frm;
3259}
3260
3261/*
3262 * Add a Mesh Peer Management IE to a frame.
3263 */
3264uint8_t *
3265ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
3266    uint16_t peerid, uint16_t reason)
3267{
3268
3269	KASSERT(localid != 0, ("localid == 0"));
3270
3271	*frm++ = IEEE80211_ELEMID_MESHPEER;
3272	switch (subtype) {
3273	case IEEE80211_ACTION_MESHPEERING_OPEN:
3274		*frm++ = IEEE80211_MPM_BASE_SZ;		/* length */
3275		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3276		ADDSHORT(frm, localid);			/* local ID */
3277		break;
3278	case IEEE80211_ACTION_MESHPEERING_CONFIRM:
3279		KASSERT(peerid != 0, ("sending peer confirm without peer id"));
3280		*frm++ = IEEE80211_MPM_BASE_SZ + 2;	/* length */
3281		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3282		ADDSHORT(frm, localid);			/* local ID */
3283		ADDSHORT(frm, peerid);			/* peer ID */
3284		break;
3285	case IEEE80211_ACTION_MESHPEERING_CLOSE:
3286		if (peerid)
3287			*frm++ = IEEE80211_MPM_MAX_SZ;	/* length */
3288		else
3289			*frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
3290		ADDSHORT(frm, IEEE80211_MPPID_MPM);	/* proto */
3291		ADDSHORT(frm, localid);	/* local ID */
3292		if (peerid)
3293			ADDSHORT(frm, peerid);	/* peer ID */
3294		ADDSHORT(frm, reason);
3295		break;
3296	}
3297	return frm;
3298}
3299
3300/*
3301 * Compute an Airtime Link Metric for the link with this node.
3302 *
3303 * Based on Draft 3.0 spec (11B.10, p.149).
3304 */
3305/*
3306 * Max 802.11s overhead.
3307 */
3308#define IEEE80211_MESH_MAXOVERHEAD \
3309	(sizeof(struct ieee80211_qosframe_addr4) \
3310	 + sizeof(struct ieee80211_meshcntl_ae10) \
3311	+ sizeof(struct llc) \
3312	+ IEEE80211_ADDR_LEN \
3313	+ IEEE80211_WEP_IVLEN \
3314	+ IEEE80211_WEP_KIDLEN \
3315	+ IEEE80211_WEP_CRCLEN \
3316	+ IEEE80211_WEP_MICLEN \
3317	+ IEEE80211_CRC_LEN)
3318uint32_t
3319mesh_airtime_calc(struct ieee80211_node *ni)
3320{
3321#define M_BITS 8
3322#define S_FACTOR (2 * M_BITS)
3323	struct ieee80211com *ic = ni->ni_ic;
3324	struct ifnet *ifp = ni->ni_vap->iv_ifp;
3325	const static int nbits = 8192 << M_BITS;
3326	uint32_t overhead, rate, errrate;
3327	uint64_t res;
3328
3329	/* Time to transmit a frame */
3330	rate = ni->ni_txrate;
3331	overhead = ieee80211_compute_duration(ic->ic_rt,
3332	    ifp->if_mtu + IEEE80211_MESH_MAXOVERHEAD, rate, 0) << M_BITS;
3333	/* Error rate in percentage */
3334	/* XXX assuming small failures are ok */
3335	errrate = (((ifp->if_oerrors +
3336	    ifp->if_ierrors) / 100) << M_BITS) / 100;
3337	res = (overhead + (nbits / rate)) *
3338	    ((1 << S_FACTOR) / ((1 << M_BITS) - errrate));
3339
3340	return (uint32_t)(res >> S_FACTOR);
3341#undef M_BITS
3342#undef S_FACTOR
3343}
3344
3345/*
3346 * Add a Mesh Link Metric report IE to a frame.
3347 */
3348uint8_t *
3349ieee80211_add_meshlmetric(uint8_t *frm, uint8_t flags, uint32_t metric)
3350{
3351	*frm++ = IEEE80211_ELEMID_MESHLINK;
3352	*frm++ = 5;
3353	*frm++ = flags;
3354	ADDWORD(frm, metric);
3355	return frm;
3356}
3357
3358/*
3359 * Add a Mesh Gate Announcement IE to a frame.
3360 */
3361uint8_t *
3362ieee80211_add_meshgate(uint8_t *frm, struct ieee80211_meshgann_ie *ie)
3363{
3364	*frm++ = IEEE80211_ELEMID_MESHGANN; /* ie */
3365	*frm++ = IEEE80211_MESHGANN_BASE_SZ; /* len */
3366	*frm++ = ie->gann_flags;
3367	*frm++ = ie->gann_hopcount;
3368	*frm++ = ie->gann_ttl;
3369	IEEE80211_ADDR_COPY(frm, ie->gann_addr);
3370	frm += 6;
3371	ADDWORD(frm, ie->gann_seq);
3372	ADDSHORT(frm, ie->gann_interval);
3373	return frm;
3374}
3375#undef ADDSHORT
3376#undef ADDWORD
3377
3378/*
3379 * Initialize any mesh-specific node state.
3380 */
3381void
3382ieee80211_mesh_node_init(struct ieee80211vap *vap, struct ieee80211_node *ni)
3383{
3384	ni->ni_flags |= IEEE80211_NODE_QOS;
3385	callout_init(&ni->ni_mltimer, CALLOUT_MPSAFE);
3386	callout_init(&ni->ni_mlhtimer, CALLOUT_MPSAFE);
3387}
3388
3389/*
3390 * Cleanup any mesh-specific node state.
3391 */
3392void
3393ieee80211_mesh_node_cleanup(struct ieee80211_node *ni)
3394{
3395	struct ieee80211vap *vap = ni->ni_vap;
3396	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3397
3398	callout_drain(&ni->ni_mltimer);
3399	callout_drain(&ni->ni_mlhtimer);
3400	/* NB: short-circuit callbacks after mesh_vdetach */
3401	if (vap->iv_mesh != NULL)
3402		ms->ms_ppath->mpp_peerdown(ni);
3403}
3404
3405void
3406ieee80211_parse_meshid(struct ieee80211_node *ni, const uint8_t *ie)
3407{
3408	ni->ni_meshidlen = ie[1];
3409	memcpy(ni->ni_meshid, ie + 2, ie[1]);
3410}
3411
3412/*
3413 * Setup mesh-specific node state on neighbor discovery.
3414 */
3415void
3416ieee80211_mesh_init_neighbor(struct ieee80211_node *ni,
3417	const struct ieee80211_frame *wh,
3418	const struct ieee80211_scanparams *sp)
3419{
3420	ieee80211_parse_meshid(ni, sp->meshid);
3421}
3422
3423void
3424ieee80211_mesh_update_beacon(struct ieee80211vap *vap,
3425	struct ieee80211_beacon_offsets *bo)
3426{
3427	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
3428
3429	if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) {
3430		(void)ieee80211_add_meshconf(bo->bo_meshconf, vap);
3431		clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF);
3432	}
3433}
3434
3435static int
3436mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
3437{
3438	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3439	uint8_t tmpmeshid[IEEE80211_NWID_LEN];
3440	struct ieee80211_mesh_route *rt;
3441	struct ieee80211req_mesh_route *imr;
3442	size_t len, off;
3443	uint8_t *p;
3444	int error;
3445
3446	if (vap->iv_opmode != IEEE80211_M_MBSS)
3447		return ENOSYS;
3448
3449	error = 0;
3450	switch (ireq->i_type) {
3451	case IEEE80211_IOC_MESH_ID:
3452		ireq->i_len = ms->ms_idlen;
3453		memcpy(tmpmeshid, ms->ms_id, ireq->i_len);
3454		error = copyout(tmpmeshid, ireq->i_data, ireq->i_len);
3455		break;
3456	case IEEE80211_IOC_MESH_AP:
3457		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_AP) != 0;
3458		break;
3459	case IEEE80211_IOC_MESH_FWRD:
3460		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) != 0;
3461		break;
3462	case IEEE80211_IOC_MESH_GATE:
3463		ireq->i_val = (ms->ms_flags & IEEE80211_MESHFLAGS_GATE) != 0;
3464		break;
3465	case IEEE80211_IOC_MESH_TTL:
3466		ireq->i_val = ms->ms_ttl;
3467		break;
3468	case IEEE80211_IOC_MESH_RTCMD:
3469		switch (ireq->i_val) {
3470		case IEEE80211_MESH_RTCMD_LIST:
3471			len = 0;
3472			MESH_RT_LOCK(ms);
3473			TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
3474				len += sizeof(*imr);
3475			}
3476			MESH_RT_UNLOCK(ms);
3477			if (len > ireq->i_len || ireq->i_len < sizeof(*imr)) {
3478				ireq->i_len = len;
3479				return ENOMEM;
3480			}
3481			ireq->i_len = len;
3482			/* XXX M_WAIT? */
3483			p = malloc(len, M_TEMP, M_NOWAIT | M_ZERO);
3484			if (p == NULL)
3485				return ENOMEM;
3486			off = 0;
3487			MESH_RT_LOCK(ms);
3488			TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
3489				if (off >= len)
3490					break;
3491				imr = (struct ieee80211req_mesh_route *)
3492				    (p + off);
3493				IEEE80211_ADDR_COPY(imr->imr_dest,
3494				    rt->rt_dest);
3495				IEEE80211_ADDR_COPY(imr->imr_nexthop,
3496				    rt->rt_nexthop);
3497				imr->imr_metric = rt->rt_metric;
3498				imr->imr_nhops = rt->rt_nhops;
3499				imr->imr_lifetime =
3500				    ieee80211_mesh_rt_update(rt, 0);
3501				imr->imr_lastmseq = rt->rt_lastmseq;
3502				imr->imr_flags = rt->rt_flags; /* last */
3503				off += sizeof(*imr);
3504			}
3505			MESH_RT_UNLOCK(ms);
3506			error = copyout(p, (uint8_t *)ireq->i_data,
3507			    ireq->i_len);
3508			free(p, M_TEMP);
3509			break;
3510		case IEEE80211_MESH_RTCMD_FLUSH:
3511		case IEEE80211_MESH_RTCMD_ADD:
3512		case IEEE80211_MESH_RTCMD_DELETE:
3513			return EINVAL;
3514		default:
3515			return ENOSYS;
3516		}
3517		break;
3518	case IEEE80211_IOC_MESH_PR_METRIC:
3519		len = strlen(ms->ms_pmetric->mpm_descr);
3520		if (ireq->i_len < len)
3521			return EINVAL;
3522		ireq->i_len = len;
3523		error = copyout(ms->ms_pmetric->mpm_descr,
3524		    (uint8_t *)ireq->i_data, len);
3525		break;
3526	case IEEE80211_IOC_MESH_PR_PATH:
3527		len = strlen(ms->ms_ppath->mpp_descr);
3528		if (ireq->i_len < len)
3529			return EINVAL;
3530		ireq->i_len = len;
3531		error = copyout(ms->ms_ppath->mpp_descr,
3532		    (uint8_t *)ireq->i_data, len);
3533		break;
3534	default:
3535		return ENOSYS;
3536	}
3537
3538	return error;
3539}
3540IEEE80211_IOCTL_GET(mesh, mesh_ioctl_get80211);
3541
3542static int
3543mesh_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
3544{
3545	struct ieee80211_mesh_state *ms = vap->iv_mesh;
3546	uint8_t tmpmeshid[IEEE80211_NWID_LEN];
3547	uint8_t tmpaddr[IEEE80211_ADDR_LEN];
3548	char tmpproto[IEEE80211_MESH_PROTO_DSZ];
3549	int error;
3550
3551	if (vap->iv_opmode != IEEE80211_M_MBSS)
3552		return ENOSYS;
3553
3554	error = 0;
3555	switch (ireq->i_type) {
3556	case IEEE80211_IOC_MESH_ID:
3557		if (ireq->i_val != 0 || ireq->i_len > IEEE80211_MESHID_LEN)
3558			return EINVAL;
3559		error = copyin(ireq->i_data, tmpmeshid, ireq->i_len);
3560		if (error != 0)
3561			break;
3562		memset(ms->ms_id, 0, IEEE80211_NWID_LEN);
3563		ms->ms_idlen = ireq->i_len;
3564		memcpy(ms->ms_id, tmpmeshid, ireq->i_len);
3565		error = ENETRESET;
3566		break;
3567	case IEEE80211_IOC_MESH_AP:
3568		if (ireq->i_val)
3569			ms->ms_flags |= IEEE80211_MESHFLAGS_AP;
3570		else
3571			ms->ms_flags &= ~IEEE80211_MESHFLAGS_AP;
3572		error = ENETRESET;
3573		break;
3574	case IEEE80211_IOC_MESH_FWRD:
3575		if (ireq->i_val)
3576			ms->ms_flags |= IEEE80211_MESHFLAGS_FWD;
3577		else
3578			ms->ms_flags &= ~IEEE80211_MESHFLAGS_FWD;
3579		mesh_gatemode_setup(vap);
3580		break;
3581	case IEEE80211_IOC_MESH_GATE:
3582		if (ireq->i_val)
3583			ms->ms_flags |= IEEE80211_MESHFLAGS_GATE;
3584		else
3585			ms->ms_flags &= ~IEEE80211_MESHFLAGS_GATE;
3586		break;
3587	case IEEE80211_IOC_MESH_TTL:
3588		ms->ms_ttl = (uint8_t) ireq->i_val;
3589		break;
3590	case IEEE80211_IOC_MESH_RTCMD:
3591		switch (ireq->i_val) {
3592		case IEEE80211_MESH_RTCMD_LIST:
3593			return EINVAL;
3594		case IEEE80211_MESH_RTCMD_FLUSH:
3595			ieee80211_mesh_rt_flush(vap);
3596			break;
3597		case IEEE80211_MESH_RTCMD_ADD:
3598			if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ireq->i_data) ||
3599			    IEEE80211_ADDR_EQ(broadcastaddr, ireq->i_data))
3600				return EINVAL;
3601			error = copyin(ireq->i_data, &tmpaddr,
3602			    IEEE80211_ADDR_LEN);
3603			if (error == 0)
3604				ieee80211_mesh_discover(vap, tmpaddr, NULL);
3605			break;
3606		case IEEE80211_MESH_RTCMD_DELETE:
3607			ieee80211_mesh_rt_del(vap, ireq->i_data);
3608			break;
3609		default:
3610			return ENOSYS;
3611		}
3612		break;
3613	case IEEE80211_IOC_MESH_PR_METRIC:
3614		error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto));
3615		if (error == 0) {
3616			error = mesh_select_proto_metric(vap, tmpproto);
3617			if (error == 0)
3618				error = ENETRESET;
3619		}
3620		break;
3621	case IEEE80211_IOC_MESH_PR_PATH:
3622		error = copyin(ireq->i_data, tmpproto, sizeof(tmpproto));
3623		if (error == 0) {
3624			error = mesh_select_proto_path(vap, tmpproto);
3625			if (error == 0)
3626				error = ENETRESET;
3627		}
3628		break;
3629	default:
3630		return ENOSYS;
3631	}
3632	return error;
3633}
3634IEEE80211_IOCTL_SET(mesh, mesh_ioctl_set80211);
3635