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