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