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