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