]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net80211/ieee80211_freebsd.c
net80211: Add framework for debugnet(4) support
[FreeBSD/FreeBSD.git] / sys / net80211 / ieee80211_freebsd.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2003-2009 Sam Leffler, Errno Consulting
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 /*
32  * IEEE 802.11 support (FreeBSD-specific code)
33  */
34 #include "opt_wlan.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h> 
38 #include <sys/eventhandler.h>
39 #include <sys/kernel.h>
40 #include <sys/linker.h>
41 #include <sys/malloc.h>
42 #include <sys/mbuf.h>   
43 #include <sys/module.h>
44 #include <sys/proc.h>
45 #include <sys/sysctl.h>
46
47 #include <sys/socket.h>
48
49 #include <net/bpf.h>
50 #include <net/if.h>
51 #include <net/if_var.h>
52 #include <net/if_dl.h>
53 #include <net/if_clone.h>
54 #include <net/if_media.h>
55 #include <net/if_types.h>
56 #include <net/ethernet.h>
57 #include <net/route.h>
58 #include <net/vnet.h>
59
60 #include <net80211/ieee80211_var.h>
61 #include <net80211/ieee80211_input.h>
62
63 DEBUGNET_DEFINE(ieee80211);
64 SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
65     "IEEE 80211 parameters");
66
67 #ifdef IEEE80211_DEBUG
68 static int      ieee80211_debug = 0;
69 SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
70             0, "debugging printfs");
71 #endif
72
73 static const char wlanname[] = "wlan";
74 static struct if_clone *wlan_cloner;
75
76 static int
77 wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
78 {
79         struct ieee80211_clone_params cp;
80         struct ieee80211vap *vap;
81         struct ieee80211com *ic;
82         int error;
83
84         error = copyin(params, &cp, sizeof(cp));
85         if (error)
86                 return error;
87         ic = ieee80211_find_com(cp.icp_parent);
88         if (ic == NULL)
89                 return ENXIO;
90         if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
91                 ic_printf(ic, "%s: invalid opmode %d\n", __func__,
92                     cp.icp_opmode);
93                 return EINVAL;
94         }
95         if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
96                 ic_printf(ic, "%s mode not supported\n",
97                     ieee80211_opmode_name[cp.icp_opmode]);
98                 return EOPNOTSUPP;
99         }
100         if ((cp.icp_flags & IEEE80211_CLONE_TDMA) &&
101 #ifdef IEEE80211_SUPPORT_TDMA
102             (ic->ic_caps & IEEE80211_C_TDMA) == 0
103 #else
104             (1)
105 #endif
106         ) {
107                 ic_printf(ic, "TDMA not supported\n");
108                 return EOPNOTSUPP;
109         }
110         vap = ic->ic_vap_create(ic, wlanname, unit,
111                         cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
112                         cp.icp_flags & IEEE80211_CLONE_MACADDR ?
113                             cp.icp_macaddr : ic->ic_macaddr);
114
115         if (vap == NULL)
116                 return (EIO);
117
118 #ifdef DEBUGNET
119         if (ic->ic_debugnet_meth != NULL)
120                 DEBUGNET_SET(vap->iv_ifp, ieee80211);
121 #endif
122         return (0);
123 }
124
125 static void
126 wlan_clone_destroy(struct ifnet *ifp)
127 {
128         struct ieee80211vap *vap = ifp->if_softc;
129         struct ieee80211com *ic = vap->iv_ic;
130
131         ic->ic_vap_delete(vap);
132 }
133
134 void
135 ieee80211_vap_destroy(struct ieee80211vap *vap)
136 {
137         CURVNET_SET(vap->iv_ifp->if_vnet);
138         if_clone_destroyif(wlan_cloner, vap->iv_ifp);
139         CURVNET_RESTORE();
140 }
141
142 int
143 ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS)
144 {
145         int msecs = ticks_to_msecs(*(int *)arg1);
146         int error;
147
148         error = sysctl_handle_int(oidp, &msecs, 0, req);
149         if (error || !req->newptr)
150                 return error;
151         *(int *)arg1 = msecs_to_ticks(msecs);
152         return 0;
153 }
154
155 static int
156 ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS)
157 {
158         int inact = (*(int *)arg1) * IEEE80211_INACT_WAIT;
159         int error;
160
161         error = sysctl_handle_int(oidp, &inact, 0, req);
162         if (error || !req->newptr)
163                 return error;
164         *(int *)arg1 = inact / IEEE80211_INACT_WAIT;
165         return 0;
166 }
167
168 static int
169 ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
170 {
171         struct ieee80211com *ic = arg1;
172
173         return SYSCTL_OUT_STR(req, ic->ic_name);
174 }
175
176 static int
177 ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS)
178 {
179         struct ieee80211com *ic = arg1;
180         int t = 0, error;
181
182         error = sysctl_handle_int(oidp, &t, 0, req);
183         if (error || !req->newptr)
184                 return error;
185         IEEE80211_LOCK(ic);
186         ieee80211_dfs_notify_radar(ic, ic->ic_curchan);
187         IEEE80211_UNLOCK(ic);
188         return 0;
189 }
190
191 /*
192  * For now, just restart everything.
193  *
194  * Later on, it'd be nice to have a separate VAP restart to
195  * full-device restart.
196  */
197 static int
198 ieee80211_sysctl_vap_restart(SYSCTL_HANDLER_ARGS)
199 {
200         struct ieee80211vap *vap = arg1;
201         int t = 0, error;
202
203         error = sysctl_handle_int(oidp, &t, 0, req);
204         if (error || !req->newptr)
205                 return error;
206
207         ieee80211_restart_all(vap->iv_ic);
208         return 0;
209 }
210
211 void
212 ieee80211_sysctl_attach(struct ieee80211com *ic)
213 {
214 }
215
216 void
217 ieee80211_sysctl_detach(struct ieee80211com *ic)
218 {
219 }
220
221 void
222 ieee80211_sysctl_vattach(struct ieee80211vap *vap)
223 {
224         struct ifnet *ifp = vap->iv_ifp;
225         struct sysctl_ctx_list *ctx;
226         struct sysctl_oid *oid;
227         char num[14];                   /* sufficient for 32 bits */
228
229         ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list),
230                 M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
231         if (ctx == NULL) {
232                 if_printf(ifp, "%s: cannot allocate sysctl context!\n",
233                         __func__);
234                 return;
235         }
236         sysctl_ctx_init(ctx);
237         snprintf(num, sizeof(num), "%u", ifp->if_dunit);
238         oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan),
239             OID_AUTO, num, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "");
240         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
241             "%parent", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
242             vap->iv_ic, 0, ieee80211_sysctl_parent, "A", "parent device");
243         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
244                 "driver_caps", CTLFLAG_RW, &vap->iv_caps, 0,
245                 "driver capabilities");
246 #ifdef IEEE80211_DEBUG
247         vap->iv_debug = ieee80211_debug;
248         SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
249                 "debug", CTLFLAG_RW, &vap->iv_debug, 0,
250                 "control debugging printfs");
251 #endif
252         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
253                 "bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0,
254                 "consecutive beacon misses before scanning");
255         /* XXX inherit from tunables */
256         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
257             "inact_run", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
258             &vap->iv_inact_run, 0, ieee80211_sysctl_inact, "I",
259             "station inactivity timeout (sec)");
260         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
261             "inact_probe", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
262             &vap->iv_inact_probe, 0, ieee80211_sysctl_inact, "I",
263             "station inactivity probe timeout (sec)");
264         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
265             "inact_auth", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
266             &vap->iv_inact_auth, 0, ieee80211_sysctl_inact, "I",
267             "station authentication timeout (sec)");
268         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
269             "inact_init", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
270             &vap->iv_inact_init, 0, ieee80211_sysctl_inact, "I",
271             "station initial state timeout (sec)");
272         if (vap->iv_htcaps & IEEE80211_HTC_HT) {
273                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
274                         "ampdu_mintraffic_bk", CTLFLAG_RW,
275                         &vap->iv_ampdu_mintraffic[WME_AC_BK], 0,
276                         "BK traffic tx aggr threshold (pps)");
277                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
278                         "ampdu_mintraffic_be", CTLFLAG_RW,
279                         &vap->iv_ampdu_mintraffic[WME_AC_BE], 0,
280                         "BE traffic tx aggr threshold (pps)");
281                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
282                         "ampdu_mintraffic_vo", CTLFLAG_RW,
283                         &vap->iv_ampdu_mintraffic[WME_AC_VO], 0,
284                         "VO traffic tx aggr threshold (pps)");
285                 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
286                         "ampdu_mintraffic_vi", CTLFLAG_RW,
287                         &vap->iv_ampdu_mintraffic[WME_AC_VI], 0,
288                         "VI traffic tx aggr threshold (pps)");
289         }
290
291         SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
292             "force_restart", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
293             vap, 0, ieee80211_sysctl_vap_restart, "I", "force a VAP restart");
294
295         if (vap->iv_caps & IEEE80211_C_DFS) {
296                 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
297                     "radar", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
298                     vap->iv_ic, 0, ieee80211_sysctl_radar, "I",
299                     "simulate radar event");
300         }
301         vap->iv_sysctl = ctx;
302         vap->iv_oid = oid;
303 }
304
305 void
306 ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
307 {
308
309         if (vap->iv_sysctl != NULL) {
310                 sysctl_ctx_free(vap->iv_sysctl);
311                 IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF);
312                 vap->iv_sysctl = NULL;
313         }
314 }
315
316 #define MS(_v, _f)      (((_v) & _f##_M) >> _f##_S)
317 int
318 ieee80211_com_vincref(struct ieee80211vap *vap)
319 {
320         uint32_t ostate;
321
322         ostate = atomic_fetchadd_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
323
324         if (ostate & IEEE80211_COM_DETACHED) {
325                 atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
326                 return (ENETDOWN);
327         }
328
329         if (MS(ostate, IEEE80211_COM_REF) == IEEE80211_COM_REF_MAX) {
330                 atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD);
331                 return (EOVERFLOW);
332         }
333
334         return (0);
335 }
336
337 void
338 ieee80211_com_vdecref(struct ieee80211vap *vap)
339 {
340         uint32_t ostate;
341
342         ostate = atomic_fetchadd_32(&vap->iv_com_state, -IEEE80211_COM_REF_ADD);
343
344         KASSERT(MS(ostate, IEEE80211_COM_REF) != 0,
345             ("com reference counter underflow"));
346
347         (void) ostate;
348 }
349
350 void
351 ieee80211_com_vdetach(struct ieee80211vap *vap)
352 {
353         int sleep_time;
354
355         sleep_time = msecs_to_ticks(250);
356         atomic_set_32(&vap->iv_com_state, IEEE80211_COM_DETACHED);
357         while (MS(atomic_load_32(&vap->iv_com_state), IEEE80211_COM_REF) != 0)
358                 pause("comref", sleep_time);
359 }
360 #undef  MS
361
362 int
363 ieee80211_node_dectestref(struct ieee80211_node *ni)
364 {
365         /* XXX need equivalent of atomic_dec_and_test */
366         atomic_subtract_int(&ni->ni_refcnt, 1);
367         return atomic_cmpset_int(&ni->ni_refcnt, 0, 1);
368 }
369
370 void
371 ieee80211_drain_ifq(struct ifqueue *ifq)
372 {
373         struct ieee80211_node *ni;
374         struct mbuf *m;
375
376         for (;;) {
377                 IF_DEQUEUE(ifq, m);
378                 if (m == NULL)
379                         break;
380
381                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
382                 KASSERT(ni != NULL, ("frame w/o node"));
383                 ieee80211_free_node(ni);
384                 m->m_pkthdr.rcvif = NULL;
385
386                 m_freem(m);
387         }
388 }
389
390 void
391 ieee80211_flush_ifq(struct ifqueue *ifq, struct ieee80211vap *vap)
392 {
393         struct ieee80211_node *ni;
394         struct mbuf *m, **mprev;
395
396         IF_LOCK(ifq);
397         mprev = &ifq->ifq_head;
398         while ((m = *mprev) != NULL) {
399                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
400                 if (ni != NULL && ni->ni_vap == vap) {
401                         *mprev = m->m_nextpkt;          /* remove from list */
402                         ifq->ifq_len--;
403
404                         m_freem(m);
405                         ieee80211_free_node(ni);        /* reclaim ref */
406                 } else
407                         mprev = &m->m_nextpkt;
408         }
409         /* recalculate tail ptr */
410         m = ifq->ifq_head;
411         for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt)
412                 ;
413         ifq->ifq_tail = m;
414         IF_UNLOCK(ifq);
415 }
416
417 /*
418  * As above, for mbufs allocated with m_gethdr/MGETHDR
419  * or initialized by M_COPY_PKTHDR.
420  */
421 #define MC_ALIGN(m, len)                                                \
422 do {                                                                    \
423         (m)->m_data += rounddown2(MCLBYTES - (len), sizeof(long));      \
424 } while (/* CONSTCOND */ 0)
425
426 /*
427  * Allocate and setup a management frame of the specified
428  * size.  We return the mbuf and a pointer to the start
429  * of the contiguous data area that's been reserved based
430  * on the packet length.  The data area is forced to 32-bit
431  * alignment and the buffer length to a multiple of 4 bytes.
432  * This is done mainly so beacon frames (that require this)
433  * can use this interface too.
434  */
435 struct mbuf *
436 ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen)
437 {
438         struct mbuf *m;
439         u_int len;
440
441         /*
442          * NB: we know the mbuf routines will align the data area
443          *     so we don't need to do anything special.
444          */
445         len = roundup2(headroom + pktlen, 4);
446         KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len));
447         if (len < MINCLSIZE) {
448                 m = m_gethdr(M_NOWAIT, MT_DATA);
449                 /*
450                  * Align the data in case additional headers are added.
451                  * This should only happen when a WEP header is added
452                  * which only happens for shared key authentication mgt
453                  * frames which all fit in MHLEN.
454                  */
455                 if (m != NULL)
456                         M_ALIGN(m, len);
457         } else {
458                 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
459                 if (m != NULL)
460                         MC_ALIGN(m, len);
461         }
462         if (m != NULL) {
463                 m->m_data += headroom;
464                 *frm = m->m_data;
465         }
466         return m;
467 }
468
469 #ifndef __NO_STRICT_ALIGNMENT
470 /*
471  * Re-align the payload in the mbuf.  This is mainly used (right now)
472  * to handle IP header alignment requirements on certain architectures.
473  */
474 struct mbuf *
475 ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
476 {
477         int pktlen, space;
478         struct mbuf *n;
479
480         pktlen = m->m_pkthdr.len;
481         space = pktlen + align;
482         if (space < MINCLSIZE)
483                 n = m_gethdr(M_NOWAIT, MT_DATA);
484         else {
485                 n = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
486                     space <= MCLBYTES ?     MCLBYTES :
487 #if MJUMPAGESIZE != MCLBYTES
488                     space <= MJUMPAGESIZE ? MJUMPAGESIZE :
489 #endif
490                     space <= MJUM9BYTES ?   MJUM9BYTES : MJUM16BYTES);
491         }
492         if (__predict_true(n != NULL)) {
493                 m_move_pkthdr(n, m);
494                 n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align);
495                 m_copydata(m, 0, pktlen, mtod(n, caddr_t));
496                 n->m_len = pktlen;
497         } else {
498                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
499                     mtod(m, const struct ieee80211_frame *), NULL,
500                     "%s", "no mbuf to realign");
501                 vap->iv_stats.is_rx_badalign++;
502         }
503         m_freem(m);
504         return n;
505 }
506 #endif /* !__NO_STRICT_ALIGNMENT */
507
508 int
509 ieee80211_add_callback(struct mbuf *m,
510         void (*func)(struct ieee80211_node *, void *, int), void *arg)
511 {
512         struct m_tag *mtag;
513         struct ieee80211_cb *cb;
514
515         mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK,
516                         sizeof(struct ieee80211_cb), M_NOWAIT);
517         if (mtag == NULL)
518                 return 0;
519
520         cb = (struct ieee80211_cb *)(mtag+1);
521         cb->func = func;
522         cb->arg = arg;
523         m_tag_prepend(m, mtag);
524         m->m_flags |= M_TXCB;
525         return 1;
526 }
527
528 int
529 ieee80211_add_xmit_params(struct mbuf *m,
530     const struct ieee80211_bpf_params *params)
531 {
532         struct m_tag *mtag;
533         struct ieee80211_tx_params *tx;
534
535         mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
536             sizeof(struct ieee80211_tx_params), M_NOWAIT);
537         if (mtag == NULL)
538                 return (0);
539
540         tx = (struct ieee80211_tx_params *)(mtag+1);
541         memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
542         m_tag_prepend(m, mtag);
543         return (1);
544 }
545
546 int
547 ieee80211_get_xmit_params(struct mbuf *m,
548     struct ieee80211_bpf_params *params)
549 {
550         struct m_tag *mtag;
551         struct ieee80211_tx_params *tx;
552
553         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
554             NULL);
555         if (mtag == NULL)
556                 return (-1);
557         tx = (struct ieee80211_tx_params *)(mtag + 1);
558         memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
559         return (0);
560 }
561
562 void
563 ieee80211_process_callback(struct ieee80211_node *ni,
564         struct mbuf *m, int status)
565 {
566         struct m_tag *mtag;
567
568         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL);
569         if (mtag != NULL) {
570                 struct ieee80211_cb *cb = (struct ieee80211_cb *)(mtag+1);
571                 cb->func(ni, cb->arg, status);
572         }
573 }
574
575 /*
576  * Add RX parameters to the given mbuf.
577  *
578  * Returns 1 if OK, 0 on error.
579  */
580 int
581 ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
582 {
583         struct m_tag *mtag;
584         struct ieee80211_rx_params *rx;
585
586         mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
587             sizeof(struct ieee80211_rx_stats), M_NOWAIT);
588         if (mtag == NULL)
589                 return (0);
590
591         rx = (struct ieee80211_rx_params *)(mtag + 1);
592         memcpy(&rx->params, rxs, sizeof(*rxs));
593         m_tag_prepend(m, mtag);
594         return (1);
595 }
596
597 int
598 ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
599 {
600         struct m_tag *mtag;
601         struct ieee80211_rx_params *rx;
602
603         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
604             NULL);
605         if (mtag == NULL)
606                 return (-1);
607         rx = (struct ieee80211_rx_params *)(mtag + 1);
608         memcpy(rxs, &rx->params, sizeof(*rxs));
609         return (0);
610 }
611
612 const struct ieee80211_rx_stats *
613 ieee80211_get_rx_params_ptr(struct mbuf *m)
614 {
615         struct m_tag *mtag;
616         struct ieee80211_rx_params *rx;
617
618         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
619             NULL);
620         if (mtag == NULL)
621                 return (NULL);
622         rx = (struct ieee80211_rx_params *)(mtag + 1);
623         return (&rx->params);
624 }
625
626
627 /*
628  * Add TOA parameters to the given mbuf.
629  */
630 int
631 ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p)
632 {
633         struct m_tag *mtag;
634         struct ieee80211_toa_params *rp;
635
636         mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS,
637             sizeof(struct ieee80211_toa_params), M_NOWAIT);
638         if (mtag == NULL)
639                 return (0);
640
641         rp = (struct ieee80211_toa_params *)(mtag + 1);
642         memcpy(rp, p, sizeof(*rp));
643         m_tag_prepend(m, mtag);
644         return (1);
645 }
646
647 int
648 ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p)
649 {
650         struct m_tag *mtag;
651         struct ieee80211_toa_params *rp;
652
653         mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS,
654             NULL);
655         if (mtag == NULL)
656                 return (0);
657         rp = (struct ieee80211_toa_params *)(mtag + 1);
658         if (p != NULL)
659                 memcpy(p, rp, sizeof(*p));
660         return (1);
661 }
662
663 /*
664  * Transmit a frame to the parent interface.
665  */
666 int
667 ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
668 {
669         int error;
670
671         /*
672          * Assert the IC TX lock is held - this enforces the
673          * processing -> queuing order is maintained
674          */
675         IEEE80211_TX_LOCK_ASSERT(ic);
676         error = ic->ic_transmit(ic, m);
677         if (error) {
678                 struct ieee80211_node *ni;
679
680                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
681
682                 /* XXX number of fragments */
683                 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
684                 ieee80211_free_node(ni);
685                 ieee80211_free_mbuf(m);
686         }
687         return (error);
688 }
689
690 /*
691  * Transmit a frame to the VAP interface.
692  */
693 int
694 ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
695 {
696         struct ifnet *ifp = vap->iv_ifp;
697
698         /*
699          * When transmitting via the VAP, we shouldn't hold
700          * any IC TX lock as the VAP TX path will acquire it.
701          */
702         IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
703
704         return (ifp->if_transmit(ifp, m));
705
706 }
707
708 #include <sys/libkern.h>
709
710 void
711 get_random_bytes(void *p, size_t n)
712 {
713         uint8_t *dp = p;
714
715         while (n > 0) {
716                 uint32_t v = arc4random();
717                 size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n;
718                 bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n);
719                 dp += sizeof(uint32_t), n -= nb;
720         }
721 }
722
723 /*
724  * Helper function for events that pass just a single mac address.
725  */
726 static void
727 notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN])
728 {
729         struct ieee80211_join_event iev;
730
731         CURVNET_SET(ifp->if_vnet);
732         memset(&iev, 0, sizeof(iev));
733         IEEE80211_ADDR_COPY(iev.iev_addr, mac);
734         rt_ieee80211msg(ifp, op, &iev, sizeof(iev));
735         CURVNET_RESTORE();
736 }
737
738 void
739 ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
740 {
741         struct ieee80211vap *vap = ni->ni_vap;
742         struct ifnet *ifp = vap->iv_ifp;
743
744         CURVNET_SET_QUIET(ifp->if_vnet);
745         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode join",
746             (ni == vap->iv_bss) ? "bss " : "");
747
748         if (ni == vap->iv_bss) {
749                 notify_macaddr(ifp, newassoc ?
750                     RTM_IEEE80211_ASSOC : RTM_IEEE80211_REASSOC, ni->ni_bssid);
751                 if_link_state_change(ifp, LINK_STATE_UP);
752         } else {
753                 notify_macaddr(ifp, newassoc ?
754                     RTM_IEEE80211_JOIN : RTM_IEEE80211_REJOIN, ni->ni_macaddr);
755         }
756         CURVNET_RESTORE();
757 }
758
759 void
760 ieee80211_notify_node_leave(struct ieee80211_node *ni)
761 {
762         struct ieee80211vap *vap = ni->ni_vap;
763         struct ifnet *ifp = vap->iv_ifp;
764
765         CURVNET_SET_QUIET(ifp->if_vnet);
766         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode leave",
767             (ni == vap->iv_bss) ? "bss " : "");
768
769         if (ni == vap->iv_bss) {
770                 rt_ieee80211msg(ifp, RTM_IEEE80211_DISASSOC, NULL, 0);
771                 if_link_state_change(ifp, LINK_STATE_DOWN);
772         } else {
773                 /* fire off wireless event station leaving */
774                 notify_macaddr(ifp, RTM_IEEE80211_LEAVE, ni->ni_macaddr);
775         }
776         CURVNET_RESTORE();
777 }
778
779 void
780 ieee80211_notify_scan_done(struct ieee80211vap *vap)
781 {
782         struct ifnet *ifp = vap->iv_ifp;
783
784         IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", "notify scan done");
785
786         /* dispatch wireless event indicating scan completed */
787         CURVNET_SET(ifp->if_vnet);
788         rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0);
789         CURVNET_RESTORE();
790 }
791
792 void
793 ieee80211_notify_replay_failure(struct ieee80211vap *vap,
794         const struct ieee80211_frame *wh, const struct ieee80211_key *k,
795         u_int64_t rsc, int tid)
796 {
797         struct ifnet *ifp = vap->iv_ifp;
798
799         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
800             "%s replay detected tid %d <rsc %ju (%jx), csc %ju (%jx), keyix %u rxkeyix %u>",
801             k->wk_cipher->ic_name, tid,
802             (intmax_t) rsc,
803             (intmax_t) rsc,
804             (intmax_t) k->wk_keyrsc[tid],
805             (intmax_t) k->wk_keyrsc[tid],
806             k->wk_keyix, k->wk_rxkeyix);
807
808         if (ifp != NULL) {              /* NB: for cipher test modules */
809                 struct ieee80211_replay_event iev;
810
811                 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
812                 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
813                 iev.iev_cipher = k->wk_cipher->ic_cipher;
814                 if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE)
815                         iev.iev_keyix = k->wk_rxkeyix;
816                 else
817                         iev.iev_keyix = k->wk_keyix;
818                 iev.iev_keyrsc = k->wk_keyrsc[tid];
819                 iev.iev_rsc = rsc;
820                 CURVNET_SET(ifp->if_vnet);
821                 rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev));
822                 CURVNET_RESTORE();
823         }
824 }
825
826 void
827 ieee80211_notify_michael_failure(struct ieee80211vap *vap,
828         const struct ieee80211_frame *wh, u_int keyix)
829 {
830         struct ifnet *ifp = vap->iv_ifp;
831
832         IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
833             "michael MIC verification failed <keyix %u>", keyix);
834         vap->iv_stats.is_rx_tkipmic++;
835
836         if (ifp != NULL) {              /* NB: for cipher test modules */
837                 struct ieee80211_michael_event iev;
838
839                 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
840                 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
841                 iev.iev_cipher = IEEE80211_CIPHER_TKIP;
842                 iev.iev_keyix = keyix;
843                 CURVNET_SET(ifp->if_vnet);
844                 rt_ieee80211msg(ifp, RTM_IEEE80211_MICHAEL, &iev, sizeof(iev));
845                 CURVNET_RESTORE();
846         }
847 }
848
849 void
850 ieee80211_notify_wds_discover(struct ieee80211_node *ni)
851 {
852         struct ieee80211vap *vap = ni->ni_vap;
853         struct ifnet *ifp = vap->iv_ifp;
854
855         notify_macaddr(ifp, RTM_IEEE80211_WDS, ni->ni_macaddr);
856 }
857
858 void
859 ieee80211_notify_csa(struct ieee80211com *ic,
860         const struct ieee80211_channel *c, int mode, int count)
861 {
862         struct ieee80211_csa_event iev;
863         struct ieee80211vap *vap;
864         struct ifnet *ifp;
865
866         memset(&iev, 0, sizeof(iev));
867         iev.iev_flags = c->ic_flags;
868         iev.iev_freq = c->ic_freq;
869         iev.iev_ieee = c->ic_ieee;
870         iev.iev_mode = mode;
871         iev.iev_count = count;
872         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
873                 ifp = vap->iv_ifp;
874                 CURVNET_SET(ifp->if_vnet);
875                 rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
876                 CURVNET_RESTORE();
877         }
878 }
879
880 void
881 ieee80211_notify_radar(struct ieee80211com *ic,
882         const struct ieee80211_channel *c)
883 {
884         struct ieee80211_radar_event iev;
885         struct ieee80211vap *vap;
886         struct ifnet *ifp;
887
888         memset(&iev, 0, sizeof(iev));
889         iev.iev_flags = c->ic_flags;
890         iev.iev_freq = c->ic_freq;
891         iev.iev_ieee = c->ic_ieee;
892         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
893                 ifp = vap->iv_ifp;
894                 CURVNET_SET(ifp->if_vnet);
895                 rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
896                 CURVNET_RESTORE();
897         }
898 }
899
900 void
901 ieee80211_notify_cac(struct ieee80211com *ic,
902         const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
903 {
904         struct ieee80211_cac_event iev;
905         struct ieee80211vap *vap;
906         struct ifnet *ifp;
907
908         memset(&iev, 0, sizeof(iev));
909         iev.iev_flags = c->ic_flags;
910         iev.iev_freq = c->ic_freq;
911         iev.iev_ieee = c->ic_ieee;
912         iev.iev_type = type;
913         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
914                 ifp = vap->iv_ifp;
915                 CURVNET_SET(ifp->if_vnet);
916                 rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
917                 CURVNET_RESTORE();
918         }
919 }
920
921 void
922 ieee80211_notify_node_deauth(struct ieee80211_node *ni)
923 {
924         struct ieee80211vap *vap = ni->ni_vap;
925         struct ifnet *ifp = vap->iv_ifp;
926
927         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node deauth");
928
929         notify_macaddr(ifp, RTM_IEEE80211_DEAUTH, ni->ni_macaddr);
930 }
931
932 void
933 ieee80211_notify_node_auth(struct ieee80211_node *ni)
934 {
935         struct ieee80211vap *vap = ni->ni_vap;
936         struct ifnet *ifp = vap->iv_ifp;
937
938         IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node auth");
939
940         notify_macaddr(ifp, RTM_IEEE80211_AUTH, ni->ni_macaddr);
941 }
942
943 void
944 ieee80211_notify_country(struct ieee80211vap *vap,
945         const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2])
946 {
947         struct ifnet *ifp = vap->iv_ifp;
948         struct ieee80211_country_event iev;
949
950         memset(&iev, 0, sizeof(iev));
951         IEEE80211_ADDR_COPY(iev.iev_addr, bssid);
952         iev.iev_cc[0] = cc[0];
953         iev.iev_cc[1] = cc[1];
954         CURVNET_SET(ifp->if_vnet);
955         rt_ieee80211msg(ifp, RTM_IEEE80211_COUNTRY, &iev, sizeof(iev));
956         CURVNET_RESTORE();
957 }
958
959 void
960 ieee80211_notify_radio(struct ieee80211com *ic, int state)
961 {
962         struct ieee80211_radio_event iev;
963         struct ieee80211vap *vap;
964         struct ifnet *ifp;
965
966         memset(&iev, 0, sizeof(iev));
967         iev.iev_state = state;
968         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
969                 ifp = vap->iv_ifp;
970                 CURVNET_SET(ifp->if_vnet);
971                 rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
972                 CURVNET_RESTORE();
973         }
974 }
975
976 void
977 ieee80211_notify_ifnet_change(struct ieee80211vap *vap)
978 {
979         struct ifnet *ifp = vap->iv_ifp;
980
981         IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, "%s\n",
982             "interface state change");
983
984         CURVNET_SET(ifp->if_vnet);
985         rt_ifmsg(ifp);
986         CURVNET_RESTORE();
987 }
988
989 void
990 ieee80211_load_module(const char *modname)
991 {
992
993 #ifdef notyet
994         (void)kern_kldload(curthread, modname, NULL);
995 #else
996         printf("%s: load the %s module by hand for now.\n", __func__, modname);
997 #endif
998 }
999
1000 static eventhandler_tag wlan_bpfevent;
1001 static eventhandler_tag wlan_ifllevent;
1002
1003 static void
1004 bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
1005 {
1006         /* NB: identify vap's by if_init */
1007         if (dlt == DLT_IEEE802_11_RADIO &&
1008             ifp->if_init == ieee80211_init) {
1009                 struct ieee80211vap *vap = ifp->if_softc;
1010                 /*
1011                  * Track bpf radiotap listener state.  We mark the vap
1012                  * to indicate if any listener is present and the com
1013                  * to indicate if any listener exists on any associated
1014                  * vap.  This flag is used by drivers to prepare radiotap
1015                  * state only when needed.
1016                  */
1017                 if (attach) {
1018                         ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
1019                         if (vap->iv_opmode == IEEE80211_M_MONITOR)
1020                                 atomic_add_int(&vap->iv_ic->ic_montaps, 1);
1021                 } else if (!bpf_peers_present(vap->iv_rawbpf)) {
1022                         ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
1023                         if (vap->iv_opmode == IEEE80211_M_MONITOR)
1024                                 atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
1025                 }
1026         }
1027 }
1028
1029 /*
1030  * Change MAC address on the vap (if was not started).
1031  */
1032 static void
1033 wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
1034 {
1035         /* NB: identify vap's by if_init */
1036         if (ifp->if_init == ieee80211_init &&
1037             (ifp->if_flags & IFF_UP) == 0) {
1038                 struct ieee80211vap *vap = ifp->if_softc;
1039
1040                 IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
1041         }
1042 }
1043
1044 /*
1045  * Fetch the VAP name.
1046  *
1047  * This returns a const char pointer suitable for debugging,
1048  * but don't expect it to stick around for much longer.
1049  */
1050 const char *
1051 ieee80211_get_vap_ifname(struct ieee80211vap *vap)
1052 {
1053         if (vap->iv_ifp == NULL)
1054                 return "(none)";
1055         return vap->iv_ifp->if_xname;
1056 }
1057
1058 #ifdef DEBUGNET
1059 static void
1060 ieee80211_debugnet_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize)
1061 {
1062         struct ieee80211vap *vap;
1063         struct ieee80211com *ic;
1064
1065         vap = if_getsoftc(ifp);
1066         ic = vap->iv_ic;
1067
1068         IEEE80211_LOCK(ic);
1069         ic->ic_debugnet_meth->dn8_init(ic, nrxr, ncl, clsize);
1070         IEEE80211_UNLOCK(ic);
1071 }
1072
1073 static void
1074 ieee80211_debugnet_event(struct ifnet *ifp, enum debugnet_ev ev)
1075 {
1076         struct ieee80211vap *vap;
1077         struct ieee80211com *ic;
1078
1079         vap = if_getsoftc(ifp);
1080         ic = vap->iv_ic;
1081
1082         IEEE80211_LOCK(ic);
1083         ic->ic_debugnet_meth->dn8_event(ic, ev);
1084         IEEE80211_UNLOCK(ic);
1085 }
1086
1087 static int
1088 ieee80211_debugnet_transmit(struct ifnet *ifp, struct mbuf *m)
1089 {
1090         return (ieee80211_vap_transmit(ifp, m));
1091 }
1092
1093 static int
1094 ieee80211_debugnet_poll(struct ifnet *ifp, int count)
1095 {
1096         struct ieee80211vap *vap;
1097         struct ieee80211com *ic;
1098
1099         vap = if_getsoftc(ifp);
1100         ic = vap->iv_ic;
1101
1102         return (ic->ic_debugnet_meth->dn8_poll(ic, count));
1103 }
1104 #endif
1105
1106 /*
1107  * Module glue.
1108  *
1109  * NB: the module name is "wlan" for compatibility with NetBSD.
1110  */
1111 static int
1112 wlan_modevent(module_t mod, int type, void *unused)
1113 {
1114         switch (type) {
1115         case MOD_LOAD:
1116                 if (bootverbose)
1117                         printf("wlan: <802.11 Link Layer>\n");
1118                 wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
1119                     bpf_track, 0, EVENTHANDLER_PRI_ANY);
1120                 wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
1121                     wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
1122                 wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
1123                     wlan_clone_destroy, 0);
1124                 return 0;
1125         case MOD_UNLOAD:
1126                 if_clone_detach(wlan_cloner);
1127                 EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
1128                 EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
1129                 return 0;
1130         }
1131         return EINVAL;
1132 }
1133
1134 static moduledata_t wlan_mod = {
1135         wlanname,
1136         wlan_modevent,
1137         0
1138 };
1139 DECLARE_MODULE(wlan, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1140 MODULE_VERSION(wlan, 1);
1141 MODULE_DEPEND(wlan, ether, 1, 1, 1);
1142 #ifdef  IEEE80211_ALQ
1143 MODULE_DEPEND(wlan, alq, 1, 1, 1);
1144 #endif  /* IEEE80211_ALQ */
1145