ieee80211_netbsd.c revision 1.31.2.4 1 /* $NetBSD: ieee80211_netbsd.c,v 1.31.2.4 2018/07/20 20:33:05 phil Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5 *
6 * Copyright (c) 2003-2009 Sam Leffler, Errno Consulting
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 /* __FBSDID("$FreeBSD$"); */
32 __KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.31.2.4 2018/07/20 20:33:05 phil Exp $");
33
34 /*
35 * IEEE 802.11 support (NetBSD-specific code)
36 */
37
38 #include "opt_wlan.h"
39
40 #include <sys/atomic.h>
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/module.h>
47 #include <sys/proc.h>
48 #include <sys/sysctl.h>
49 #include <sys/syslog.h>
50
51 #include <sys/socket.h>
52
53 #include <net/bpf.h>
54 #include <net/if.h>
55 #include <net/if_dl.h>
56 #include <net/if_ether.h>
57 #include <net/if_media.h>
58 #include <net/if_types.h>
59 #include <net/route.h>
60
61 #include <net80211/ieee80211_var.h>
62 #include <net80211/ieee80211_input.h>
63
64 static const struct sysctlnode *
65 ieee80211_sysctl_treetop(struct sysctllog **log);
66 static void ieee80211_sysctl_setup(void);
67
68 /* NNN in .h file? */
69 #define SYSCTL_HANDLER_ARGS SYSCTLFN_ARGS
70
71 #ifdef IEEE80211_DEBUG
72 static int ieee80211_debug = 0;
73 #endif
74
75 #ifdef notyet
76 static struct if_clone *wlan_cloner;
77 #endif
78 /* notyet */
79
80 static const char wlanname[] = "wlan";
81
82 int
83 ieee80211_init0(void)
84 {
85 ieee80211_sysctl_setup();
86 return 0;
87 }
88
89 static __unused int
90 wlan_clone_create(struct if_clone *ifc, int unit, void * params)
91 {
92 struct ieee80211_clone_params cp;
93 struct ieee80211vap *vap;
94 struct ieee80211com *ic;
95 int error;
96
97 error = copyin(params, &cp, sizeof(cp));
98 if (error)
99 return error;
100 ic = ieee80211_find_com(cp.icp_parent);
101 if (ic == NULL)
102 return ENXIO;
103 if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
104 ic_printf(ic, "%s: invalid opmode %d\n", __func__,
105 cp.icp_opmode);
106 return EINVAL;
107 }
108 if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
109 ic_printf(ic, "%s mode not supported\n",
110 ieee80211_opmode_name[cp.icp_opmode]);
111 return EOPNOTSUPP;
112 }
113 if ((cp.icp_flags & IEEE80211_CLONE_TDMA) &&
114 #ifdef IEEE80211_SUPPORT_TDMA
115 (ic->ic_caps & IEEE80211_C_TDMA) == 0
116 #else
117 (1)
118 #endif
119 ) {
120 ic_printf(ic, "TDMA not supported\n");
121 return EOPNOTSUPP;
122 }
123 vap = ic->ic_vap_create(ic, wlanname, unit,
124 cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
125 cp.icp_flags & IEEE80211_CLONE_MACADDR ?
126 cp.icp_macaddr : ic->ic_macaddr);
127
128 return (vap == NULL ? EIO : 0);
129 }
130
131 static __unused void
132 wlan_clone_destroy(struct ifnet *ifp)
133 {
134 struct ieee80211vap *vap = ifp->if_softc;
135 struct ieee80211com *ic = vap->iv_ic;
136
137 ic->ic_vap_delete(vap);
138 }
139
140 void
141 ieee80211_vap_destroy(struct ieee80211vap *vap)
142 {
143 #ifdef notyet
144 CURVNET_SET(vap->iv_ifp->if_vnet);
145 if_clone_destroyif(wlan_cloner, vap->iv_ifp);
146 CURVNET_RESTORE();
147 #else
148 printf ("vap_destroy called ... what next?\n");
149 #endif
150 }
151
152 #ifdef notyet
153 int
154 ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS)
155 {
156 int msecs = ticks_to_msecs(*(int *)arg1);
157 int error, t;
158
159 error = sysctl_handle_int(oidp, &msecs, 0, req);
160 if (error || !req->newptr)
161 return error;
162 t = msecs_to_ticks(msecs);
163 *(int *)arg1 = (t < 1) ? 1 : t;
164 return 0;
165 }
166
167 static int
168 ieee80211_sysctl_inact(SYSCTL_HANDLER_ARGS)
169 {
170 int inact = (*(int *)arg1) * IEEE80211_INACT_WAIT;
171 int error;
172
173 error = sysctl_handle_int(oidp, &inact, 0, req);
174 if (error || !req->newptr)
175 return error;
176 *(int *)arg1 = inact / IEEE80211_INACT_WAIT;
177 return 0;
178 }
179 #endif
180
181 static int
182 ieee80211_sysctl_parent(SYSCTLFN_ARGS)
183 {
184 struct ieee80211vap *vap;
185 char pname[IFNAMSIZ];
186 struct sysctlnode node;
187
188 node = *rnode;
189 vap = node.sysctl_data;
190 strlcpy(pname, vap->iv_ifp->if_xname, IFNAMSIZ);
191 node.sysctl_data = pname;
192 return sysctl_lookup(SYSCTLFN_CALL(&node));
193 }
194
195 #ifdef notyet
196 static int
197 ieee80211_sysctl_radar(SYSCTL_HANDLER_ARGS)
198 {
199 struct ieee80211com *ic = arg1;
200 int t = 0, error;
201
202 error = sysctl_handle_int(oidp, &t, 0, req);
203 if (error || !req->newptr)
204 return error;
205 IEEE80211_LOCK(ic);
206 ieee80211_dfs_notify_radar(ic, ic->ic_curchan);
207 IEEE80211_UNLOCK(ic);
208 return 0;
209 }
210
211 /*
212 * For now, just restart everything.
213 *
214 * Later on, it'd be nice to have a separate VAP restart to
215 * full-device restart.
216 */
217 static int
218 ieee80211_sysctl_vap_restart(SYSCTL_HANDLER_ARGS)
219 {
220 struct ieee80211vap *vap = arg1;
221 int t = 0, error;
222
223 error = sysctl_handle_int(oidp, &t, 0, req);
224 if (error || !req->newptr)
225 return error;
226
227 ieee80211_restart_all(vap->iv_ic);
228 return 0;
229 }
230 #endif /* notyet */
231
232 void
233 ieee80211_sysctl_attach(struct ieee80211com *ic)
234 {
235 }
236
237 void
238 ieee80211_sysctl_detach(struct ieee80211com *ic)
239 {
240 }
241
242 /*
243 * Setup sysctl(3) MIB, net.ieee80211.*
244 *
245 * TBD condition CTLFLAG_PERMANENT on being a module or not
246 */
247 static struct sysctllog *ieee80211_sysctllog;
248 static void
249 ieee80211_sysctl_setup(void)
250 {
251 int rc;
252 const struct sysctlnode *rnode;
253
254 if ((rnode = ieee80211_sysctl_treetop(&ieee80211_sysctllog)) == NULL)
255 return;
256
257 #ifdef notyet
258 if ((rc = sysctl_createv(&ieee80211_sysctllog, 0, &rnode, NULL,
259 CTLFLAG_PERMANENT, CTLTYPE_NODE, "nodes", "client/peer stations",
260 ieee80211_sysctl_node, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
261 goto err;
262 #endif
263
264 #ifdef IEEE80211_DEBUG
265 /* control debugging printfs */
266 if ((rc = sysctl_createv(&ieee80211_sysctllog, 0, &rnode, NULL,
267 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
268 "debug", SYSCTL_DESCR("control debugging printfs"),
269 NULL, 0, &ieee80211_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
270 goto err;
271 #endif
272
273 #ifdef notyet
274 ieee80211_rssadapt_sysctl_setup(&ieee80211_sysctllog);
275 #endif
276
277 return;
278 err:
279 printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
280 }
281
282 /*
283 * Create or get top of sysctl tree net.link.ieee80211.
284 */
285 static const struct sysctlnode *
286 ieee80211_sysctl_treetop(struct sysctllog **log)
287 {
288 int rc;
289 const struct sysctlnode *rnode;
290
291 if ((rc = sysctl_createv(log, 0, NULL, &rnode,
292 CTLFLAG_PERMANENT, CTLTYPE_NODE, "link",
293 "link-layer statistics and controls",
294 NULL, 0, NULL, 0, CTL_NET, PF_LINK, CTL_EOL)) != 0)
295 goto err;
296
297 if ((rc = sysctl_createv(log, 0, &rnode, &rnode,
298 CTLFLAG_PERMANENT, CTLTYPE_NODE, "ieee80211",
299 "IEEE 802.11 WLAN statistics and controls",
300 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
301 goto err;
302
303 return rnode;
304 err:
305 printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
306 return NULL;
307 }
308
309 void
310 ieee80211_sysctl_vattach(struct ieee80211vap *vap)
311 {
312 int rc;
313 const struct sysctlnode *cnode, *rnode;
314 char num[sizeof("vap") + 14]; /* sufficient for 32 bits */
315
316 if ((rnode = ieee80211_sysctl_treetop(NULL)) == NULL)
317 return;
318
319 snprintf(num, sizeof(num), "vap%u", vap->iv_ifp->if_index);
320
321 if ((rc = sysctl_createv(&vap->iv_sysctllog, 0, &rnode, &rnode,
322 CTLFLAG_PERMANENT, CTLTYPE_NODE, num, SYSCTL_DESCR("virtual AP"),
323 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
324 goto err;
325
326 /* control debugging printfs */
327 if ((rc = sysctl_createv(&vap->iv_sysctllog, 0, &rnode, &cnode,
328 CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRING,
329 "parent", SYSCTL_DESCR("parent device"),
330 ieee80211_sysctl_parent, 0, (void *)vap, IFNAMSIZ,
331 CTL_CREATE, CTL_EOL)) != 0)
332 goto err;
333
334
335 #ifdef notyet
336 struct ifnet *ifp = vap->iv_ifp;
337 struct sysctl_ctx_list *ctx;
338 struct sysctl_oid *oid;
339 char num[14]; /* sufficient for 32 bits */
340
341 ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list),
342 M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
343 if (ctx == NULL) {
344 if_printf(ifp, "%s: cannot allocate sysctl context!\n",
345 __func__);
346 return;
347 }
348 sysctl_ctx_init(ctx);
349 snprintf(num, sizeof(num), "%u", ifp->if_dunit);
350 oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan),
351 OID_AUTO, num, CTLFLAG_RD, NULL, "");
352 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
353 "%parent", CTLTYPE_STRING | CTLFLAG_RD, vap->iv_ic, 0,
354 ieee80211_sysctl_parent, "A", "parent device");
355 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
356 "driver_caps", CTLFLAG_RW, &vap->iv_caps, 0,
357 "driver capabilities");
358 #ifdef IEEE80211_DEBUG
359 vap->iv_debug = ieee80211_debug;
360 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
361 "debug", CTLFLAG_RW, &vap->iv_debug, 0,
362 "control debugging printfs");
363 #endif
364 SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
365 "bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0,
366 "consecutive beacon misses before scanning");
367 /* XXX inherit from tunables */
368 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
369 "inact_run", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_run, 0,
370 ieee80211_sysctl_inact, "I",
371 "station inactivity timeout (sec)");
372 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
373 "inact_probe", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_probe, 0,
374 ieee80211_sysctl_inact, "I",
375 "station inactivity probe timeout (sec)");
376 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
377 "inact_auth", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_auth, 0,
378 ieee80211_sysctl_inact, "I",
379 "station authentication timeout (sec)");
380 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
381 "inact_init", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_init, 0,
382 ieee80211_sysctl_inact, "I",
383 "station initial state timeout (sec)");
384 if (vap->iv_htcaps & IEEE80211_HTC_HT) {
385 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
386 "ampdu_mintraffic_bk", CTLFLAG_RW,
387 &vap->iv_ampdu_mintraffic[WME_AC_BK], 0,
388 "BK traffic tx aggr threshold (pps)");
389 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
390 "ampdu_mintraffic_be", CTLFLAG_RW,
391 &vap->iv_ampdu_mintraffic[WME_AC_BE], 0,
392 "BE traffic tx aggr threshold (pps)");
393 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
394 "ampdu_mintraffic_vo", CTLFLAG_RW,
395 &vap->iv_ampdu_mintraffic[WME_AC_VO], 0,
396 "VO traffic tx aggr threshold (pps)");
397 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
398 "ampdu_mintraffic_vi", CTLFLAG_RW,
399 &vap->iv_ampdu_mintraffic[WME_AC_VI], 0,
400 "VI traffic tx aggr threshold (pps)");
401 }
402
403 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
404 "force_restart", CTLTYPE_INT | CTLFLAG_RW, vap, 0,
405 ieee80211_sysctl_vap_restart, "I",
406 "force a VAP restart");
407
408 if (vap->iv_caps & IEEE80211_C_DFS) {
409 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
410 "radar", CTLTYPE_INT | CTLFLAG_RW, vap->iv_ic, 0,
411 ieee80211_sysctl_radar, "I", "simulate radar event");
412 }
413 vap->iv_sysctl = ctx;
414 vap->iv_oid = oid;
415 #endif
416 return;
417 err:
418 printf("%s: sysctl_createv failed, rc = %d\n", __func__, rc);
419 }
420
421 void
422 ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
423 {
424 #ifdef notyet
425 if (vap->iv_sysctl != NULL) {
426 sysctl_ctx_free(vap->iv_sysctl);
427 IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF);
428 vap->iv_sysctl = NULL;
429 }
430 #endif
431 }
432
433
434 int
435 ieee80211_node_dectestref(struct ieee80211_node *ni)
436 {
437 /* XXX need equivalent of atomic_dec_and_test */
438 atomic_subtract_int(&ni->ni_refcnt, 1);
439 return atomic_cas_uint(&ni->ni_refcnt, 0, 1) == 0;
440 }
441
442 void
443 ieee80211_drain_ifq(struct ifqueue *ifq)
444 {
445 struct ieee80211_node *ni;
446 struct mbuf *m;
447
448 for (;;) {
449 IF_DEQUEUE(ifq, m);
450 if (m == NULL)
451 break;
452
453 ni = (struct ieee80211_node *)m_get_rcvif_NOMPSAFE(m);
454 FBSDKASSERT(ni != NULL, ("frame w/o node"));
455 ieee80211_free_node(ni);
456 ieee80211_free_mbuf(m);
457 }
458 }
459
460 void
461 ieee80211_flush_ifq(struct ifqueue *ifq, struct ieee80211vap *vap)
462 {
463 struct ieee80211_node *ni;
464 struct mbuf *m, **mprev;
465
466 IFQ_LOCK(ifq);
467 mprev = &ifq->ifq_head;
468 while ((m = *mprev) != NULL) {
469 ni = (struct ieee80211_node *)m_get_rcvif_NOMPSAFE(m);
470 if (ni != NULL && ni->ni_vap == vap) {
471 *mprev = m->m_nextpkt; /* remove from list */
472 ifq->ifq_len--;
473
474 ieee80211_free_node(ni); /* reclaim ref */
475 ieee80211_free_mbuf(m);
476 } else
477 mprev = &m->m_nextpkt;
478 }
479 /* recalculate tail ptr */
480 m = ifq->ifq_head;
481 for (; m != NULL && m->m_nextpkt != NULL; m = m->m_nextpkt)
482 ;
483 ifq->ifq_tail = m;
484 IFQ_UNLOCK(ifq);
485 }
486
487 /*
488 * As above, for mbufs allocated with m_gethdr/MGETHDR
489 * or initialized by M_COPY_PKTHDR.
490 */
491 #define MC_ALIGN(m, len) \
492 do { \
493 (m)->m_data += rounddown2(MCLBYTES - (len), sizeof(long)); \
494 } while (/* CONSTCOND */ 0)
495
496 /*
497 * Allocate and setup a management frame of the specified
498 * size. We return the mbuf and a pointer to the start
499 * of the contiguous data area that's been reserved based
500 * on the packet length. The data area is forced to 32-bit
501 * alignment and the buffer length to a multiple of 4 bytes.
502 * This is done mainly so beacon frames (that require this)
503 * can use this interface too.
504 */
505 struct mbuf *
506 ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen)
507 {
508 struct mbuf *m;
509 u_int len;
510
511 /*
512 * NB: we know the mbuf routines will align the data area
513 * so we don't need to do anything special.
514 */
515 len = roundup2(headroom + pktlen, 4);
516 FBSDKASSERT(len <= MCLBYTES, ("802.11 mgt frame too large: %u", len));
517 if (len < MINCLSIZE) {
518 m = m_gethdr(M_NOWAIT, MT_DATA);
519 /*
520 * Align the data in case additional headers are added.
521 * This should only happen when a WEP header is added
522 * which only happens for shared key authentication mgt
523 * frames which all fit in MHLEN.
524 */
525 if (m != NULL)
526 M_ALIGN(m, len);
527 } else {
528 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
529 if (m != NULL)
530 MC_ALIGN(m, len);
531 }
532 if (m != NULL) {
533 m->m_data += headroom;
534 *frm = m->m_data;
535 }
536 return m;
537 }
538
539 #ifndef __NO_STRICT_ALIGNMENT
540 /*
541 * Re-align the payload in the mbuf. This is mainly used (right now)
542 * to handle IP header alignment requirements on certain architectures.
543 */
544 struct mbuf *
545 ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
546 {
547 int pktlen, space;
548 struct mbuf *n;
549
550 pktlen = m->m_pkthdr.len;
551 space = pktlen + align;
552 if (space < MINCLSIZE)
553 n = m_gethdr(M_NOWAIT, MT_DATA);
554 else {
555 n = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
556 space <= MCLBYTES ? MCLBYTES :
557 #if MJUMPAGESIZE != MCLBYTES
558 space <= MJUMPAGESIZE ? MJUMPAGESIZE :
559 #endif
560 space <= MJUM9BYTES ? MJUM9BYTES : MJUM16BYTES);
561 }
562 if (__predict_true(n != NULL)) {
563 m_move_pkthdr(n, m);
564 n->m_data = (caddr_t)(ALIGN(n->m_data + align) - align);
565 m_copydata(m, 0, pktlen, mtod(n, caddr_t));
566 n->m_len = pktlen;
567 } else {
568 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
569 mtod(m, const struct ieee80211_frame *), NULL,
570 "%s", "no mbuf to realign");
571 vap->iv_stats.is_rx_badalign++;
572 }
573 m_freem(m);
574 return n;
575 }
576 #endif /* !__NO_STRICT_ALIGNMENT */
577
578 int
579 ieee80211_add_callback(struct mbuf *m,
580 void (*func)(struct ieee80211_node *, void *, int), void *arg)
581 {
582 struct m_tag *mtag;
583 struct ieee80211_cb *cb;
584
585 mtag = m_tag_get(/*MTAG_ABI_NET80211*/ NET80211_TAG_CALLBACK,
586 sizeof(struct ieee80211_cb), M_NOWAIT);
587 if (mtag == NULL)
588 return 0;
589
590 cb = (struct ieee80211_cb *)(mtag+1);
591 cb->func = func;
592 cb->arg = arg;
593 m_tag_prepend(m, mtag);
594 m->m_flags |= M_TXCB;
595 return 1;
596 }
597
598 int
599 ieee80211_add_xmit_params(struct mbuf *m,
600 const struct ieee80211_bpf_params *params)
601 {
602 struct m_tag *mtag;
603 struct ieee80211_tx_params *tx;
604
605 mtag = m_tag_get(/*MTAG_ABI_NET80211*/ NET80211_TAG_XMIT_PARAMS,
606 sizeof(struct ieee80211_tx_params), M_NOWAIT);
607 if (mtag == NULL)
608 return (0);
609
610 tx = (struct ieee80211_tx_params *)(mtag+1);
611 memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
612 m_tag_prepend(m, mtag);
613 return (1);
614 }
615
616 int
617 ieee80211_get_xmit_params(struct mbuf *m,
618 struct ieee80211_bpf_params *params)
619 {
620 struct m_tag *mtag;
621 struct ieee80211_tx_params *tx;
622
623 mtag = m_tag_find(m, /*MTAG_ABI_NET80211,*/ NET80211_TAG_XMIT_PARAMS,
624 NULL);
625 if (mtag == NULL)
626 return (-1);
627 tx = (struct ieee80211_tx_params *)(mtag + 1);
628 memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
629 return (0);
630 }
631
632 void
633 ieee80211_process_callback(struct ieee80211_node *ni,
634 struct mbuf *m, int status)
635 {
636 struct m_tag *mtag;
637
638 mtag = m_tag_find(m, /*MTAG_ABI_NET80211,*/ NET80211_TAG_CALLBACK, NULL);
639 if (mtag != NULL) {
640 struct ieee80211_cb *cb = (struct ieee80211_cb *)(mtag+1);
641 cb->func(ni, cb->arg, status);
642 }
643 }
644
645 /*
646 * Add RX parameters to the given mbuf.
647 *
648 * Returns 1 if OK, 0 on error.
649 */
650 int
651 ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
652 {
653 struct m_tag *mtag;
654 struct ieee80211_rx_params *rx;
655
656 mtag = m_tag_get(/*MTAG_ABI_NET80211,*/ NET80211_TAG_RECV_PARAMS,
657 sizeof(struct ieee80211_rx_stats), M_NOWAIT);
658 if (mtag == NULL)
659 return (0);
660
661 rx = (struct ieee80211_rx_params *)(mtag + 1);
662 memcpy(&rx->params, rxs, sizeof(*rxs));
663 m_tag_prepend(m, mtag);
664 return (1);
665 }
666
667 int
668 ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
669 {
670 struct m_tag *mtag;
671 struct ieee80211_rx_params *rx;
672
673 mtag = m_tag_find(m, /*MTAG_ABI_NET80211,*/ NET80211_TAG_RECV_PARAMS,
674 NULL);
675 if (mtag == NULL)
676 return (-1);
677 rx = (struct ieee80211_rx_params *)(mtag + 1);
678 memcpy(rxs, &rx->params, sizeof(*rxs));
679 return (0);
680 }
681
682 const struct ieee80211_rx_stats *
683 ieee80211_get_rx_params_ptr(struct mbuf *m)
684 {
685 struct m_tag *mtag;
686 struct ieee80211_rx_params *rx;
687
688 mtag = m_tag_find(m, /*MTAG_ABI_NET80211,*/ NET80211_TAG_RECV_PARAMS,
689 NULL);
690 if (mtag == NULL)
691 return (NULL);
692 rx = (struct ieee80211_rx_params *)(mtag + 1);
693 return (&rx->params);
694 }
695
696
697 /*
698 * Add TOA parameters to the given mbuf.
699 */
700 int
701 ieee80211_add_toa_params(struct mbuf *m, const struct ieee80211_toa_params *p)
702 {
703 struct m_tag *mtag;
704 struct ieee80211_toa_params *rp;
705
706 mtag = m_tag_get(/*MTAG_ABI_NET80211,*/ NET80211_TAG_TOA_PARAMS,
707 sizeof(struct ieee80211_toa_params), M_NOWAIT);
708 if (mtag == NULL)
709 return (0);
710
711 rp = (struct ieee80211_toa_params *)(mtag + 1);
712 memcpy(rp, p, sizeof(*rp));
713 m_tag_prepend(m, mtag);
714 return (1);
715 }
716
717 int
718 ieee80211_get_toa_params(struct mbuf *m, struct ieee80211_toa_params *p)
719 {
720 struct m_tag *mtag;
721 struct ieee80211_toa_params *rp;
722
723 mtag = m_tag_find(m, /*MTAG_ABI_NET80211,*/ NET80211_TAG_TOA_PARAMS,
724 NULL);
725 if (mtag == NULL)
726 return (0);
727 rp = (struct ieee80211_toa_params *)(mtag + 1);
728 if (p != NULL)
729 memcpy(p, rp, sizeof(*p));
730 return (1);
731 }
732
733 /*
734 * Transmit a frame to the parent interface.
735 */
736 int
737 ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
738 {
739 int error;
740
741 /*
742 * Assert the IC TX lock is held - this enforces the
743 * processing -> queuing order is maintained
744 */
745 IEEE80211_TX_LOCK_ASSERT(ic);
746 error = ic->ic_transmit(ic, m);
747 if (error) {
748 struct ieee80211_node *ni;
749
750 ni = (struct ieee80211_node *)m_get_rcvif_NOMPSAFE(m);
751
752 /* XXX number of fragments */
753 if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
754 ieee80211_free_node(ni);
755 ieee80211_free_mbuf(m);
756 }
757 return (error);
758 }
759
760 /*
761 * Transmit a frame to the VAP interface.
762 */
763 int
764 ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
765 {
766 struct ifnet *ifp = vap->iv_ifp;
767
768 /*
769 * When transmitting via the VAP, we shouldn't hold
770 * any IC TX lock as the VAP TX path will acquire it.
771 */
772 IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
773
774 return (ifp->if_transmit(ifp, m));
775
776 }
777
778 void
779 get_random_bytes(void *p, size_t n)
780 {
781 uint8_t *dp = p;
782
783 while (n > 0) {
784 uint32_t v = arc4random();
785 size_t nb = n > sizeof(uint32_t) ? sizeof(uint32_t) : n;
786 bcopy(&v, dp, n > sizeof(uint32_t) ? sizeof(uint32_t) : n);
787 dp += sizeof(uint32_t), n -= nb;
788 }
789 }
790
791 /*
792 * Helper function for events that pass just a single mac address.
793 */
794 static void
795 notify_macaddr(struct ifnet *ifp, int op, const uint8_t mac[IEEE80211_ADDR_LEN])
796 {
797 struct ieee80211_join_event iev;
798
799 CURVNET_SET(ifp->if_vnet);
800 memset(&iev, 0, sizeof(iev));
801 IEEE80211_ADDR_COPY(iev.iev_addr, mac);
802 rt_ieee80211msg(ifp, op, &iev, sizeof(iev));
803 CURVNET_RESTORE();
804 }
805
806 void
807 ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
808 {
809 struct ieee80211vap *vap = ni->ni_vap;
810 struct ifnet *ifp = vap->iv_ifp;
811
812 CURVNET_SET_QUIET(ifp->if_vnet);
813 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode join",
814 (ni == vap->iv_bss) ? "bss " : "");
815
816 if (ni == vap->iv_bss) {
817 notify_macaddr(ifp, newassoc ?
818 RTM_IEEE80211_ASSOC : RTM_IEEE80211_REASSOC, ni->ni_bssid);
819 if_link_state_change(ifp, LINK_STATE_UP);
820 } else {
821 notify_macaddr(ifp, newassoc ?
822 RTM_IEEE80211_JOIN : RTM_IEEE80211_REJOIN, ni->ni_macaddr);
823 }
824 CURVNET_RESTORE();
825 }
826
827 void
828 ieee80211_notify_node_leave(struct ieee80211_node *ni)
829 {
830 struct ieee80211vap *vap = ni->ni_vap;
831 struct ifnet *ifp = vap->iv_ifp;
832
833 CURVNET_SET_QUIET(ifp->if_vnet);
834 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%snode leave",
835 (ni == vap->iv_bss) ? "bss " : "");
836
837 if (ni == vap->iv_bss) {
838 rt_ieee80211msg(ifp, RTM_IEEE80211_DISASSOC, NULL, 0);
839 if_link_state_change(ifp, LINK_STATE_DOWN);
840 } else {
841 /* fire off wireless event station leaving */
842 notify_macaddr(ifp, RTM_IEEE80211_LEAVE, ni->ni_macaddr);
843 }
844 CURVNET_RESTORE();
845 }
846
847 void
848 ieee80211_notify_scan_done(struct ieee80211vap *vap)
849 {
850 struct ifnet *ifp = vap->iv_ifp;
851
852 IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s\n", "notify scan done");
853
854 /* dispatch wireless event indicating scan completed */
855 CURVNET_SET(ifp->if_vnet);
856 rt_ieee80211msg(ifp, RTM_IEEE80211_SCAN, NULL, 0);
857 CURVNET_RESTORE();
858 }
859
860 void
861 ieee80211_notify_replay_failure(struct ieee80211vap *vap,
862 const struct ieee80211_frame *wh, const struct ieee80211_key *k,
863 u_int64_t rsc, int tid)
864 {
865 struct ifnet *ifp = vap->iv_ifp;
866
867 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
868 "%s replay detected tid %d <rsc %ju, csc %ju, keyix %u rxkeyix %u>",
869 k->wk_cipher->ic_name, tid, (intmax_t) rsc,
870 (intmax_t) k->wk_keyrsc[tid],
871 k->wk_keyix, k->wk_rxkeyix);
872
873 if (ifp != NULL) { /* NB: for cipher test modules */
874 struct ieee80211_replay_event iev;
875
876 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
877 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
878 iev.iev_cipher = k->wk_cipher->ic_cipher;
879 if (k->wk_rxkeyix != IEEE80211_KEYIX_NONE)
880 iev.iev_keyix = k->wk_rxkeyix;
881 else
882 iev.iev_keyix = k->wk_keyix;
883 iev.iev_keyrsc = k->wk_keyrsc[tid];
884 iev.iev_rsc = rsc;
885 CURVNET_SET(ifp->if_vnet);
886 rt_ieee80211msg(ifp, RTM_IEEE80211_REPLAY, &iev, sizeof(iev));
887 CURVNET_RESTORE();
888 }
889 }
890
891 void
892 ieee80211_notify_michael_failure(struct ieee80211vap *vap,
893 const struct ieee80211_frame *wh, u_int keyix)
894 {
895 struct ifnet *ifp = vap->iv_ifp;
896
897 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_CRYPTO, wh->i_addr2,
898 "michael MIC verification failed <keyix %u>", keyix);
899 vap->iv_stats.is_rx_tkipmic++;
900
901 if (ifp != NULL) { /* NB: for cipher test modules */
902 struct ieee80211_michael_event iev;
903
904 IEEE80211_ADDR_COPY(iev.iev_dst, wh->i_addr1);
905 IEEE80211_ADDR_COPY(iev.iev_src, wh->i_addr2);
906 iev.iev_cipher = IEEE80211_CIPHER_TKIP;
907 iev.iev_keyix = keyix;
908 CURVNET_SET(ifp->if_vnet);
909 rt_ieee80211msg(ifp, RTM_IEEE80211_MICHAEL, &iev, sizeof(iev));
910 CURVNET_RESTORE();
911 }
912 }
913
914 void
915 ieee80211_notify_wds_discover(struct ieee80211_node *ni)
916 {
917 struct ieee80211vap *vap = ni->ni_vap;
918 struct ifnet *ifp = vap->iv_ifp;
919
920 notify_macaddr(ifp, RTM_IEEE80211_WDS, ni->ni_macaddr);
921 }
922
923 void
924 ieee80211_notify_csa(struct ieee80211com *ic,
925 const struct ieee80211_channel *c, int mode, int count)
926 {
927 struct ieee80211_csa_event iev;
928 struct ieee80211vap *vap;
929 struct ifnet *ifp;
930
931 memset(&iev, 0, sizeof(iev));
932 iev.iev_flags = c->ic_flags;
933 iev.iev_freq = c->ic_freq;
934 iev.iev_ieee = c->ic_ieee;
935 iev.iev_mode = mode;
936 iev.iev_count = count;
937 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
938 ifp = vap->iv_ifp;
939 CURVNET_SET(ifp->if_vnet);
940 rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
941 CURVNET_RESTORE();
942 }
943 }
944
945 void
946 ieee80211_notify_radar(struct ieee80211com *ic,
947 const struct ieee80211_channel *c)
948 {
949 struct ieee80211_radar_event iev;
950 struct ieee80211vap *vap;
951 struct ifnet *ifp;
952
953 memset(&iev, 0, sizeof(iev));
954 iev.iev_flags = c->ic_flags;
955 iev.iev_freq = c->ic_freq;
956 iev.iev_ieee = c->ic_ieee;
957 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
958 ifp = vap->iv_ifp;
959 CURVNET_SET(ifp->if_vnet);
960 rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
961 CURVNET_RESTORE();
962 }
963 }
964
965 void
966 ieee80211_notify_cac(struct ieee80211com *ic,
967 const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
968 {
969 struct ieee80211_cac_event iev;
970 struct ieee80211vap *vap;
971 struct ifnet *ifp;
972
973 memset(&iev, 0, sizeof(iev));
974 iev.iev_flags = c->ic_flags;
975 iev.iev_freq = c->ic_freq;
976 iev.iev_ieee = c->ic_ieee;
977 iev.iev_type = type;
978 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
979 ifp = vap->iv_ifp;
980 CURVNET_SET(ifp->if_vnet);
981 rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
982 CURVNET_RESTORE();
983 }
984 }
985
986 void
987 ieee80211_notify_node_deauth(struct ieee80211_node *ni)
988 {
989 struct ieee80211vap *vap = ni->ni_vap;
990 struct ifnet *ifp = vap->iv_ifp;
991
992 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node deauth");
993
994 notify_macaddr(ifp, RTM_IEEE80211_DEAUTH, ni->ni_macaddr);
995 }
996
997 void
998 ieee80211_notify_node_auth(struct ieee80211_node *ni)
999 {
1000 struct ieee80211vap *vap = ni->ni_vap;
1001 struct ifnet *ifp = vap->iv_ifp;
1002
1003 IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node auth");
1004
1005 notify_macaddr(ifp, RTM_IEEE80211_AUTH, ni->ni_macaddr);
1006 }
1007
1008 void
1009 ieee80211_notify_country(struct ieee80211vap *vap,
1010 const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t cc[2])
1011 {
1012 struct ifnet *ifp = vap->iv_ifp;
1013 struct ieee80211_country_event iev;
1014
1015 memset(&iev, 0, sizeof(iev));
1016 IEEE80211_ADDR_COPY(iev.iev_addr, bssid);
1017 iev.iev_cc[0] = cc[0];
1018 iev.iev_cc[1] = cc[1];
1019 CURVNET_SET(ifp->if_vnet);
1020 rt_ieee80211msg(ifp, RTM_IEEE80211_COUNTRY, &iev, sizeof(iev));
1021 CURVNET_RESTORE();
1022 }
1023
1024 void
1025 ieee80211_notify_radio(struct ieee80211com *ic, int state)
1026 {
1027 struct ieee80211_radio_event iev;
1028 struct ieee80211vap *vap;
1029 struct ifnet *ifp;
1030
1031 memset(&iev, 0, sizeof(iev));
1032 iev.iev_state = state;
1033 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
1034 ifp = vap->iv_ifp;
1035 CURVNET_SET(ifp->if_vnet);
1036 rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
1037 CURVNET_RESTORE();
1038 }
1039 }
1040
1041 #ifdef notyet
1042 void
1043 ieee80211_load_module(const char *modname)
1044 {
1045 struct thread *td = curthread;
1046
1047 if (suser(td) == 0 && securelevel_gt(td->td_ucred, 0) == 0) {
1048 mtx_lock(&Giant);
1049 (void) linker_load_module(modname, NULL, NULL, NULL, NULL);
1050 mtx_unlock(&Giant);
1051 }
1052 }
1053 #endif
1054
1055 #ifdef notyet
1056 static eventhandler_tag wlan_bpfevent;
1057 static eventhandler_tag wlan_ifllevent;
1058
1059 static void
1060 bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
1061 {
1062 /* NB: identify vap's by if_init */
1063 if (dlt == DLT_IEEE802_11_RADIO &&
1064 ifp->if_init == ieee80211_init) {
1065 struct ieee80211vap *vap = ifp->if_softc;
1066 /*
1067 * Track bpf radiotap listener state. We mark the vap
1068 * to indicate if any listener is present and the com
1069 * to indicate if any listener exists on any associated
1070 * vap. This flag is used by drivers to prepare radiotap
1071 * state only when needed.
1072 */
1073 if (attach) {
1074 ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF);
1075 if (vap->iv_opmode == IEEE80211_M_MONITOR)
1076 atomic_add_int(&vap->iv_ic->ic_montaps, 1);
1077 } else if (!bpf_peers_present(vap->iv_rawbpf)) {
1078 ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF);
1079 if (vap->iv_opmode == IEEE80211_M_MONITOR)
1080 atomic_subtract_int(&vap->iv_ic->ic_montaps, 1);
1081 }
1082 }
1083 }
1084
1085 /*
1086 * Change MAC address on the vap (if was not started).
1087 */
1088 static void
1089 wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
1090 {
1091 /* NB: identify vap's by if_init */
1092 if (ifp->if_init == ieee80211_init &&
1093 (ifp->if_flags & IFF_UP) == 0) {
1094 struct ieee80211vap *vap = ifp->if_softc;
1095
1096 IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
1097 }
1098 }
1099 #endif
1100
1101 void
1102 if_inc_counter(struct ifnet *ifp, ift_counter ifc, int64_t value)
1103 {
1104 switch (ifc) {
1105 case IFCOUNTER_IPACKETS:
1106 ifp->if_data.ifi_ipackets += value;
1107 break;
1108 case IFCOUNTER_IERRORS:
1109 ifp->if_data.ifi_ierrors += value;
1110 break;
1111 case IFCOUNTER_OPACKETS:
1112 ifp->if_data.ifi_opackets += value;
1113 break;
1114 case IFCOUNTER_OERRORS:
1115 ifp->if_data.ifi_oerrors += value;
1116 break;
1117 case IFCOUNTER_COLLISIONS:
1118 ifp->if_data.ifi_collisions += value;
1119 break;
1120 case IFCOUNTER_IBYTES:
1121 ifp->if_data.ifi_ibytes += value;
1122 break;
1123 case IFCOUNTER_OBYTES:
1124 ifp->if_data.ifi_obytes += value;
1125 break;
1126 case IFCOUNTER_IMCASTS:
1127 ifp->if_data.ifi_imcasts += value;
1128 break;
1129 case IFCOUNTER_OMCASTS:
1130 ifp->if_data.ifi_omcasts += value;
1131 break;
1132 case IFCOUNTER_IQDROPS:
1133 ifp->if_data.ifi_iqdrops += value;
1134 break;
1135 case IFCOUNTER_OQDROPS:
1136 /* ifp->if_data.ifi_oqdrops += value; No such field, just ignore it q*/
1137 break;
1138 case IFCOUNTER_NOPROTO:
1139 ifp->if_data.ifi_noproto += value;
1140 break;
1141 default:
1142 panic("if_inc_counter: non-existant counter");
1143 }
1144 }
1145
1146
1147 #ifdef notyet
1148 /*
1149 * Module glue.
1150 *
1151 * NB: the module name is "wlan" for compatibility with NetBSD.
1152 */
1153 static int
1154 wlan_modevent(module_t mod, int type, void *unused)
1155 {
1156 switch (type) {
1157 case MOD_LOAD:
1158 if (bootverbose)
1159 printf("wlan: <802.11 Link Layer>\n");
1160 wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
1161 bpf_track, 0, EVENTHANDLER_PRI_ANY);
1162 wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
1163 wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
1164 wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
1165 wlan_clone_destroy, 0);
1166 return 0;
1167 case MOD_UNLOAD:
1168 if_clone_detach(wlan_cloner);
1169 EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
1170 EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
1171 return 0;
1172 }
1173 return EINVAL;
1174 }
1175
1176 static moduledata_t wlan_mod = {
1177 wlanname,
1178 wlan_modevent,
1179 0
1180 };
1181 DECLARE_MODULE(wlan, wlan_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
1182 MODULE_VERSION(wlan, 1);
1183 MODULE_DEPEND(wlan, ether, 1, 1, 1);
1184 #endif
1185
1186 #ifdef IEEE80211_ALQ
1187 MODULE_DEPEND(wlan, alq, 1, 1, 1);
1188 #endif /* IEEE80211_ALQ */
1189
1190 /* Missing support for if_printf in NetBSD ... */
1191 int
1192 if_printf(struct ifnet *ifp, const char *fmt, ...)
1193 {
1194 char if_fmt[256];
1195 va_list ap;
1196
1197 snprintf(if_fmt, sizeof(if_fmt), "%s: %s", ifp->if_xname, fmt);
1198 va_start(ap, fmt);
1199 vlog(LOG_INFO, if_fmt, ap);
1200 va_end(ap);
1201 return (0);
1202 }
1203
1204 /*
1205 * Set the m_data pointer of a newly-allocated mbuf
1206 * to place an object of the specified size at the
1207 * end of the mbuf, longword aligned.
1208 */
1209 void
1210 m_align(struct mbuf *m, int len)
1211 {
1212 int adjust;
1213
1214 KASSERT(len != M_COPYALL);
1215
1216 if (m->m_flags & M_EXT)
1217 adjust = m->m_ext.ext_size - len;
1218 else if (m->m_flags & M_PKTHDR)
1219 adjust = MHLEN - len;
1220 else
1221 adjust = MLEN - len;
1222 m->m_data += adjust &~ (sizeof(long)-1);
1223 }
1224
1225 /*
1226 * Append the specified data to the indicated mbuf chain,
1227 * Extend the mbuf chain if the new data does not fit in
1228 * existing space.
1229 *
1230 * Return 1 if able to complete the job; otherwise 0.
1231 */
1232 int
1233 m_append(struct mbuf *m0, int len, const void *cpv)
1234 {
1235 struct mbuf *m, *n;
1236 int remainder, space;
1237 const char *cp = cpv;
1238
1239 KASSERT(len != M_COPYALL);
1240 for (m = m0; m->m_next != NULL; m = m->m_next)
1241 continue;
1242 remainder = len;
1243 space = M_TRAILINGSPACE(m);
1244 if (space > 0) {
1245 /*
1246 * Copy into available space.
1247 */
1248 if (space > remainder)
1249 space = remainder;
1250 memmove(mtod(m, char *) + m->m_len, cp, space);
1251 m->m_len += space;
1252 cp = cp + space, remainder -= space;
1253 }
1254 while (remainder > 0) {
1255 /*
1256 * Allocate a new mbuf; could check space
1257 * and allocate a cluster instead.
1258 */
1259 n = m_get(M_DONTWAIT, m->m_type);
1260 if (n == NULL)
1261 break;
1262 n->m_len = min(MLEN, remainder);
1263 memmove(mtod(n, void *), cp, n->m_len);
1264 cp += n->m_len, remainder -= n->m_len;
1265 m->m_next = n;
1266 m = n;
1267 }
1268 if (m0->m_flags & M_PKTHDR)
1269 m0->m_pkthdr.len += len - remainder;
1270 return (remainder == 0);
1271 }
1272
1273 /*
1274 * Create a writable copy of the mbuf chain. While doing this
1275 * we compact the chain with a goal of producing a chain with
1276 * at most two mbufs. The second mbuf in this chain is likely
1277 * to be a cluster. The primary purpose of this work is to create
1278 * a writable packet for encryption, compression, etc. The
1279 * secondary goal is to linearize the data so the data can be
1280 * passed to crypto hardware in the most efficient manner possible.
1281 */
1282 struct mbuf *
1283 m_unshare(struct mbuf *m0, int how)
1284 {
1285 struct mbuf *m, *mprev;
1286 struct mbuf *n, *mfirst, *mlast;
1287 int len, off;
1288
1289 mprev = NULL;
1290 for (m = m0; m != NULL; m = mprev->m_next) {
1291 /*
1292 * Regular mbufs are ignored unless there's a cluster
1293 * in front of it that we can use to coalesce. We do
1294 * the latter mainly so later clusters can be coalesced
1295 * also w/o having to handle them specially (i.e. convert
1296 * mbuf+cluster -> cluster). This optimization is heavily
1297 * influenced by the assumption that we're running over
1298 * Ethernet where MCLBYTES is large enough that the max
1299 * packet size will permit lots of coalescing into a
1300 * single cluster. This in turn permits efficient
1301 * crypto operations, especially when using hardware.
1302 */
1303 if ((m->m_flags & M_EXT) == 0) {
1304 if (mprev && (mprev->m_flags & M_EXT) &&
1305 m->m_len <= M_TRAILINGSPACE(mprev)) {
1306 /* XXX: this ignores mbuf types */
1307 memcpy(mtod(mprev, __uint8_t *) + mprev->m_len,
1308 mtod(m, __uint8_t *), m->m_len);
1309 mprev->m_len += m->m_len;
1310 mprev->m_next = m->m_next; /* unlink from chain */
1311 m_free(m); /* reclaim mbuf */
1312 } else {
1313 mprev = m;
1314 }
1315 continue;
1316 }
1317 /*
1318 * Writable mbufs are left alone (for now).
1319 */
1320 if (!M_READONLY(m)) {
1321 mprev = m;
1322 continue;
1323 }
1324
1325 /*
1326 * Not writable, replace with a copy or coalesce with
1327 * the previous mbuf if possible (since we have to copy
1328 * it anyway, we try to reduce the number of mbufs and
1329 * clusters so that future work is easier).
1330 */
1331 FBSDKASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
1332 /* NB: we only coalesce into a cluster or larger */
1333 if (mprev != NULL && (mprev->m_flags & M_EXT) &&
1334 m->m_len <= M_TRAILINGSPACE(mprev)) {
1335 /* XXX: this ignores mbuf types */
1336 memcpy(mtod(mprev, __uint8_t *) + mprev->m_len,
1337 mtod(m, __uint8_t *), m->m_len);
1338 mprev->m_len += m->m_len;
1339 mprev->m_next = m->m_next; /* unlink from chain */
1340 m_free(m); /* reclaim mbuf */
1341 continue;
1342 }
1343
1344 /*
1345 * Allocate new space to hold the copy and copy the data.
1346 * We deal with jumbo mbufs (i.e. m_len > MCLBYTES) by
1347 * splitting them into clusters. We could just malloc a
1348 * buffer and make it external but too many device drivers
1349 * don't know how to break up the non-contiguous memory when
1350 * doing DMA.
1351 */
1352 n = m_getcl(how, m->m_type, m->m_flags & M_COPYFLAGS);
1353 if (n == NULL) {
1354 m_freem(m0);
1355 return (NULL);
1356 }
1357 if (m->m_flags & M_PKTHDR) {
1358 FBSDKASSERT(mprev == NULL, ("%s: m0 %p, m %p has M_PKTHDR",
1359 __func__, m0, m));
1360 m_move_pkthdr(n, m);
1361 }
1362 len = m->m_len;
1363 off = 0;
1364 mfirst = n;
1365 mlast = NULL;
1366 for (;;) {
1367 int cc = min(len, MCLBYTES);
1368 memcpy(mtod(n, __uint8_t *), mtod(m, __uint8_t *) + off, cc);
1369 n->m_len = cc;
1370 if (mlast != NULL)
1371 mlast->m_next = n;
1372 mlast = n;
1373 #if 0
1374 newipsecstat.ips_clcopied++;
1375 #endif
1376
1377 len -= cc;
1378 if (len <= 0)
1379 break;
1380 off += cc;
1381
1382 n = m_getcl(how, m->m_type, m->m_flags & M_COPYFLAGS);
1383 if (n == NULL) {
1384 m_freem(mfirst);
1385 m_freem(m0);
1386 return (NULL);
1387 }
1388 }
1389 n->m_next = m->m_next;
1390 if (mprev == NULL)
1391 m0 = mfirst; /* new head of chain */
1392 else
1393 mprev->m_next = mfirst; /* replace old mbuf */
1394 m_free(m); /* release old mbuf */
1395 mprev = mfirst;
1396 }
1397 return (m0);
1398 }
1399