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