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