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