1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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 /* 30 * IEEE 802.11 support (FreeBSD-specific code) 31 */ 32 #include "opt_wlan.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/eventhandler.h> 37 #include <sys/kernel.h> 38 #include <sys/linker.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/module.h> 42 #include <sys/priv.h> 43 #include <sys/proc.h> 44 #include <sys/sysctl.h> 45 #include <sys/syslog.h> 46 47 #include <sys/socket.h> 48 49 #include <net/bpf.h> 50 #include <net/debugnet.h> 51 #include <net/if.h> 52 #include <net/if_var.h> 53 #include <net/if_dl.h> 54 #include <net/if_clone.h> 55 #include <net/if_media.h> 56 #include <net/if_private.h> 57 #include <net/if_types.h> 58 #include <net/ethernet.h> 59 #include <net/route.h> 60 #include <net/vnet.h> 61 62 #include <machine/stdarg.h> 63 64 #include <net80211/ieee80211_var.h> 65 #include <net80211/ieee80211_input.h> 66 67 DEBUGNET_DEFINE(ieee80211); 68 SYSCTL_NODE(_net, OID_AUTO, wlan, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 69 "IEEE 80211 parameters"); 70 71 #ifdef IEEE80211_DEBUG 72 static int ieee80211_debug = 0; 73 SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug, 74 0, "debugging printfs"); 75 #endif 76 77 static const char wlanname[] = "wlan"; 78 static struct if_clone *wlan_cloner; 79 80 /* 81 * priv(9) NET80211 checks. 82 * Return 0 if operation is allowed, E* (usually EPERM) otherwise. 83 */ 84 int 85 ieee80211_priv_check_vap_getkey(u_long cmd __unused, 86 struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) 87 { 88 89 return (priv_check(curthread, PRIV_NET80211_VAP_GETKEY)); 90 } 91 92 int 93 ieee80211_priv_check_vap_manage(u_long cmd __unused, 94 struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) 95 { 96 97 return (priv_check(curthread, PRIV_NET80211_VAP_MANAGE)); 98 } 99 100 int 101 ieee80211_priv_check_vap_setmac(u_long cmd __unused, 102 struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) 103 { 104 105 return (priv_check(curthread, PRIV_NET80211_VAP_SETMAC)); 106 } 107 108 int 109 ieee80211_priv_check_create_vap(u_long cmd __unused, 110 struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) 111 { 112 113 return (priv_check(curthread, PRIV_NET80211_CREATE_VAP)); 114 } 115 116 static int 117 wlan_clone_create(struct if_clone *ifc, char *name, size_t len, 118 struct ifc_data *ifd, struct ifnet **ifpp) 119 { 120 struct ieee80211_clone_params cp; 121 struct ieee80211vap *vap; 122 struct ieee80211com *ic; 123 int error; 124 125 error = ieee80211_priv_check_create_vap(0, NULL, NULL); 126 if (error) 127 return error; 128 129 error = ifc_copyin(ifd, &cp, sizeof(cp)); 130 if (error) 131 return error; 132 ic = ieee80211_find_com(cp.icp_parent); 133 if (ic == NULL) 134 return ENXIO; 135 if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) { 136 ic_printf(ic, "%s: invalid opmode %d\n", __func__, 137 cp.icp_opmode); 138 return EINVAL; 139 } 140 if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) { 141 ic_printf(ic, "%s mode not supported\n", 142 ieee80211_opmode_name[cp.icp_opmode]); 143 return EOPNOTSUPP; 144 } 145 if ((cp.icp_flags & IEEE80211_CLONE_TDMA) && 146 #ifdef IEEE80211_SUPPORT_TDMA 147 (ic->ic_caps & IEEE80211_C_TDMA) == 0 148 #else 149 (1) 150 #endif 151 ) { 152 ic_printf(ic, "TDMA not supported\n"); 153 return EOPNOTSUPP; 154 } 155 vap = ic->ic_vap_create(ic, wlanname, ifd->unit, 156 cp.icp_opmode, cp.icp_flags, cp.icp_bssid, 157 cp.icp_flags & IEEE80211_CLONE_MACADDR ? 158 cp.icp_macaddr : ic->ic_macaddr); 159 160 if (vap == NULL) 161 return (EIO); 162 163 #ifdef DEBUGNET 164 if (ic->ic_debugnet_meth != NULL) 165 DEBUGNET_SET(vap->iv_ifp, ieee80211); 166 #endif 167 *ifpp = vap->iv_ifp; 168 169 return (0); 170 } 171 172 static int 173 wlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp, uint32_t flags) 174 { 175 struct ieee80211vap *vap = ifp->if_softc; 176 struct ieee80211com *ic = vap->iv_ic; 177 178 ic->ic_vap_delete(vap); 179 180 return (0); 181 } 182 183 void 184 ieee80211_vap_destroy(struct ieee80211vap *vap) 185 { 186 CURVNET_SET(vap->iv_ifp->if_vnet); 187 if_clone_destroyif(wlan_cloner, vap->iv_ifp); 188 CURVNET_RESTORE(); 189 } 190 191 int 192 ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS) 193 { 194 int msecs = ticks_to_msecs(*(int *)arg1); 195 int error; 196 197 error = sysctl_handle_int(oidp, &msecs, 0, req); 198 if (error || !req->newptr) 199 return error; 200 *(int *)arg1 = msecs_to_ticks(msecs); 201 return 0; 202 } 203 204 static int 205 ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS) 206 { 207 int inact = (*(int *)arg1) * IEEE80211_INACT_WAIT; 208 int error; 209 210 error = sysctl_handle_int(oidp, &inact, 0, req); 211 if (error || !req->newptr) 212 return error; 213 *(int *)arg1 = inact / IEEE80211_INACT_WAIT; 214 return 0; 215 } 216 217 static int 218 ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS) 219 { 220 struct ieee80211com *ic = arg1; 221 222 return SYSCTL_OUT_STR(req, ic->ic_name); 223 } 224 225 static int 226 ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS) 227 { 228 struct ieee80211com *ic = arg1; 229 int t = 0, error; 230 231 error = sysctl_handle_int(oidp, &t, 0, req); 232 if (error || !req->newptr) 233 return error; 234 IEEE80211_LOCK(ic); 235 ieee80211_dfs_notify_radar(ic, ic->ic_curchan); 236 IEEE80211_UNLOCK(ic); 237 return 0; 238 } 239 240 /* 241 * For now, just restart everything. 242 * 243 * Later on, it'd be nice to have a separate VAP restart to 244 * full-device restart. 245 */ 246 static int 247 ieee80211_sysctl_vap_restart(SYSCTL_HANDLER_ARGS) 248 { 249 struct ieee80211vap *vap = arg1; 250 int t = 0, error; 251 252 error = sysctl_handle_int(oidp, &t, 0, req); 253 if (error || !req->newptr) 254 return error; 255 256 ieee80211_restart_all(vap->iv_ic); 257 return 0; 258 } 259 260 void 261 ieee80211_sysctl_attach(struct ieee80211com *ic) 262 { 263 } 264 265 void 266 ieee80211_sysctl_detach(struct ieee80211com *ic) 267 { 268 } 269 270 void 271 ieee80211_sysctl_vattach(struct ieee80211vap *vap) 272 { 273 struct ifnet *ifp = vap->iv_ifp; 274 struct sysctl_ctx_list *ctx; 275 struct sysctl_oid *oid; 276 char num[14]; /* sufficient for 32 bits */ 277 278 ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list), 279 M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO); 280 if (ctx == NULL) { 281 net80211_vap_printf(vap, 282 "%s: cannot allocate sysctl context!\n", __func__); 283 return; 284 } 285 sysctl_ctx_init(ctx); 286 snprintf(num, sizeof(num), "%u", ifp->if_dunit); 287 oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan), 288 OID_AUTO, num, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); 289 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 290 "%parent", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, 291 vap->iv_ic, 0, ieee80211_sysctl_parent, "A", "parent device"); 292 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 293 "driver_caps", CTLFLAG_RW, &vap->iv_caps, 0, 294 "driver capabilities"); 295 #ifdef IEEE80211_DEBUG 296 vap->iv_debug = ieee80211_debug; 297 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 298 "debug", CTLFLAG_RW, &vap->iv_debug, 0, 299 "control debugging printfs"); 300 #endif 301 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 302 "bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0, 303 "consecutive beacon misses before scanning"); 304 /* XXX inherit from tunables */ 305 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 306 "inact_run", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 307 &vap->iv_inact_run, 0, ieee80211_sysctl_inact, "I", 308 "station inactivity timeout (sec)"); 309 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 310 "inact_probe", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 311 &vap->iv_inact_probe, 0, ieee80211_sysctl_inact, "I", 312 "station inactivity probe timeout (sec)"); 313 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 314 "inact_auth", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 315 &vap->iv_inact_auth, 0, ieee80211_sysctl_inact, "I", 316 "station authentication timeout (sec)"); 317 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 318 "inact_init", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 319 &vap->iv_inact_init, 0, ieee80211_sysctl_inact, "I", 320 "station initial state timeout (sec)"); 321 if (vap->iv_htcaps & IEEE80211_HTC_HT) { 322 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 323 "ampdu_mintraffic_bk", CTLFLAG_RW, 324 &vap->iv_ampdu_mintraffic[WME_AC_BK], 0, 325 "BK traffic tx aggr threshold (pps)"); 326 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 327 "ampdu_mintraffic_be", CTLFLAG_RW, 328 &vap->iv_ampdu_mintraffic[WME_AC_BE], 0, 329 "BE traffic tx aggr threshold (pps)"); 330 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 331 "ampdu_mintraffic_vo", CTLFLAG_RW, 332 &vap->iv_ampdu_mintraffic[WME_AC_VO], 0, 333 "VO traffic tx aggr threshold (pps)"); 334 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 335 "ampdu_mintraffic_vi", CTLFLAG_RW, 336 &vap->iv_ampdu_mintraffic[WME_AC_VI], 0, 337 "VI traffic tx aggr threshold (pps)"); 338 } 339 340 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 341 "force_restart", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 342 vap, 0, ieee80211_sysctl_vap_restart, "I", "force a VAP restart"); 343 344 if (vap->iv_caps & IEEE80211_C_DFS) { 345 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, 346 "radar", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 347 vap->iv_ic, 0, ieee80211_sysctl_radar, "I", 348 "simulate radar event"); 349 } 350 vap->iv_sysctl = ctx; 351 vap->iv_oid = oid; 352 } 353 354 void 355 ieee80211_sysctl_vdetach(struct ieee80211vap *vap) 356 { 357 358 if (vap->iv_sysctl != NULL) { 359 sysctl_ctx_free(vap->iv_sysctl); 360 IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF); 361 vap->iv_sysctl = NULL; 362 } 363 } 364 365 int 366 ieee80211_com_vincref(struct ieee80211vap *vap) 367 { 368 uint32_t ostate; 369 370 ostate = atomic_fetchadd_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD); 371 372 if (ostate & IEEE80211_COM_DETACHED) { 373 atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD); 374 return (ENETDOWN); 375 } 376 377 if (_IEEE80211_MASKSHIFT(ostate, IEEE80211_COM_REF) == 378 IEEE80211_COM_REF_MAX) { 379 atomic_subtract_32(&vap->iv_com_state, IEEE80211_COM_REF_ADD); 380 return (EOVERFLOW); 381 } 382 383 return (0); 384 } 385 386 void 387 ieee80211_com_vdecref(struct ieee80211vap *vap) 388 { 389 uint32_t ostate; 390 391 ostate = atomic_fetchadd_32(&vap->iv_com_state, -IEEE80211_COM_REF_ADD); 392 393 KASSERT(_IEEE80211_MASKSHIFT(ostate, IEEE80211_COM_REF) != 0, 394 ("com reference counter underflow")); 395 396 (void) ostate; 397 } 398 399 void 400 ieee80211_com_vdetach(struct ieee80211vap *vap) 401 { 402 int sleep_time; 403 404 sleep_time = msecs_to_ticks(250); 405 atomic_set_32(&vap->iv_com_state, IEEE80211_COM_DETACHED); 406 while (_IEEE80211_MASKSHIFT(atomic_load_32(&vap->iv_com_state), 407 IEEE80211_COM_REF) != 0) 408 pause("comref", sleep_time); 409 } 410 411 int 412 ieee80211_node_dectestref(struct ieee80211_node *ni) 413 { 414 /* XXX need equivalent of atomic_dec_and_test */ 415 atomic_subtract_int(&ni->ni_refcnt, 1); 416 return atomic_cmpset_int(&ni->ni_refcnt, 0, 1); 417 } 418 419 void 420 ieee80211_drain_ifq(struct ifqueue *ifq) 421 { 422 struct ieee80211_node *ni; 423 struct mbuf *m; 424 425 for (;;) { 426 IF_DEQUEUE(ifq, m); 427 if (m == NULL) 428 break; 429 430 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 431 KASSERT(ni != NULL, ("frame w/o node")); 432 ieee80211_free_node(ni); 433 m->m_pkthdr.rcvif = NULL; 434 435 m_freem(m); 436 } 437 } 438 439 void 440 ieee80211_flush_ifq(struct ifqueue *ifq, struct ieee80211vap *vap) 441 { 442 struct ieee80211_node *ni; 443 struct mbuf *m, **mprev; 444 445 IF_LOCK(ifq); 446 mprev = &ifq->ifq_head; 447 while ((m = *mprev) != NULL) { 448 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 449 if (ni != NULL && ni->ni_vap == vap) { 450 *mprev = m->m_nextpkt; /* remove from list */ 451 ifq->ifq_len--; 452 453 m_freem(m); 454 ieee80211_free_node(ni); /* reclaim ref */ 455 } else 456 mprev = &m->m_nextpkt; 457 } 458 /* recalculate tail ptr */ 459 m = ifq->ifq_head; 460 for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt) 461 ; 462 ifq->ifq_tail = m; 463 IF_UNLOCK(ifq); 464 } 465 466 /* 467 * As above, for mbufs allocated with m_gethdr/MGETHDR 468 * or initialized by M_COPY_PKTHDR. 469 */ 470 #define MC_ALIGN(m, len) \ 471 do { \ 472 (m)->m_data += rounddown2(MCLBYTES - (len), sizeof(long)); \ 473 } while (/* CONSTCOND */ 0) 474 475 /* 476 * Allocate and setup a management frame of the specified 477 * size. We return the mbuf and a pointer to the start 478 * of the contiguous data area that's been reserved based 479 * on the packet length. The data area is forced to 32-bit 480 * alignment and the buffer length to a multiple of 4 bytes. 481 * This is done mainly so beacon frames (that require this) 482 * can use this interface too. 483 */ 484 struct mbuf * 485 ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen) 486 { 487 struct mbuf *m; 488 u_int len; 489 490 /* 491 * NB: we know the mbuf routines will align the data area 492 * so we don't need to do anything special. 493 */ 494 len = roundup2(headroom + pktlen, 4); 495 KASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len)); 496 if (len < MINCLSIZE) { 497 m = m_gethdr(IEEE80211_M_NOWAIT, MT_DATA); 498 /* 499 * Align the data in case additional headers are added. 500 * This should only happen when a WEP header is added 501 * which only happens for shared key authentication mgt 502 * frames which all fit in MHLEN. 503 */ 504 if (m != NULL) 505 M_ALIGN(m, len); 506 } else { 507 m = m_getcl(IEEE80211_M_NOWAIT, MT_DATA, M_PKTHDR); 508 if (m != NULL) 509 MC_ALIGN(m, len); 510 } 511 if (m != NULL) { 512 m->m_data += headroom; 513 *frm = m->m_data; 514 } 515 return m; 516 } 517 518 #ifndef __NO_STRICT_ALIGNMENT 519 /* 520 * Re-align the payload in the mbuf. This is mainly used (right now) 521 * to handle IP header alignment requirements on certain architectures. 522 */ 523 struct mbuf * 524 ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align) 525 { 526 int pktlen, space; 527 struct mbuf *n; 528 529 pktlen = m->m_pkthdr.len; 530 space = pktlen + align; 531 if (space < MINCLSIZE) 532 n = m_gethdr(IEEE80211_M_NOWAIT, MT_DATA); 533 else { 534 n = m_getjcl(IEEE80211_M_NOWAIT, MT_DATA, M_PKTHDR, 535 space <= MCLBYTES ? MCLBYTES : 536 #if MJUMPAGESIZE != MCLBYTES 537 space <= MJUMPAGESIZE ? MJUMPAGESIZE : 538 #endif 539 space <= MJUM9BYTES ? MJUM9BYTES : MJUM16BYTES); 540 } 541 if (__predict_true(n != NULL)) { 542 m_move_pkthdr(n, m); 543 n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align); 544 m_copydata(m, 0, pktlen, mtod(n, caddr_t)); 545 n->m_len = pktlen; 546 } else { 547 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, 548 mtod(m, const struct ieee80211_frame *), NULL, 549 "%s", "no mbuf to realign"); 550 vap->iv_stats.is_rx_badalign++; 551 } 552 m_freem(m); 553 return n; 554 } 555 #endif /* !__NO_STRICT_ALIGNMENT */ 556 557 int 558 ieee80211_add_callback(struct mbuf *m, 559 void (*func)(struct ieee80211_node *, void *, int), void *arg) 560 { 561 struct m_tag *mtag; 562 struct ieee80211_cb *cb; 563 564 mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, 565 sizeof(struct ieee80211_cb), IEEE80211_M_NOWAIT); 566 if (mtag == NULL) 567 return 0; 568 569 cb = (struct ieee80211_cb *)(mtag+1); 570 cb->func = func; 571 cb->arg = arg; 572 m_tag_prepend(m, mtag); 573 m->m_flags |= M_TXCB; 574 return 1; 575 } 576 577 int 578 ieee80211_add_xmit_params(struct mbuf *m, 579 const struct ieee80211_bpf_params *params) 580 { 581 struct m_tag *mtag; 582 struct ieee80211_tx_params *tx; 583 584 mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS, 585 sizeof(struct ieee80211_tx_params), IEEE80211_M_NOWAIT); 586 if (mtag == NULL) 587 return (0); 588 589 tx = (struct ieee80211_tx_params *)(mtag+1); 590 memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params)); 591 m_tag_prepend(m, mtag); 592 return (1); 593 } 594 595 int 596 ieee80211_get_xmit_params(struct mbuf *m, 597 struct ieee80211_bpf_params *params) 598 { 599 struct m_tag *mtag; 600 struct ieee80211_tx_params *tx; 601 602 mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS, 603 NULL); 604 if (mtag == NULL) 605 return (-1); 606 tx = (struct ieee80211_tx_params *)(mtag + 1); 607 memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params)); 608 return (0); 609 } 610 611 void 612 ieee80211_process_callback(struct ieee80211_node *ni, 613 struct mbuf *m, int status) 614 { 615 struct m_tag *mtag; 616 617 mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_CALLBACK, NULL); 618 if (mtag != NULL) { 619 struct ieee80211_cb *cb = (struct ieee80211_cb *)(mtag+1); 620 cb->func(ni, cb->arg, status); 621 } 622 } 623 624 /* 625 * Add RX parameters to the given mbuf. 626 * 627 * Returns 1 if OK, 0 on error. 628 */ 629 int 630 ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs) 631 { 632 struct m_tag *mtag; 633 struct ieee80211_rx_params *rx; 634 635 mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, 636 sizeof(struct ieee80211_rx_stats), IEEE80211_M_NOWAIT); 637 if (mtag == NULL) 638 return (0); 639 640 rx = (struct ieee80211_rx_params *)(mtag + 1); 641 memcpy(&rx->params, rxs, sizeof(*rxs)); 642 m_tag_prepend(m, mtag); 643 return (1); 644 } 645 646 int 647 ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs) 648 { 649 struct m_tag *mtag; 650 struct ieee80211_rx_params *rx; 651 652 mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, 653 NULL); 654 if (mtag == NULL) 655 return (-1); 656 rx = (struct ieee80211_rx_params *)(mtag + 1); 657 memcpy(rxs, &rx->params, sizeof(*rxs)); 658 return (0); 659 } 660 661 const struct ieee80211_rx_stats * 662 ieee80211_get_rx_params_ptr(struct mbuf *m) 663 { 664 struct m_tag *mtag; 665 struct ieee80211_rx_params *rx; 666 667 mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, 668 NULL); 669 if (mtag == NULL) 670 return (NULL); 671 rx = (struct ieee80211_rx_params *)(mtag + 1); 672 return (&rx->params); 673 } 674 675 /* 676 * Add TOA parameters to the given mbuf. 677 */ 678 int 679 ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p) 680 { 681 struct m_tag *mtag; 682 struct ieee80211_toa_params *rp; 683 684 mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS, 685 sizeof(struct ieee80211_toa_params), IEEE80211_M_NOWAIT); 686 if (mtag == NULL) 687 return (0); 688 689 rp = (struct ieee80211_toa_params *)(mtag + 1); 690 memcpy(rp, p, sizeof(*rp)); 691 m_tag_prepend(m, mtag); 692 return (1); 693 } 694 695 int 696 ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p) 697 { 698 struct m_tag *mtag; 699 struct ieee80211_toa_params *rp; 700 701 mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_TOA_PARAMS, 702 NULL); 703 if (mtag == NULL) 704 return (0); 705 rp = (struct ieee80211_toa_params *)(mtag + 1); 706 if (p != NULL) 707 memcpy(p, rp, sizeof(*p)); 708 return (1); 709 } 710 711 /* 712 * @brief Transmit a frame to the parent interface. 713 * 714 * Transmit an 802.11 or 802.3 frame to the parent interface. 715 * 716 * This is called as part of 802.11 processing to enqueue a frame 717 * from net80211 into the device for transmit. 718 * 719 * If the interface is marked as 802.3 via IEEE80211_C_8023ENCAP 720 * (ie, doing offload), then an 802.3 frame will be sent and the 721 * driver will need to understand what to do. 722 * 723 * If the interface is marked as 802.11 (ie, no offload), then 724 * an encapsulated 802.11 frame will be queued. In the case 725 * of an 802.11 fragmented frame this will be a list of frames 726 * representing the fragments making up the 802.11 frame, linked 727 * via m_nextpkt. 728 * 729 * A fragmented frame list will consist of: 730 * + only the first frame with M_SEQNO_SET() assigned the sequence number; 731 * + only the first frame with the node reference and node in rcvif; 732 * + all frames will have the sequence + fragment number populated in 733 * the 802.11 header. 734 * 735 * The driver must ensure it doesn't try releasing a node reference 736 * for each fragment in the list. 737 * 738 * The provided mbuf/list is consumed both upon success and error. 739 * 740 * @param ic struct ieee80211com device to enqueue frame to 741 * @param m struct mbuf chain / packet list to enqueue 742 * @returns 0 if successful, errno if error. 743 */ 744 int 745 ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) 746 { 747 int error; 748 749 /* 750 * Assert the IC TX lock is held - this enforces the 751 * processing -> queuing order is maintained 752 */ 753 IEEE80211_TX_LOCK_ASSERT(ic); 754 error = ic->ic_transmit(ic, m); 755 if (error) { 756 struct ieee80211_node *ni; 757 758 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 759 760 /* XXX number of fragments */ 761 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); 762 763 /* Note: there's only one node reference for a fragment list */ 764 ieee80211_free_node(ni); 765 ieee80211_free_mbuf(m); 766 } 767 return (error); 768 } 769 770 /* 771 * @brief Transmit an 802.3 frame to the VAP interface. 772 * 773 * This is the entry point for the wifi stack to enqueue 802.3 774 * encapsulated frames for transmit to the given vap/ifnet instance. 775 * This is used in paths where 802.3 frames have been received 776 * or queued, and need to be pushed through the VAP encapsulation 777 * and transmit processing pipeline. 778 * 779 * The provided mbuf/list is consumed both upon success and error. 780 * 781 * @param vap struct ieee80211vap instance to transmit frame to 782 * @param m mbuf to transmit 783 * @returns 0 if OK, errno if error 784 */ 785 int 786 ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m) 787 { 788 struct ifnet *ifp = vap->iv_ifp; 789 790 /* 791 * When transmitting via the VAP, we shouldn't hold 792 * any IC TX lock as the VAP TX path will acquire it. 793 */ 794 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic); 795 796 return (ifp->if_transmit(ifp, m)); 797 798 } 799 800 #include <sys/libkern.h> 801 802 void 803 net80211_get_random_bytes(void *p, size_t n) 804 { 805 uint8_t *dp = p; 806 807 while (n > 0) { 808 uint32_t v = arc4random(); 809 size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n; 810 bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n); 811 dp += sizeof(uint32_t), n -= nb; 812 } 813 } 814 815 /* 816 * Helper function for events that pass just a single mac address. 817 */ 818 static void 819 notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN]) 820 { 821 struct ieee80211_join_event iev; 822 823 CURVNET_SET(ifp->if_vnet); 824 memset(&iev, 0, sizeof(iev)); 825 IEEE80211_ADDR_COPY(iev.iev_addr, mac); 826 rt_ieee80211msg(ifp, op, &iev, sizeof(iev)); 827 CURVNET_RESTORE(); 828 } 829 830 void 831 ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc) 832 { 833 struct ieee80211vap *vap = ni->ni_vap; 834 struct ifnet *ifp = vap->iv_ifp; 835 836 CURVNET_SET_QUIET(ifp->if_vnet); 837 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode join", 838 (ni == vap->iv_bss) ? "bss " : ""); 839 840 if (ni == vap->iv_bss) { 841 notify_macaddr(ifp, newassoc ? 842 RTM_IEEE80211_ASSOC : RTM_IEEE80211_REASSOC, ni->ni_bssid); 843 if_link_state_change(ifp, LINK_STATE_UP); 844 } else { 845 notify_macaddr(ifp, newassoc ? 846 RTM_IEEE80211_JOIN : RTM_IEEE80211_REJOIN, ni->ni_macaddr); 847 } 848 CURVNET_RESTORE(); 849 } 850 851 void 852 ieee80211_notify_node_leave(struct ieee80211_node *ni) 853 { 854 struct ieee80211vap *vap = ni->ni_vap; 855 struct ifnet *ifp = vap->iv_ifp; 856 857 CURVNET_SET_QUIET(ifp->if_vnet); 858 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode leave", 859 (ni == vap->iv_bss) ? "bss " : ""); 860 861 if (ni == vap->iv_bss) { 862 rt_ieee80211msg(ifp, RTM_IEEE80211_DISASSOC, NULL, 0); 863 if_link_state_change(ifp, LINK_STATE_DOWN); 864 } else { 865 /* fire off wireless event station leaving */ 866 notify_macaddr(ifp, RTM_IEEE80211_LEAVE, ni->ni_macaddr); 867 } 868 CURVNET_RESTORE(); 869 } 870 871 void 872 ieee80211_notify_scan_done(struct ieee80211vap *vap) 873 { 874 struct ifnet *ifp = vap->iv_ifp; 875 876 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", "notify scan done"); 877 878 /* dispatch wireless event indicating scan completed */ 879 CURVNET_SET(ifp->if_vnet); 880 rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0); 881 CURVNET_RESTORE(); 882 } 883 884 void 885 ieee80211_notify_replay_failure(struct ieee80211vap *vap, 886 const struct ieee80211_frame *wh, const struct ieee80211_key *k, 887 u_int64_t rsc, int tid) 888 { 889 struct ifnet *ifp = vap->iv_ifp; 890 891 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, 892 "%s replay detected tid %d <rsc %ju (%jx), csc %ju (%jx), keyix %u rxkeyix %u>", 893 k->wk_cipher->ic_name, tid, 894 (intmax_t) rsc, 895 (intmax_t) rsc, 896 (intmax_t) k->wk_keyrsc[tid], 897 (intmax_t) k->wk_keyrsc[tid], 898 k->wk_keyix, k->wk_rxkeyix); 899 900 if (ifp != NULL) { /* NB: for cipher test modules */ 901 struct ieee80211_replay_event iev; 902 903 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1); 904 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2); 905 iev.iev_cipher = k->wk_cipher->ic_cipher; 906 if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE) 907 iev.iev_keyix = k->wk_rxkeyix; 908 else 909 iev.iev_keyix = k->wk_keyix; 910 iev.iev_keyrsc = k->wk_keyrsc[tid]; 911 iev.iev_rsc = rsc; 912 CURVNET_SET(ifp->if_vnet); 913 rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev)); 914 CURVNET_RESTORE(); 915 } 916 } 917 918 void 919 ieee80211_notify_michael_failure(struct ieee80211vap *vap, 920 const struct ieee80211_frame *wh, ieee80211_keyix keyix) 921 { 922 struct ifnet *ifp = vap->iv_ifp; 923 924 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2, 925 "michael MIC verification failed <keyix %u>", keyix); 926 vap->iv_stats.is_rx_tkipmic++; 927 928 if (ifp != NULL) { /* NB: for cipher test modules */ 929 struct ieee80211_michael_event iev; 930 931 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1); 932 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2); 933 iev.iev_cipher = IEEE80211_CIPHER_TKIP; 934 iev.iev_keyix = keyix; 935 CURVNET_SET(ifp->if_vnet); 936 rt_ieee80211msg(ifp, RTM_IEEE80211_MICHAEL, &iev, sizeof(iev)); 937 CURVNET_RESTORE(); 938 } 939 } 940 941 void 942 ieee80211_notify_wds_discover(struct ieee80211_node *ni) 943 { 944 struct ieee80211vap *vap = ni->ni_vap; 945 struct ifnet *ifp = vap->iv_ifp; 946 947 notify_macaddr(ifp, RTM_IEEE80211_WDS, ni->ni_macaddr); 948 } 949 950 void 951 ieee80211_notify_csa(struct ieee80211com *ic, 952 const struct ieee80211_channel *c, int mode, int count) 953 { 954 struct ieee80211_csa_event iev; 955 struct ieee80211vap *vap; 956 struct ifnet *ifp; 957 958 memset(&iev, 0, sizeof(iev)); 959 iev.iev_flags = c->ic_flags; 960 iev.iev_freq = c->ic_freq; 961 iev.iev_ieee = c->ic_ieee; 962 iev.iev_mode = mode; 963 iev.iev_count = count; 964 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 965 ifp = vap->iv_ifp; 966 CURVNET_SET(ifp->if_vnet); 967 rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev)); 968 CURVNET_RESTORE(); 969 } 970 } 971 972 void 973 ieee80211_notify_radar(struct ieee80211com *ic, 974 const struct ieee80211_channel *c) 975 { 976 struct ieee80211_radar_event iev; 977 struct ieee80211vap *vap; 978 struct ifnet *ifp; 979 980 memset(&iev, 0, sizeof(iev)); 981 iev.iev_flags = c->ic_flags; 982 iev.iev_freq = c->ic_freq; 983 iev.iev_ieee = c->ic_ieee; 984 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 985 ifp = vap->iv_ifp; 986 CURVNET_SET(ifp->if_vnet); 987 rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev)); 988 CURVNET_RESTORE(); 989 } 990 } 991 992 void 993 ieee80211_notify_cac(struct ieee80211com *ic, 994 const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type) 995 { 996 struct ieee80211_cac_event iev; 997 struct ieee80211vap *vap; 998 struct ifnet *ifp; 999 1000 memset(&iev, 0, sizeof(iev)); 1001 iev.iev_flags = c->ic_flags; 1002 iev.iev_freq = c->ic_freq; 1003 iev.iev_ieee = c->ic_ieee; 1004 iev.iev_type = type; 1005 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 1006 ifp = vap->iv_ifp; 1007 CURVNET_SET(ifp->if_vnet); 1008 rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev)); 1009 CURVNET_RESTORE(); 1010 } 1011 } 1012 1013 void 1014 ieee80211_notify_node_deauth(struct ieee80211_node *ni) 1015 { 1016 struct ieee80211vap *vap = ni->ni_vap; 1017 struct ifnet *ifp = vap->iv_ifp; 1018 1019 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node deauth"); 1020 1021 notify_macaddr(ifp, RTM_IEEE80211_DEAUTH, ni->ni_macaddr); 1022 } 1023 1024 void 1025 ieee80211_notify_node_auth(struct ieee80211_node *ni) 1026 { 1027 struct ieee80211vap *vap = ni->ni_vap; 1028 struct ifnet *ifp = vap->iv_ifp; 1029 1030 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node auth"); 1031 1032 notify_macaddr(ifp, RTM_IEEE80211_AUTH, ni->ni_macaddr); 1033 } 1034 1035 void 1036 ieee80211_notify_country(struct ieee80211vap *vap, 1037 const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2]) 1038 { 1039 struct ifnet *ifp = vap->iv_ifp; 1040 struct ieee80211_country_event iev; 1041 1042 memset(&iev, 0, sizeof(iev)); 1043 IEEE80211_ADDR_COPY(iev.iev_addr, bssid); 1044 iev.iev_cc[0] = cc[0]; 1045 iev.iev_cc[1] = cc[1]; 1046 CURVNET_SET(ifp->if_vnet); 1047 rt_ieee80211msg(ifp, RTM_IEEE80211_COUNTRY, &iev, sizeof(iev)); 1048 CURVNET_RESTORE(); 1049 } 1050 1051 void 1052 ieee80211_notify_radio(struct ieee80211com *ic, int state) 1053 { 1054 struct ieee80211_radio_event iev; 1055 struct ieee80211vap *vap; 1056 struct ifnet *ifp; 1057 1058 memset(&iev, 0, sizeof(iev)); 1059 iev.iev_state = state; 1060 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 1061 ifp = vap->iv_ifp; 1062 CURVNET_SET(ifp->if_vnet); 1063 rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev)); 1064 CURVNET_RESTORE(); 1065 } 1066 } 1067 1068 void 1069 ieee80211_notify_ifnet_change(struct ieee80211vap *vap, int if_flags_mask) 1070 { 1071 struct ifnet *ifp = vap->iv_ifp; 1072 1073 IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, "%s\n", 1074 "interface state change"); 1075 1076 CURVNET_SET(ifp->if_vnet); 1077 rt_ifmsg(ifp, if_flags_mask); 1078 CURVNET_RESTORE(); 1079 } 1080 1081 void 1082 ieee80211_load_module(const char *modname) 1083 { 1084 1085 #ifdef notyet 1086 (void)kern_kldload(curthread, modname, NULL); 1087 #else 1088 printf("%s: load the %s module by hand for now.\n", __func__, modname); 1089 #endif 1090 } 1091 1092 static eventhandler_tag wlan_bpfevent; 1093 static eventhandler_tag wlan_ifllevent; 1094 1095 static void 1096 bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach) 1097 { 1098 /* NB: identify vap's by if_init */ 1099 if (dlt == DLT_IEEE802_11_RADIO && 1100 ifp->if_init == ieee80211_init) { 1101 struct ieee80211vap *vap = ifp->if_softc; 1102 /* 1103 * Track bpf radiotap listener state. We mark the vap 1104 * to indicate if any listener is present and the com 1105 * to indicate if any listener exists on any associated 1106 * vap. This flag is used by drivers to prepare radiotap 1107 * state only when needed. 1108 */ 1109 if (attach) { 1110 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF); 1111 if (vap->iv_opmode == IEEE80211_M_MONITOR) 1112 atomic_add_int(&vap->iv_ic->ic_montaps, 1); 1113 } else if (!bpf_peers_present(vap->iv_rawbpf)) { 1114 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF); 1115 if (vap->iv_opmode == IEEE80211_M_MONITOR) 1116 atomic_subtract_int(&vap->iv_ic->ic_montaps, 1); 1117 } 1118 } 1119 } 1120 1121 /* 1122 * Change MAC address on the vap (if was not started). 1123 */ 1124 static void 1125 wlan_iflladdr(void *arg __unused, struct ifnet *ifp) 1126 { 1127 /* NB: identify vap's by if_init */ 1128 if (ifp->if_init == ieee80211_init && 1129 (ifp->if_flags & IFF_UP) == 0) { 1130 struct ieee80211vap *vap = ifp->if_softc; 1131 1132 IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp)); 1133 } 1134 } 1135 1136 /* 1137 * Fetch the VAP name. 1138 * 1139 * This returns a const char pointer suitable for debugging, 1140 * but don't expect it to stick around for much longer. 1141 */ 1142 const char * 1143 ieee80211_get_vap_ifname(struct ieee80211vap *vap) 1144 { 1145 if (vap->iv_ifp == NULL) 1146 return "(none)"; 1147 return (if_name(vap->iv_ifp)); 1148 } 1149 1150 #ifdef DEBUGNET 1151 static void 1152 ieee80211_debugnet_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize) 1153 { 1154 struct ieee80211vap *vap; 1155 struct ieee80211com *ic; 1156 1157 vap = if_getsoftc(ifp); 1158 ic = vap->iv_ic; 1159 1160 IEEE80211_LOCK(ic); 1161 ic->ic_debugnet_meth->dn8_init(ic, nrxr, ncl, clsize); 1162 IEEE80211_UNLOCK(ic); 1163 } 1164 1165 static void 1166 ieee80211_debugnet_event(struct ifnet *ifp, enum debugnet_ev ev) 1167 { 1168 struct ieee80211vap *vap; 1169 struct ieee80211com *ic; 1170 1171 vap = if_getsoftc(ifp); 1172 ic = vap->iv_ic; 1173 1174 IEEE80211_LOCK(ic); 1175 ic->ic_debugnet_meth->dn8_event(ic, ev); 1176 IEEE80211_UNLOCK(ic); 1177 } 1178 1179 static int 1180 ieee80211_debugnet_transmit(struct ifnet *ifp, struct mbuf *m) 1181 { 1182 return (ieee80211_vap_transmit(ifp, m)); 1183 } 1184 1185 static int 1186 ieee80211_debugnet_poll(struct ifnet *ifp, int count) 1187 { 1188 struct ieee80211vap *vap; 1189 struct ieee80211com *ic; 1190 1191 vap = if_getsoftc(ifp); 1192 ic = vap->iv_ic; 1193 1194 return (ic->ic_debugnet_meth->dn8_poll(ic, count)); 1195 } 1196 #endif 1197 1198 /** 1199 * @brief Check if the MAC address was changed by the upper layer. 1200 * 1201 * This is specifically to handle cases like the MAC address 1202 * being changed via an ioctl (eg SIOCSIFLLADDR). 1203 * 1204 * @param vap VAP to sync MAC address for 1205 */ 1206 void 1207 ieee80211_vap_sync_mac_address(struct ieee80211vap *vap) 1208 { 1209 struct epoch_tracker et; 1210 const struct ifnet *ifp = vap->iv_ifp; 1211 1212 /* 1213 * Check if the MAC address was changed 1214 * via SIOCSIFLLADDR ioctl. 1215 * 1216 * NB: device may be detached during initialization; 1217 * use if_ioctl for existence check. 1218 */ 1219 NET_EPOCH_ENTER(et); 1220 if (ifp->if_ioctl == ieee80211_ioctl && 1221 (ifp->if_flags & IFF_UP) == 0 && 1222 !IEEE80211_ADDR_EQ(vap->iv_myaddr, IF_LLADDR(ifp))) 1223 IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp)); 1224 NET_EPOCH_EXIT(et); 1225 } 1226 1227 /** 1228 * @brief Initial MAC address setup for a VAP. 1229 * 1230 * @param vap VAP to sync MAC address for 1231 */ 1232 void 1233 ieee80211_vap_copy_mac_address(struct ieee80211vap *vap) 1234 { 1235 struct epoch_tracker et; 1236 1237 NET_EPOCH_ENTER(et); 1238 IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(vap->iv_ifp)); 1239 NET_EPOCH_EXIT(et); 1240 } 1241 1242 /** 1243 * @brief Deliver data into the upper ifp of the VAP interface 1244 * 1245 * This delivers an 802.3 frame from net80211 up to the operating 1246 * system network interface layer. 1247 * 1248 * @param vap the current VAP 1249 * @param m the 802.3 frame to pass up to the VAP interface 1250 * 1251 * Note: this API consumes the mbuf. 1252 */ 1253 void 1254 ieee80211_vap_deliver_data(struct ieee80211vap *vap, struct mbuf *m) 1255 { 1256 struct epoch_tracker et; 1257 1258 NET_EPOCH_ENTER(et); 1259 if_input(vap->iv_ifp, m); 1260 NET_EPOCH_EXIT(et); 1261 } 1262 1263 /** 1264 * @brief Return whether the VAP is configured with monitor mode 1265 * 1266 * This checks the operating system layer for whether monitor mode 1267 * is enabled. 1268 * 1269 * @param vap the current VAP 1270 * @retval true if the underlying interface is in MONITOR mode, false otherwise 1271 */ 1272 bool 1273 ieee80211_vap_ifp_check_is_monitor(struct ieee80211vap *vap) 1274 { 1275 return ((if_getflags(vap->iv_ifp) & IFF_MONITOR) != 0); 1276 } 1277 1278 /** 1279 * @brief Return whether the VAP is configured in simplex mode. 1280 * 1281 * This checks the operating system layer for whether simplex mode 1282 * is enabled. 1283 * 1284 * @param vap the current VAP 1285 * @retval true if the underlying interface is in SIMPLEX mode, false otherwise 1286 */ 1287 bool 1288 ieee80211_vap_ifp_check_is_simplex(struct ieee80211vap *vap) 1289 { 1290 return ((if_getflags(vap->iv_ifp) & IFF_SIMPLEX) != 0); 1291 } 1292 1293 /** 1294 * @brief Return if the VAP underlying network interface is running 1295 * 1296 * @param vap the current VAP 1297 * @retval true if the underlying interface is running; false otherwise 1298 */ 1299 bool 1300 ieee80211_vap_ifp_check_is_running(struct ieee80211vap *vap) 1301 { 1302 return ((if_getdrvflags(vap->iv_ifp) & IFF_DRV_RUNNING) != 0); 1303 } 1304 1305 /** 1306 * @brief Change the VAP underlying network interface state 1307 * 1308 * @param vap the current VAP 1309 * @param state true to mark the interface as RUNNING, false to clear 1310 */ 1311 void 1312 ieee80211_vap_ifp_set_running_state(struct ieee80211vap *vap, bool state) 1313 { 1314 if (state) 1315 if_setdrvflagbits(vap->iv_ifp, IFF_DRV_RUNNING, 0); 1316 else 1317 if_setdrvflagbits(vap->iv_ifp, 0, IFF_DRV_RUNNING); 1318 } 1319 1320 /** 1321 * @brief Return the broadcast MAC address. 1322 * 1323 * @param vap The current VAP 1324 * @retval a uint8_t array representing the ethernet broadcast address 1325 */ 1326 const uint8_t * 1327 ieee80211_vap_get_broadcast_address(struct ieee80211vap *vap) 1328 { 1329 return (if_getbroadcastaddr(vap->iv_ifp)); 1330 } 1331 1332 /** 1333 * @brief net80211 printf() (not vap/ic related) 1334 */ 1335 void 1336 net80211_printf(const char *fmt, ...) 1337 { 1338 va_list ap; 1339 1340 va_start(ap, fmt); 1341 vprintf(fmt, ap); 1342 va_end(ap); 1343 } 1344 1345 /** 1346 * @brief VAP specific printf() 1347 */ 1348 void 1349 net80211_vap_printf(const struct ieee80211vap *vap, const char *fmt, ...) 1350 { 1351 char if_fmt[256]; 1352 va_list ap; 1353 1354 va_start(ap, fmt); 1355 snprintf(if_fmt, sizeof(if_fmt), "%s: %s", if_name(vap->iv_ifp), fmt); 1356 vlog(LOG_INFO, if_fmt, ap); 1357 va_end(ap); 1358 } 1359 1360 /** 1361 * @brief ic specific printf() 1362 */ 1363 void 1364 net80211_ic_printf(const struct ieee80211com *ic, const char *fmt, ...) 1365 { 1366 va_list ap; 1367 1368 /* 1369 * TODO: do the vap_printf stuff above, use vlog(LOG_INFO, ...) 1370 */ 1371 printf("%s: ", ic->ic_name); 1372 va_start(ap, fmt); 1373 vprintf(fmt, ap); 1374 va_end(ap); 1375 } 1376 1377 /* 1378 * Module glue. 1379 * 1380 * NB: the module name is "wlan" for compatibility with NetBSD. 1381 */ 1382 static int 1383 wlan_modevent(module_t mod, int type, void *unused) 1384 { 1385 switch (type) { 1386 case MOD_LOAD: 1387 if (bootverbose) 1388 printf("wlan: <802.11 Link Layer>\n"); 1389 wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track, 1390 bpf_track, 0, EVENTHANDLER_PRI_ANY); 1391 wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event, 1392 wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY); 1393 struct if_clone_addreq req = { 1394 .create_f = wlan_clone_create, 1395 .destroy_f = wlan_clone_destroy, 1396 .flags = IFC_F_AUTOUNIT, 1397 }; 1398 wlan_cloner = ifc_attach_cloner(wlanname, &req); 1399 return 0; 1400 case MOD_UNLOAD: 1401 ifc_detach_cloner(wlan_cloner); 1402 EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); 1403 EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent); 1404 return 0; 1405 } 1406 return EINVAL; 1407 } 1408 1409 static moduledata_t wlan_mod = { 1410 wlanname, 1411 wlan_modevent, 1412 0 1413 }; 1414 DECLARE_MODULE(wlan, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 1415 MODULE_VERSION(wlan, 1); 1416 MODULE_DEPEND(wlan, ether, 1, 1, 1); 1417 #ifdef IEEE80211_ALQ 1418 MODULE_DEPEND(wlan, alq, 1, 1, 1); 1419 #endif /* IEEE80211_ALQ */ 1420