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