38#include <sys/eventhandler.h>
39#include <sys/kernel.h>
40#include <sys/linker.h>
41#include <sys/malloc.h>
43#include <sys/module.h>
46#include <sys/sysctl.h>
48#include <sys/socket.h>
51#include <net/debugnet.h>
53#include <net/if_var.h>
55#include <net/if_clone.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58#include <net/ethernet.h>
66SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
67 "IEEE 80211 parameters");
70static int ieee80211_debug = 0;
71SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
72 0,
"debugging printfs");
84 struct ieee80211vap *vap __unused,
struct ifnet *ifp __unused)
87 return (priv_check(curthread, PRIV_NET80211_VAP_GETKEY));
92 struct ieee80211vap *vap __unused,
struct ifnet *ifp __unused)
95 return (priv_check(curthread, PRIV_NET80211_VAP_MANAGE));
100 struct ieee80211vap *vap __unused,
struct ifnet *ifp __unused)
103 return (priv_check(curthread, PRIV_NET80211_VAP_SETMAC));
108 struct ieee80211vap *vap __unused,
struct ifnet *ifp __unused)
111 return (priv_check(curthread, PRIV_NET80211_CREATE_VAP));
126 error = copyin(params, &cp,
sizeof(cp));
133 ic_printf(ic,
"%s: invalid opmode %d\n", __func__,
143#ifdef IEEE80211_SUPPORT_TDMA
162 DEBUGNET_SET(vap->
iv_ifp, ieee80211);
179 CURVNET_SET(vap->
iv_ifp->if_vnet);
190 error = sysctl_handle_int(oidp, &msecs, 0, req);
191 if (error || !req->newptr)
203 error = sysctl_handle_int(oidp, &inact, 0, req);
204 if (error || !req->newptr)
215 return SYSCTL_OUT_STR(req, ic->
ic_name);
224 error = sysctl_handle_int(oidp, &t, 0, req);
225 if (error || !req->newptr)
245 error = sysctl_handle_int(oidp, &t, 0, req);
246 if (error || !req->newptr)
266 struct ifnet *ifp = vap->
iv_ifp;
267 struct sysctl_ctx_list *ctx;
268 struct sysctl_oid *oid;
271 ctx = (
struct sysctl_ctx_list *)
IEEE80211_MALLOC(
sizeof(
struct sysctl_ctx_list),
274 if_printf(ifp,
"%s: cannot allocate sysctl context!\n",
278 sysctl_ctx_init(ctx);
279 snprintf(num,
sizeof(num),
"%u", ifp->if_dunit);
280 oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan),
281 OID_AUTO, num, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"");
282 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
283 "%parent", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
285 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
286 "driver_caps", CTLFLAG_RW, &vap->
iv_caps, 0,
287 "driver capabilities");
288#ifdef IEEE80211_DEBUG
290 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
291 "debug", CTLFLAG_RW, &vap->
iv_debug, 0,
292 "control debugging printfs");
294 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
296 "consecutive beacon misses before scanning");
298 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
299 "inact_run", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
301 "station inactivity timeout (sec)");
302 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
303 "inact_probe", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
305 "station inactivity probe timeout (sec)");
306 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
307 "inact_auth", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
309 "station authentication timeout (sec)");
310 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
311 "inact_init", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
313 "station initial state timeout (sec)");
315 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
316 "ampdu_mintraffic_bk", CTLFLAG_RW,
318 "BK traffic tx aggr threshold (pps)");
319 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
320 "ampdu_mintraffic_be", CTLFLAG_RW,
322 "BE traffic tx aggr threshold (pps)");
323 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
324 "ampdu_mintraffic_vo", CTLFLAG_RW,
326 "VO traffic tx aggr threshold (pps)");
327 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
328 "ampdu_mintraffic_vi", CTLFLAG_RW,
330 "VI traffic tx aggr threshold (pps)");
333 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
334 "force_restart", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
338 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
339 "radar", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
341 "simulate radar event");
387 (
"com reference counter underflow"));
401 pause(
"comref", sleep_time);
409 return atomic_cmpset_int(&ni->
ni_refcnt, 0, 1);
424 KASSERT(ni != NULL, (
"frame w/o node"));
426 m->m_pkthdr.rcvif = NULL;
436 struct mbuf *m, **mprev;
439 mprev = &ifq->ifq_head;
440 while ((m = *mprev) != NULL) {
442 if (ni != NULL && ni->
ni_vap == vap) {
443 *mprev = m->m_nextpkt;
449 mprev = &m->m_nextpkt;
453 for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt)
463#define MC_ALIGN(m, len) \
465 (m)->m_data += rounddown2(MCLBYTES - (len), sizeof(long)); \
487 len = roundup2(headroom + pktlen, 4);
488 KASSERT(len <= MCLBYTES, (
"802.11 mgt frame too large: %u", len));
489 if (len < MINCLSIZE) {
490 m = m_gethdr(M_NOWAIT, MT_DATA);
500 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
505 m->m_data += headroom;
511#ifndef __NO_STRICT_ALIGNMENT
522 pktlen = m->m_pkthdr.len;
523 space = pktlen + align;
524 if (space < MINCLSIZE)
525 n = m_gethdr(M_NOWAIT, MT_DATA);
527 n = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
528 space <= MCLBYTES ? MCLBYTES :
529#
if MJUMPAGESIZE != MCLBYTES
530 space <= MJUMPAGESIZE ? MJUMPAGESIZE :
532 space <= MJUM9BYTES ? MJUM9BYTES : MJUM16BYTES);
534 if (__predict_true(n != NULL)) {
536 n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align);
537 m_copydata(m, 0, pktlen, mtod(n, caddr_t));
542 "%s",
"no mbuf to realign");
565 m_tag_prepend(m, mtag);
584 m_tag_prepend(m, mtag);
606 struct mbuf *m,
int status)
634 memcpy(&rx->
params, rxs,
sizeof(*rxs));
635 m_tag_prepend(m, mtag);
650 memcpy(rxs, &rx->
params,
sizeof(*rxs));
683 memcpy(rp, p,
sizeof(*rp));
684 m_tag_prepend(m, mtag);
700 memcpy(p, rp,
sizeof(*p));
724 if_inc_counter(ni->
ni_vap->
iv_ifp, IFCOUNTER_OERRORS, 1);
737 struct ifnet *ifp = vap->
iv_ifp;
745 return (ifp->if_transmit(ifp, m));
749#include <sys/libkern.h>
757 uint32_t v = arc4random();
758 size_t nb = n >
sizeof(uint32_t) ?
sizeof(uint32_t) : n;
759 bcopy(&v, dp, n >
sizeof(uint32_t) ?
sizeof(uint32_t) : n);
760 dp +=
sizeof(uint32_t), n -= nb;
772 CURVNET_SET(ifp->if_vnet);
773 memset(&iev, 0,
sizeof(iev));
775 rt_ieee80211msg(ifp, op, &iev,
sizeof(iev));
783 struct ifnet *ifp = vap->
iv_ifp;
785 CURVNET_SET_QUIET(ifp->if_vnet);
787 (ni == vap->
iv_bss) ?
"bss " :
"");
792 if_link_state_change(ifp, LINK_STATE_UP);
804 struct ifnet *ifp = vap->
iv_ifp;
806 CURVNET_SET_QUIET(ifp->if_vnet);
808 (ni == vap->
iv_bss) ?
"bss " :
"");
812 if_link_state_change(ifp, LINK_STATE_DOWN);
823 struct ifnet *ifp = vap->
iv_ifp;
828 CURVNET_SET(ifp->if_vnet);
836 u_int64_t rsc,
int tid)
838 struct ifnet *ifp = vap->
iv_ifp;
841 "%s replay detected tid %d <rsc %ju (%jx), csc %ju (%jx), keyix %u rxkeyix %u>",
861 CURVNET_SET(ifp->if_vnet);
871 struct ifnet *ifp = vap->
iv_ifp;
874 "michael MIC verification failed <keyix %u>", keyix);
884 CURVNET_SET(ifp->if_vnet);
894 struct ifnet *ifp = vap->
iv_ifp;
907 memset(&iev, 0,
sizeof(iev));
913 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
915 CURVNET_SET(ifp->if_vnet);
929 memset(&iev, 0,
sizeof(iev));
933 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
935 CURVNET_SET(ifp->if_vnet);
949 memset(&iev, 0,
sizeof(iev));
954 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
956 CURVNET_SET(ifp->if_vnet);
966 struct ifnet *ifp = vap->
iv_ifp;
977 struct ifnet *ifp = vap->
iv_ifp;
988 struct ifnet *ifp = vap->
iv_ifp;
991 memset(&iev, 0,
sizeof(iev));
995 CURVNET_SET(ifp->if_vnet);
1007 memset(&iev, 0,
sizeof(iev));
1009 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
1011 CURVNET_SET(ifp->if_vnet);
1020 struct ifnet *ifp = vap->
iv_ifp;
1023 "interface state change");
1025 CURVNET_SET(ifp->if_vnet);
1035 (void)kern_kldload(curthread, modname, NULL);
1037 printf(
"%s: load the %s module by hand for now.\n", __func__, modname);
1062 }
else if (!bpf_peers_present(vap->
iv_rawbpf)) {
1078 (ifp->if_flags & IFF_UP) == 0) {
1096 return vap->
iv_ifp->if_xname;
1101ieee80211_debugnet_init(
struct ifnet *ifp,
int *nrxr,
int *ncl,
int *clsize)
1106 vap = if_getsoftc(ifp);
1115ieee80211_debugnet_event(
struct ifnet *ifp,
enum debugnet_ev ev)
1120 vap = if_getsoftc(ifp);
1129ieee80211_debugnet_transmit(
struct ifnet *ifp,
struct mbuf *m)
1135ieee80211_debugnet_poll(
struct ifnet *ifp,
int count)
1140 vap = if_getsoftc(ifp);
1158 printf(
"wlan: <802.11 Link Layer>\n");
#define IEEE80211_OPMODE_MAX
int ic_printf(struct ieee80211com *ic, const char *fmt,...)
const int ieee80211_opcap[IEEE80211_OPMODE_MAX]
void ieee80211_syncflag_ext(struct ieee80211vap *vap, int flag)
struct ieee80211com * ieee80211_find_com(const char *name)
#define IEEE80211_ADDR_LEN
static const struct ieee80211_aclator mac
SYSCTL_INT(_net_wlan, OID_AUTO, alq_size, CTLFLAG_RW, &ieee80211_alq_qsize, 0, "In-memory log size (bytes)")
#define IEEE80211_KEYIX_NONE
#define IEEE80211_CIPHER_TKIP
void ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *chan)
void ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
int ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS)
SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD|CTLFLAG_MPSAFE, 0, "IEEE 80211 parameters")
int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
static void bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
void ieee80211_notify_node_auth(struct ieee80211_node *ni)
struct mbuf * ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen)
void ieee80211_process_callback(struct ieee80211_node *ni, struct mbuf *m, int status)
void ieee80211_notify_csa(struct ieee80211com *ic, const struct ieee80211_channel *c, int mode, int count)
void ieee80211_com_vdetach(struct ieee80211vap *vap)
void ieee80211_notify_radar(struct ieee80211com *ic, const struct ieee80211_channel *c)
void ieee80211_notify_country(struct ieee80211vap *vap, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2])
int ieee80211_node_dectestref(struct ieee80211_node *ni)
void ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
int ieee80211_priv_check_vap_setmac(u_long cmd __unused, struct ieee80211vap *vap __unused, struct ifnet *ifp __unused)
void ieee80211_notify_wds_discover(struct ieee80211_node *ni)
int ieee80211_priv_check_vap_getkey(u_long cmd __unused, struct ieee80211vap *vap __unused, struct ifnet *ifp __unused)
void net80211_get_random_bytes(void *p, size_t n)
static int ieee80211_sysctl_vap_restart(SYSCTL_HANDLER_ARGS)
static eventhandler_tag wlan_bpfevent
void ieee80211_notify_node_leave(struct ieee80211_node *ni)
void ieee80211_sysctl_attach(struct ieee80211com *ic)
int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
int ieee80211_add_xmit_params(struct mbuf *m, const struct ieee80211_bpf_params *params)
static int ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS)
void ieee80211_com_vdecref(struct ieee80211vap *vap)
void ieee80211_sysctl_vattach(struct ieee80211vap *vap)
void ieee80211_flush_ifq(struct ifqueue *ifq, struct ieee80211vap *vap)
int ieee80211_add_callback(struct mbuf *m, void(*func)(struct ieee80211_node *, void *, int), void *arg)
DEBUGNET_DEFINE(ieee80211)
struct mbuf * ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
static void wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
int ieee80211_priv_check_create_vap(u_long cmd __unused, struct ieee80211vap *vap __unused, struct ifnet *ifp __unused)
int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params *params)
void ieee80211_vap_destroy(struct ieee80211vap *vap)
int ieee80211_priv_check_vap_manage(u_long cmd __unused, struct ieee80211vap *vap __unused, struct ifnet *ifp __unused)
static void notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN])
void ieee80211_notify_scan_done(struct ieee80211vap *vap)
static moduledata_t wlan_mod
const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m)
void ieee80211_notify_cac(struct ieee80211com *ic, const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
static int wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
static eventhandler_tag wlan_ifllevent
DECLARE_MODULE(wlan, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST)
void ieee80211_notify_ifnet_change(struct ieee80211vap *vap)
void ieee80211_sysctl_detach(struct ieee80211com *ic)
static struct if_clone * wlan_cloner
static int ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
int ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
void ieee80211_drain_ifq(struct ifqueue *ifq)
void ieee80211_notify_radio(struct ieee80211com *ic, int state)
void ieee80211_notify_node_deauth(struct ieee80211_node *ni)
MODULE_DEPEND(wlan, ether, 1, 1, 1)
static int wlan_modevent(module_t mod, int type, void *unused)
const char * ieee80211_get_vap_ifname(struct ieee80211vap *vap)
int ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
static int ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS)
static void wlan_clone_destroy(struct ifnet *ifp)
static const char wlanname[]
void ieee80211_load_module(const char *modname)
int ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p)
int ieee80211_com_vincref(struct ieee80211vap *vap)
int ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p)
void ieee80211_notify_replay_failure(struct ieee80211vap *vap, const struct ieee80211_frame *wh, const struct ieee80211_key *k, u_int64_t rsc, int tid)
void ieee80211_notify_michael_failure(struct ieee80211vap *vap, const struct ieee80211_frame *wh, u_int keyix)
#define NET80211_TAG_RECV_PARAMS
#define IEEE80211_TX_LOCK_ASSERT(_ic)
#define NET80211_TAG_XMIT_PARAMS
#define RTM_IEEE80211_WDS
#define RTM_IEEE80211_CAC
#define RTM_IEEE80211_REASSOC
#define IEEE80211_M_NOWAIT
#define RTM_IEEE80211_REPLAY
#define NET80211_TAG_CALLBACK
#define RTM_IEEE80211_COUNTRY
#define msecs_to_ticks(ms)
#define IEEE80211_UNLOCK(_ic)
#define RTM_IEEE80211_RADIO
#define ticks_to_msecs(t)
#define IEEE80211_TX_UNLOCK_ASSERT(_ic)
#define RTM_IEEE80211_JOIN
#define RTM_IEEE80211_CSA
#define IEEE80211_LOCK(_ic)
#define RTM_IEEE80211_ASSOC
#define RTM_IEEE80211_MICHAEL
#define NET80211_TAG_TOA_PARAMS
#define RTM_IEEE80211_DEAUTH
#define MTAG_ABI_NET80211
#define RTM_IEEE80211_DISASSOC
#define RTM_IEEE80211_AUTH
#define RTM_IEEE80211_SCAN
#define RTM_IEEE80211_REJOIN
#define RTM_IEEE80211_LEAVE
#define RTM_IEEE80211_RADAR
#define IEEE80211_CLONE_MACADDR
#define IEEE80211_CLONE_TDMA
void ieee80211_free_node(struct ieee80211_node *ni)
#define IEEE80211_INACT_WAIT
void ieee80211_free_mbuf(struct mbuf *m)
int ieee80211_vap_transmit(struct ifnet *ifp, struct mbuf *m)
void ieee80211_restart_all(struct ieee80211com *ic)
void ieee80211_init(void *arg)
const char * ieee80211_opmode_name[IEEE80211_OPMODE_MAX]
ieee80211_notify_cac_event
#define DLT_IEEE802_11_RADIO
#define IEEE80211_ADDR_COPY(dst, src)
#define IEEE80211_COM_REF
#define IEEE80211_COM_REF_ADD
#define _IEEE80211_MASKSHIFT(_v, _f)
#define IEEE80211_MSG_CRYPTO
#define IEEE80211_MSG_ANY
#define IEEE80211_MSG_SCAN
#define IEEE80211_NOTE_MAC(_vap, _m, _mac, _fmt,...)
#define IEEE80211_COM_DETACHED
#define IEEE80211_MSG_NODE
#define IEEE80211_MSG_DEBUG
#define IEEE80211_NOTE(_vap, _m, _ni, _fmt,...)
#define IEEE80211_FEXT_BPF
#define IEEE80211_DPRINTF(_vap, _m, _fmt,...)
#define IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt,...)
#define IEEE80211_COM_REF_MAX
void(* func)(struct ieee80211_node *, void *, int status)
char icp_parent[IFNAMSIZ]
uint8_t icp_macaddr[IEEE80211_ADDR_LEN]
uint8_t icp_bssid[IEEE80211_ADDR_LEN]
uint8_t i_addr1[IEEE80211_ADDR_LEN]
uint8_t i_addr2[IEEE80211_ADDR_LEN]
uint64_t wk_keyrsc[IEEE80211_TID_SIZE]
const struct ieee80211_cipher * wk_cipher
ieee80211_keyix wk_rxkeyix
uint8_t ni_macaddr[IEEE80211_ADDR_LEN]
uint8_t ni_bssid[IEEE80211_ADDR_LEN]
struct ieee80211vap * ni_vap
struct ieee80211_rx_stats params
struct ieee80211_bpf_params params
struct ieee80211vap *(* ic_vap_create)(struct ieee80211com *, const char[IFNAMSIZ], int, enum ieee80211_opmode, int, const uint8_t[IEEE80211_ADDR_LEN], const uint8_t[IEEE80211_ADDR_LEN])
uint8_t ic_macaddr[IEEE80211_ADDR_LEN]
void(* ic_vap_delete)(struct ieee80211vap *)
int(* ic_transmit)(struct ieee80211com *, struct mbuf *)
const struct debugnet80211_methods * ic_debugnet_meth
struct ieee80211_channel * ic_curchan
struct sysctl_oid * iv_oid
struct ieee80211com * iv_ic
struct ieee80211_node * iv_bss
enum ieee80211_opmode iv_opmode
uint8_t iv_myaddr[IEEE80211_ADDR_LEN]
struct ieee80211_stats iv_stats
struct sysctl_ctx_list * iv_sysctl
u_int iv_ampdu_mintraffic[WME_NUM_AC]
struct bpf_if * iv_rawbpf