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