]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/uipc_mbuf.c
Merge ACPICA 20141107 and 20150204.
[FreeBSD/FreeBSD.git] / sys / kern / uipc_mbuf.c
1 /*-
2  * Copyright (c) 1982, 1986, 1988, 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *      @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include "opt_param.h"
36 #include "opt_mbuf_stress_test.h"
37 #include "opt_mbuf_profiling.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/limits.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/sysctl.h>
47 #include <sys/domain.h>
48 #include <sys/protosw.h>
49 #include <sys/uio.h>
50
51 int     max_linkhdr;
52 int     max_protohdr;
53 int     max_hdr;
54 int     max_datalen;
55 #ifdef MBUF_STRESS_TEST
56 int     m_defragpackets;
57 int     m_defragbytes;
58 int     m_defraguseless;
59 int     m_defragfailure;
60 int     m_defragrandomfailures;
61 #endif
62
63 /*
64  * sysctl(8) exported objects
65  */
66 SYSCTL_INT(_kern_ipc, KIPC_MAX_LINKHDR, max_linkhdr, CTLFLAG_RD,
67            &max_linkhdr, 0, "Size of largest link layer header");
68 SYSCTL_INT(_kern_ipc, KIPC_MAX_PROTOHDR, max_protohdr, CTLFLAG_RD,
69            &max_protohdr, 0, "Size of largest protocol layer header");
70 SYSCTL_INT(_kern_ipc, KIPC_MAX_HDR, max_hdr, CTLFLAG_RD,
71            &max_hdr, 0, "Size of largest link plus protocol header");
72 SYSCTL_INT(_kern_ipc, KIPC_MAX_DATALEN, max_datalen, CTLFLAG_RD,
73            &max_datalen, 0, "Minimum space left in mbuf after max_hdr");
74 #ifdef MBUF_STRESS_TEST
75 SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragpackets, CTLFLAG_RD,
76            &m_defragpackets, 0, "");
77 SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragbytes, CTLFLAG_RD,
78            &m_defragbytes, 0, "");
79 SYSCTL_INT(_kern_ipc, OID_AUTO, m_defraguseless, CTLFLAG_RD,
80            &m_defraguseless, 0, "");
81 SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragfailure, CTLFLAG_RD,
82            &m_defragfailure, 0, "");
83 SYSCTL_INT(_kern_ipc, OID_AUTO, m_defragrandomfailures, CTLFLAG_RW,
84            &m_defragrandomfailures, 0, "");
85 #endif
86
87 /*
88  * Ensure the correct size of various mbuf parameters.  It could be off due
89  * to compiler-induced padding and alignment artifacts.
90  */
91 CTASSERT(MSIZE - offsetof(struct mbuf, m_dat) == MLEN);
92 CTASSERT(MSIZE - offsetof(struct mbuf, m_pktdat) == MHLEN);
93
94 /*
95  * mbuf data storage should be 64-bit aligned regardless of architectural
96  * pointer size; check this is the case with and without a packet header.
97  */
98 CTASSERT(offsetof(struct mbuf, m_dat) % 8 == 0);
99 CTASSERT(offsetof(struct mbuf, m_pktdat) % 8 == 0);
100
101 /*
102  * While the specific values here don't matter too much (i.e., +/- a few
103  * words), we do want to ensure that changes to these values are carefully
104  * reasoned about and properly documented.  This is especially the case as
105  * network-protocol and device-driver modules encode these layouts, and must
106  * be recompiled if the structures change.  Check these values at compile time
107  * against the ones documented in comments in mbuf.h.
108  *
109  * NB: Possibly they should be documented there via #define's and not just
110  * comments.
111  */
112 #if defined(__LP64__)
113 CTASSERT(offsetof(struct mbuf, m_dat) == 32);
114 CTASSERT(sizeof(struct pkthdr) == 56);
115 CTASSERT(sizeof(struct m_ext) == 48);
116 #else
117 CTASSERT(offsetof(struct mbuf, m_dat) == 24);
118 CTASSERT(sizeof(struct pkthdr) == 48);
119 CTASSERT(sizeof(struct m_ext) == 28);
120 #endif
121
122 /*
123  * Assert that the queue(3) macros produce code of the same size as an old
124  * plain pointer does.
125  */
126 #ifdef INVARIANTS
127 static struct mbuf m_assertbuf;
128 CTASSERT(sizeof(m_assertbuf.m_slist) == sizeof(m_assertbuf.m_next));
129 CTASSERT(sizeof(m_assertbuf.m_stailq) == sizeof(m_assertbuf.m_next));
130 CTASSERT(sizeof(m_assertbuf.m_slistpkt) == sizeof(m_assertbuf.m_nextpkt));
131 CTASSERT(sizeof(m_assertbuf.m_stailqpkt) == sizeof(m_assertbuf.m_nextpkt));
132 #endif
133
134 /*
135  * m_get2() allocates minimum mbuf that would fit "size" argument.
136  */
137 struct mbuf *
138 m_get2(int size, int how, short type, int flags)
139 {
140         struct mb_args args;
141         struct mbuf *m, *n;
142
143         args.flags = flags;
144         args.type = type;
145
146         if (size <= MHLEN || (size <= MLEN && (flags & M_PKTHDR) == 0))
147                 return (uma_zalloc_arg(zone_mbuf, &args, how));
148         if (size <= MCLBYTES)
149                 return (uma_zalloc_arg(zone_pack, &args, how));
150
151         if (size > MJUMPAGESIZE)
152                 return (NULL);
153
154         m = uma_zalloc_arg(zone_mbuf, &args, how);
155         if (m == NULL)
156                 return (NULL);
157
158         n = uma_zalloc_arg(zone_jumbop, m, how);
159         if (n == NULL) {
160                 uma_zfree(zone_mbuf, m);
161                 return (NULL);
162         }
163
164         return (m);
165 }
166
167 /*
168  * m_getjcl() returns an mbuf with a cluster of the specified size attached.
169  * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
170  */
171 struct mbuf *
172 m_getjcl(int how, short type, int flags, int size)
173 {
174         struct mb_args args;
175         struct mbuf *m, *n;
176         uma_zone_t zone;
177
178         if (size == MCLBYTES)
179                 return m_getcl(how, type, flags);
180
181         args.flags = flags;
182         args.type = type;
183
184         m = uma_zalloc_arg(zone_mbuf, &args, how);
185         if (m == NULL)
186                 return (NULL);
187
188         zone = m_getzone(size);
189         n = uma_zalloc_arg(zone, m, how);
190         if (n == NULL) {
191                 uma_zfree(zone_mbuf, m);
192                 return (NULL);
193         }
194         return (m);
195 }
196
197 /*
198  * Allocate a given length worth of mbufs and/or clusters (whatever fits
199  * best) and return a pointer to the top of the allocated chain.  If an
200  * existing mbuf chain is provided, then we will append the new chain
201  * to the existing one but still return the top of the newly allocated
202  * chain.
203  */
204 struct mbuf *
205 m_getm2(struct mbuf *m, int len, int how, short type, int flags)
206 {
207         struct mbuf *mb, *nm = NULL, *mtail = NULL;
208
209         KASSERT(len >= 0, ("%s: len is < 0", __func__));
210
211         /* Validate flags. */
212         flags &= (M_PKTHDR | M_EOR);
213
214         /* Packet header mbuf must be first in chain. */
215         if ((flags & M_PKTHDR) && m != NULL)
216                 flags &= ~M_PKTHDR;
217
218         /* Loop and append maximum sized mbufs to the chain tail. */
219         while (len > 0) {
220                 if (len > MCLBYTES)
221                         mb = m_getjcl(how, type, (flags & M_PKTHDR),
222                             MJUMPAGESIZE);
223                 else if (len >= MINCLSIZE)
224                         mb = m_getcl(how, type, (flags & M_PKTHDR));
225                 else if (flags & M_PKTHDR)
226                         mb = m_gethdr(how, type);
227                 else
228                         mb = m_get(how, type);
229
230                 /* Fail the whole operation if one mbuf can't be allocated. */
231                 if (mb == NULL) {
232                         if (nm != NULL)
233                                 m_freem(nm);
234                         return (NULL);
235                 }
236
237                 /* Book keeping. */
238                 len -= M_SIZE(mb);
239                 if (mtail != NULL)
240                         mtail->m_next = mb;
241                 else
242                         nm = mb;
243                 mtail = mb;
244                 flags &= ~M_PKTHDR;     /* Only valid on the first mbuf. */
245         }
246         if (flags & M_EOR)
247                 mtail->m_flags |= M_EOR;  /* Only valid on the last mbuf. */
248
249         /* If mbuf was supplied, append new chain to the end of it. */
250         if (m != NULL) {
251                 for (mtail = m; mtail->m_next != NULL; mtail = mtail->m_next)
252                         ;
253                 mtail->m_next = nm;
254                 mtail->m_flags &= ~M_EOR;
255         } else
256                 m = nm;
257
258         return (m);
259 }
260
261 /*
262  * Free an entire chain of mbufs and associated external buffers, if
263  * applicable.
264  */
265 void
266 m_freem(struct mbuf *mb)
267 {
268
269         while (mb != NULL)
270                 mb = m_free(mb);
271 }
272
273 /*-
274  * Configure a provided mbuf to refer to the provided external storage
275  * buffer and setup a reference count for said buffer.  If the setting
276  * up of the reference count fails, the M_EXT bit will not be set.  If
277  * successfull, the M_EXT bit is set in the mbuf's flags.
278  *
279  * Arguments:
280  *    mb     The existing mbuf to which to attach the provided buffer.
281  *    buf    The address of the provided external storage buffer.
282  *    size   The size of the provided buffer.
283  *    freef  A pointer to a routine that is responsible for freeing the
284  *           provided external storage buffer.
285  *    args   A pointer to an argument structure (of any type) to be passed
286  *           to the provided freef routine (may be NULL).
287  *    flags  Any other flags to be passed to the provided mbuf.
288  *    type   The type that the external storage buffer should be
289  *           labeled with.
290  *
291  * Returns:
292  *    Nothing.
293  */
294 int
295 m_extadd(struct mbuf *mb, caddr_t buf, u_int size,
296     void (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2,
297     int flags, int type, int wait)
298 {
299         KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__));
300
301         if (type != EXT_EXTREF)
302                 mb->m_ext.ext_cnt = uma_zalloc(zone_ext_refcnt, wait);
303
304         if (mb->m_ext.ext_cnt == NULL)
305                 return (ENOMEM);
306
307         *(mb->m_ext.ext_cnt) = 1;
308         mb->m_flags |= (M_EXT | flags);
309         mb->m_ext.ext_buf = buf;
310         mb->m_data = mb->m_ext.ext_buf;
311         mb->m_ext.ext_size = size;
312         mb->m_ext.ext_free = freef;
313         mb->m_ext.ext_arg1 = arg1;
314         mb->m_ext.ext_arg2 = arg2;
315         mb->m_ext.ext_type = type;
316         mb->m_ext.ext_flags = 0;
317
318         return (0);
319 }
320
321 /*
322  * Non-directly-exported function to clean up after mbufs with M_EXT
323  * storage attached to them if the reference count hits 1.
324  */
325 void
326 mb_free_ext(struct mbuf *m)
327 {
328         int freembuf;
329
330         KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m));
331
332         /*
333          * Check if the header is embedded in the cluster.
334          */
335         freembuf = (m->m_flags & M_NOFREE) ? 0 : 1;
336
337         switch (m->m_ext.ext_type) {
338         case EXT_SFBUF:
339                 sf_ext_free(m->m_ext.ext_arg1, m->m_ext.ext_arg2);
340                 break;
341         default:
342                 KASSERT(m->m_ext.ext_cnt != NULL,
343                     ("%s: no refcounting pointer on %p", __func__, m));
344                 /* 
345                  * Free attached storage if this mbuf is the only
346                  * reference to it.
347                  */
348                 if (*(m->m_ext.ext_cnt) != 1) {
349                         if (atomic_fetchadd_int(m->m_ext.ext_cnt, -1) != 1)
350                                 break;
351                 }
352
353                 switch (m->m_ext.ext_type) {
354                 case EXT_PACKET:        /* The packet zone is special. */
355                         if (*(m->m_ext.ext_cnt) == 0)
356                                 *(m->m_ext.ext_cnt) = 1;
357                         uma_zfree(zone_pack, m);
358                         return;         /* Job done. */
359                 case EXT_CLUSTER:
360                         uma_zfree(zone_clust, m->m_ext.ext_buf);
361                         break;
362                 case EXT_JUMBOP:
363                         uma_zfree(zone_jumbop, m->m_ext.ext_buf);
364                         break;
365                 case EXT_JUMBO9:
366                         uma_zfree(zone_jumbo9, m->m_ext.ext_buf);
367                         break;
368                 case EXT_JUMBO16:
369                         uma_zfree(zone_jumbo16, m->m_ext.ext_buf);
370                         break;
371                 case EXT_NET_DRV:
372                 case EXT_MOD_TYPE:
373                 case EXT_DISPOSABLE:
374                         *(m->m_ext.ext_cnt) = 0;
375                         uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *,
376                                 m->m_ext.ext_cnt));
377                         /* FALLTHROUGH */
378                 case EXT_EXTREF:
379                         KASSERT(m->m_ext.ext_free != NULL,
380                                 ("%s: ext_free not set", __func__));
381                         (*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1,
382                             m->m_ext.ext_arg2);
383                         break;
384                 default:
385                         KASSERT(m->m_ext.ext_type == 0,
386                                 ("%s: unknown ext_type", __func__));
387                 }
388         }
389
390         if (freembuf)
391                 uma_zfree(zone_mbuf, m);
392 }
393
394 /*
395  * Attach the cluster from *m to *n, set up m_ext in *n
396  * and bump the refcount of the cluster.
397  */
398 static void
399 mb_dupcl(struct mbuf *n, struct mbuf *m)
400 {
401
402         KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m));
403         KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n));
404
405         switch (m->m_ext.ext_type) {
406         case EXT_SFBUF:
407                 sf_ext_ref(m->m_ext.ext_arg1, m->m_ext.ext_arg2);
408                 break;
409         default:
410                 KASSERT(m->m_ext.ext_cnt != NULL,
411                     ("%s: no refcounting pointer on %p", __func__, m));
412                 if (*(m->m_ext.ext_cnt) == 1)
413                         *(m->m_ext.ext_cnt) += 1;
414                 else
415                         atomic_add_int(m->m_ext.ext_cnt, 1);
416         }
417
418         n->m_ext = m->m_ext;
419         n->m_flags |= M_EXT;
420         n->m_flags |= m->m_flags & M_RDONLY;
421 }
422
423 /*
424  * Clean up mbuf (chain) from any tags and packet headers.
425  * If "all" is set then the first mbuf in the chain will be
426  * cleaned too.
427  */
428 void
429 m_demote(struct mbuf *m0, int all, int flags)
430 {
431         struct mbuf *m;
432
433         for (m = all ? m0 : m0->m_next; m != NULL; m = m->m_next) {
434                 KASSERT(m->m_nextpkt == NULL, ("%s: m_nextpkt in m %p, m0 %p",
435                     __func__, m, m0));
436                 if (m->m_flags & M_PKTHDR) {
437                         m_tag_delete_chain(m, NULL);
438                         m->m_flags &= ~M_PKTHDR;
439                         bzero(&m->m_pkthdr, sizeof(struct pkthdr));
440                 }
441                 m->m_flags = m->m_flags & (M_EXT | M_RDONLY | M_NOFREE | flags);
442         }
443 }
444
445 /*
446  * Sanity checks on mbuf (chain) for use in KASSERT() and general
447  * debugging.
448  * Returns 0 or panics when bad and 1 on all tests passed.
449  * Sanitize, 0 to run M_SANITY_ACTION, 1 to garble things so they
450  * blow up later.
451  */
452 int
453 m_sanity(struct mbuf *m0, int sanitize)
454 {
455         struct mbuf *m;
456         caddr_t a, b;
457         int pktlen = 0;
458
459 #ifdef INVARIANTS
460 #define M_SANITY_ACTION(s)      panic("mbuf %p: " s, m)
461 #else
462 #define M_SANITY_ACTION(s)      printf("mbuf %p: " s, m)
463 #endif
464
465         for (m = m0; m != NULL; m = m->m_next) {
466                 /*
467                  * Basic pointer checks.  If any of these fails then some
468                  * unrelated kernel memory before or after us is trashed.
469                  * No way to recover from that.
470                  */
471                 a = M_START(m);
472                 b = a + M_SIZE(m);
473                 if ((caddr_t)m->m_data < a)
474                         M_SANITY_ACTION("m_data outside mbuf data range left");
475                 if ((caddr_t)m->m_data > b)
476                         M_SANITY_ACTION("m_data outside mbuf data range right");
477                 if ((caddr_t)m->m_data + m->m_len > b)
478                         M_SANITY_ACTION("m_data + m_len exeeds mbuf space");
479
480                 /* m->m_nextpkt may only be set on first mbuf in chain. */
481                 if (m != m0 && m->m_nextpkt != NULL) {
482                         if (sanitize) {
483                                 m_freem(m->m_nextpkt);
484                                 m->m_nextpkt = (struct mbuf *)0xDEADC0DE;
485                         } else
486                                 M_SANITY_ACTION("m->m_nextpkt on in-chain mbuf");
487                 }
488
489                 /* packet length (not mbuf length!) calculation */
490                 if (m0->m_flags & M_PKTHDR)
491                         pktlen += m->m_len;
492
493                 /* m_tags may only be attached to first mbuf in chain. */
494                 if (m != m0 && m->m_flags & M_PKTHDR &&
495                     !SLIST_EMPTY(&m->m_pkthdr.tags)) {
496                         if (sanitize) {
497                                 m_tag_delete_chain(m, NULL);
498                                 /* put in 0xDEADC0DE perhaps? */
499                         } else
500                                 M_SANITY_ACTION("m_tags on in-chain mbuf");
501                 }
502
503                 /* M_PKTHDR may only be set on first mbuf in chain */
504                 if (m != m0 && m->m_flags & M_PKTHDR) {
505                         if (sanitize) {
506                                 bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
507                                 m->m_flags &= ~M_PKTHDR;
508                                 /* put in 0xDEADCODE and leave hdr flag in */
509                         } else
510                                 M_SANITY_ACTION("M_PKTHDR on in-chain mbuf");
511                 }
512         }
513         m = m0;
514         if (pktlen && pktlen != m->m_pkthdr.len) {
515                 if (sanitize)
516                         m->m_pkthdr.len = 0;
517                 else
518                         M_SANITY_ACTION("m_pkthdr.len != mbuf chain length");
519         }
520         return 1;
521
522 #undef  M_SANITY_ACTION
523 }
524
525
526 /*
527  * "Move" mbuf pkthdr from "from" to "to".
528  * "from" must have M_PKTHDR set, and "to" must be empty.
529  */
530 void
531 m_move_pkthdr(struct mbuf *to, struct mbuf *from)
532 {
533
534 #if 0
535         /* see below for why these are not enabled */
536         M_ASSERTPKTHDR(to);
537         /* Note: with MAC, this may not be a good assertion. */
538         KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags),
539             ("m_move_pkthdr: to has tags"));
540 #endif
541 #ifdef MAC
542         /*
543          * XXXMAC: It could be this should also occur for non-MAC?
544          */
545         if (to->m_flags & M_PKTHDR)
546                 m_tag_delete_chain(to, NULL);
547 #endif
548         to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
549         if ((to->m_flags & M_EXT) == 0)
550                 to->m_data = to->m_pktdat;
551         to->m_pkthdr = from->m_pkthdr;          /* especially tags */
552         SLIST_INIT(&from->m_pkthdr.tags);       /* purge tags from src */
553         from->m_flags &= ~M_PKTHDR;
554 }
555
556 /*
557  * Duplicate "from"'s mbuf pkthdr in "to".
558  * "from" must have M_PKTHDR set, and "to" must be empty.
559  * In particular, this does a deep copy of the packet tags.
560  */
561 int
562 m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
563 {
564
565 #if 0
566         /*
567          * The mbuf allocator only initializes the pkthdr
568          * when the mbuf is allocated with m_gethdr(). Many users
569          * (e.g. m_copy*, m_prepend) use m_get() and then
570          * smash the pkthdr as needed causing these
571          * assertions to trip.  For now just disable them.
572          */
573         M_ASSERTPKTHDR(to);
574         /* Note: with MAC, this may not be a good assertion. */
575         KASSERT(SLIST_EMPTY(&to->m_pkthdr.tags), ("m_dup_pkthdr: to has tags"));
576 #endif
577         MBUF_CHECKSLEEP(how);
578 #ifdef MAC
579         if (to->m_flags & M_PKTHDR)
580                 m_tag_delete_chain(to, NULL);
581 #endif
582         to->m_flags = (from->m_flags & M_COPYFLAGS) | (to->m_flags & M_EXT);
583         if ((to->m_flags & M_EXT) == 0)
584                 to->m_data = to->m_pktdat;
585         to->m_pkthdr = from->m_pkthdr;
586         SLIST_INIT(&to->m_pkthdr.tags);
587         return (m_tag_copy_chain(to, from, how));
588 }
589
590 /*
591  * Lesser-used path for M_PREPEND:
592  * allocate new mbuf to prepend to chain,
593  * copy junk along.
594  */
595 struct mbuf *
596 m_prepend(struct mbuf *m, int len, int how)
597 {
598         struct mbuf *mn;
599
600         if (m->m_flags & M_PKTHDR)
601                 mn = m_gethdr(how, m->m_type);
602         else
603                 mn = m_get(how, m->m_type);
604         if (mn == NULL) {
605                 m_freem(m);
606                 return (NULL);
607         }
608         if (m->m_flags & M_PKTHDR)
609                 m_move_pkthdr(mn, m);
610         mn->m_next = m;
611         m = mn;
612         if (len < M_SIZE(m))
613                 M_ALIGN(m, len);
614         m->m_len = len;
615         return (m);
616 }
617
618 /*
619  * Make a copy of an mbuf chain starting "off0" bytes from the beginning,
620  * continuing for "len" bytes.  If len is M_COPYALL, copy to end of mbuf.
621  * The wait parameter is a choice of M_WAITOK/M_NOWAIT from caller.
622  * Note that the copy is read-only, because clusters are not copied,
623  * only their reference counts are incremented.
624  */
625 struct mbuf *
626 m_copym(struct mbuf *m, int off0, int len, int wait)
627 {
628         struct mbuf *n, **np;
629         int off = off0;
630         struct mbuf *top;
631         int copyhdr = 0;
632
633         KASSERT(off >= 0, ("m_copym, negative off %d", off));
634         KASSERT(len >= 0, ("m_copym, negative len %d", len));
635         MBUF_CHECKSLEEP(wait);
636         if (off == 0 && m->m_flags & M_PKTHDR)
637                 copyhdr = 1;
638         while (off > 0) {
639                 KASSERT(m != NULL, ("m_copym, offset > size of mbuf chain"));
640                 if (off < m->m_len)
641                         break;
642                 off -= m->m_len;
643                 m = m->m_next;
644         }
645         np = &top;
646         top = 0;
647         while (len > 0) {
648                 if (m == NULL) {
649                         KASSERT(len == M_COPYALL,
650                             ("m_copym, length > size of mbuf chain"));
651                         break;
652                 }
653                 if (copyhdr)
654                         n = m_gethdr(wait, m->m_type);
655                 else
656                         n = m_get(wait, m->m_type);
657                 *np = n;
658                 if (n == NULL)
659                         goto nospace;
660                 if (copyhdr) {
661                         if (!m_dup_pkthdr(n, m, wait))
662                                 goto nospace;
663                         if (len == M_COPYALL)
664                                 n->m_pkthdr.len -= off0;
665                         else
666                                 n->m_pkthdr.len = len;
667                         copyhdr = 0;
668                 }
669                 n->m_len = min(len, m->m_len - off);
670                 if (m->m_flags & M_EXT) {
671                         n->m_data = m->m_data + off;
672                         mb_dupcl(n, m);
673                 } else
674                         bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
675                             (u_int)n->m_len);
676                 if (len != M_COPYALL)
677                         len -= n->m_len;
678                 off = 0;
679                 m = m->m_next;
680                 np = &n->m_next;
681         }
682
683         return (top);
684 nospace:
685         m_freem(top);
686         return (NULL);
687 }
688
689 /*
690  * Copy an entire packet, including header (which must be present).
691  * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'.
692  * Note that the copy is read-only, because clusters are not copied,
693  * only their reference counts are incremented.
694  * Preserve alignment of the first mbuf so if the creator has left
695  * some room at the beginning (e.g. for inserting protocol headers)
696  * the copies still have the room available.
697  */
698 struct mbuf *
699 m_copypacket(struct mbuf *m, int how)
700 {
701         struct mbuf *top, *n, *o;
702
703         MBUF_CHECKSLEEP(how);
704         n = m_get(how, m->m_type);
705         top = n;
706         if (n == NULL)
707                 goto nospace;
708
709         if (!m_dup_pkthdr(n, m, how))
710                 goto nospace;
711         n->m_len = m->m_len;
712         if (m->m_flags & M_EXT) {
713                 n->m_data = m->m_data;
714                 mb_dupcl(n, m);
715         } else {
716                 n->m_data = n->m_pktdat + (m->m_data - m->m_pktdat );
717                 bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
718         }
719
720         m = m->m_next;
721         while (m) {
722                 o = m_get(how, m->m_type);
723                 if (o == NULL)
724                         goto nospace;
725
726                 n->m_next = o;
727                 n = n->m_next;
728
729                 n->m_len = m->m_len;
730                 if (m->m_flags & M_EXT) {
731                         n->m_data = m->m_data;
732                         mb_dupcl(n, m);
733                 } else {
734                         bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
735                 }
736
737                 m = m->m_next;
738         }
739         return top;
740 nospace:
741         m_freem(top);
742         return (NULL);
743 }
744
745 /*
746  * Copy data from an mbuf chain starting "off" bytes from the beginning,
747  * continuing for "len" bytes, into the indicated buffer.
748  */
749 void
750 m_copydata(const struct mbuf *m, int off, int len, caddr_t cp)
751 {
752         u_int count;
753
754         KASSERT(off >= 0, ("m_copydata, negative off %d", off));
755         KASSERT(len >= 0, ("m_copydata, negative len %d", len));
756         while (off > 0) {
757                 KASSERT(m != NULL, ("m_copydata, offset > size of mbuf chain"));
758                 if (off < m->m_len)
759                         break;
760                 off -= m->m_len;
761                 m = m->m_next;
762         }
763         while (len > 0) {
764                 KASSERT(m != NULL, ("m_copydata, length > size of mbuf chain"));
765                 count = min(m->m_len - off, len);
766                 bcopy(mtod(m, caddr_t) + off, cp, count);
767                 len -= count;
768                 cp += count;
769                 off = 0;
770                 m = m->m_next;
771         }
772 }
773
774 /*
775  * Copy a packet header mbuf chain into a completely new chain, including
776  * copying any mbuf clusters.  Use this instead of m_copypacket() when
777  * you need a writable copy of an mbuf chain.
778  */
779 struct mbuf *
780 m_dup(struct mbuf *m, int how)
781 {
782         struct mbuf **p, *top = NULL;
783         int remain, moff, nsize;
784
785         MBUF_CHECKSLEEP(how);
786         /* Sanity check */
787         if (m == NULL)
788                 return (NULL);
789         M_ASSERTPKTHDR(m);
790
791         /* While there's more data, get a new mbuf, tack it on, and fill it */
792         remain = m->m_pkthdr.len;
793         moff = 0;
794         p = &top;
795         while (remain > 0 || top == NULL) {     /* allow m->m_pkthdr.len == 0 */
796                 struct mbuf *n;
797
798                 /* Get the next new mbuf */
799                 if (remain >= MINCLSIZE) {
800                         n = m_getcl(how, m->m_type, 0);
801                         nsize = MCLBYTES;
802                 } else {
803                         n = m_get(how, m->m_type);
804                         nsize = MLEN;
805                 }
806                 if (n == NULL)
807                         goto nospace;
808
809                 if (top == NULL) {              /* First one, must be PKTHDR */
810                         if (!m_dup_pkthdr(n, m, how)) {
811                                 m_free(n);
812                                 goto nospace;
813                         }
814                         if ((n->m_flags & M_EXT) == 0)
815                                 nsize = MHLEN;
816                 }
817                 n->m_len = 0;
818
819                 /* Link it into the new chain */
820                 *p = n;
821                 p = &n->m_next;
822
823                 /* Copy data from original mbuf(s) into new mbuf */
824                 while (n->m_len < nsize && m != NULL) {
825                         int chunk = min(nsize - n->m_len, m->m_len - moff);
826
827                         bcopy(m->m_data + moff, n->m_data + n->m_len, chunk);
828                         moff += chunk;
829                         n->m_len += chunk;
830                         remain -= chunk;
831                         if (moff == m->m_len) {
832                                 m = m->m_next;
833                                 moff = 0;
834                         }
835                 }
836
837                 /* Check correct total mbuf length */
838                 KASSERT((remain > 0 && m != NULL) || (remain == 0 && m == NULL),
839                         ("%s: bogus m_pkthdr.len", __func__));
840         }
841         return (top);
842
843 nospace:
844         m_freem(top);
845         return (NULL);
846 }
847
848 /*
849  * Concatenate mbuf chain n to m.
850  * Both chains must be of the same type (e.g. MT_DATA).
851  * Any m_pkthdr is not updated.
852  */
853 void
854 m_cat(struct mbuf *m, struct mbuf *n)
855 {
856         while (m->m_next)
857                 m = m->m_next;
858         while (n) {
859                 if (!M_WRITABLE(m) ||
860                     M_TRAILINGSPACE(m) < n->m_len) {
861                         /* just join the two chains */
862                         m->m_next = n;
863                         return;
864                 }
865                 /* splat the data from one into the other */
866                 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
867                     (u_int)n->m_len);
868                 m->m_len += n->m_len;
869                 n = m_free(n);
870         }
871 }
872
873 /*
874  * Concatenate two pkthdr mbuf chains.
875  */
876 void
877 m_catpkt(struct mbuf *m, struct mbuf *n)
878 {
879
880         M_ASSERTPKTHDR(m);
881         M_ASSERTPKTHDR(n);
882
883         m->m_pkthdr.len += n->m_pkthdr.len;
884         m_demote(n, 1, 0);
885
886         m_cat(m, n);
887 }
888
889 void
890 m_adj(struct mbuf *mp, int req_len)
891 {
892         int len = req_len;
893         struct mbuf *m;
894         int count;
895
896         if ((m = mp) == NULL)
897                 return;
898         if (len >= 0) {
899                 /*
900                  * Trim from head.
901                  */
902                 while (m != NULL && len > 0) {
903                         if (m->m_len <= len) {
904                                 len -= m->m_len;
905                                 m->m_len = 0;
906                                 m = m->m_next;
907                         } else {
908                                 m->m_len -= len;
909                                 m->m_data += len;
910                                 len = 0;
911                         }
912                 }
913                 if (mp->m_flags & M_PKTHDR)
914                         mp->m_pkthdr.len -= (req_len - len);
915         } else {
916                 /*
917                  * Trim from tail.  Scan the mbuf chain,
918                  * calculating its length and finding the last mbuf.
919                  * If the adjustment only affects this mbuf, then just
920                  * adjust and return.  Otherwise, rescan and truncate
921                  * after the remaining size.
922                  */
923                 len = -len;
924                 count = 0;
925                 for (;;) {
926                         count += m->m_len;
927                         if (m->m_next == (struct mbuf *)0)
928                                 break;
929                         m = m->m_next;
930                 }
931                 if (m->m_len >= len) {
932                         m->m_len -= len;
933                         if (mp->m_flags & M_PKTHDR)
934                                 mp->m_pkthdr.len -= len;
935                         return;
936                 }
937                 count -= len;
938                 if (count < 0)
939                         count = 0;
940                 /*
941                  * Correct length for chain is "count".
942                  * Find the mbuf with last data, adjust its length,
943                  * and toss data from remaining mbufs on chain.
944                  */
945                 m = mp;
946                 if (m->m_flags & M_PKTHDR)
947                         m->m_pkthdr.len = count;
948                 for (; m; m = m->m_next) {
949                         if (m->m_len >= count) {
950                                 m->m_len = count;
951                                 if (m->m_next != NULL) {
952                                         m_freem(m->m_next);
953                                         m->m_next = NULL;
954                                 }
955                                 break;
956                         }
957                         count -= m->m_len;
958                 }
959         }
960 }
961
962 /*
963  * Rearange an mbuf chain so that len bytes are contiguous
964  * and in the data area of an mbuf (so that mtod will work
965  * for a structure of size len).  Returns the resulting
966  * mbuf chain on success, frees it and returns null on failure.
967  * If there is room, it will add up to max_protohdr-len extra bytes to the
968  * contiguous region in an attempt to avoid being called next time.
969  */
970 struct mbuf *
971 m_pullup(struct mbuf *n, int len)
972 {
973         struct mbuf *m;
974         int count;
975         int space;
976
977         /*
978          * If first mbuf has no cluster, and has room for len bytes
979          * without shifting current data, pullup into it,
980          * otherwise allocate a new mbuf to prepend to the chain.
981          */
982         if ((n->m_flags & M_EXT) == 0 &&
983             n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
984                 if (n->m_len >= len)
985                         return (n);
986                 m = n;
987                 n = n->m_next;
988                 len -= m->m_len;
989         } else {
990                 if (len > MHLEN)
991                         goto bad;
992                 m = m_get(M_NOWAIT, n->m_type);
993                 if (m == NULL)
994                         goto bad;
995                 if (n->m_flags & M_PKTHDR)
996                         m_move_pkthdr(m, n);
997         }
998         space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
999         do {
1000                 count = min(min(max(len, max_protohdr), space), n->m_len);
1001                 bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
1002                   (u_int)count);
1003                 len -= count;
1004                 m->m_len += count;
1005                 n->m_len -= count;
1006                 space -= count;
1007                 if (n->m_len)
1008                         n->m_data += count;
1009                 else
1010                         n = m_free(n);
1011         } while (len > 0 && n);
1012         if (len > 0) {
1013                 (void) m_free(m);
1014                 goto bad;
1015         }
1016         m->m_next = n;
1017         return (m);
1018 bad:
1019         m_freem(n);
1020         return (NULL);
1021 }
1022
1023 /*
1024  * Like m_pullup(), except a new mbuf is always allocated, and we allow
1025  * the amount of empty space before the data in the new mbuf to be specified
1026  * (in the event that the caller expects to prepend later).
1027  */
1028 int MSFail;
1029
1030 struct mbuf *
1031 m_copyup(struct mbuf *n, int len, int dstoff)
1032 {
1033         struct mbuf *m;
1034         int count, space;
1035
1036         if (len > (MHLEN - dstoff))
1037                 goto bad;
1038         m = m_get(M_NOWAIT, n->m_type);
1039         if (m == NULL)
1040                 goto bad;
1041         if (n->m_flags & M_PKTHDR)
1042                 m_move_pkthdr(m, n);
1043         m->m_data += dstoff;
1044         space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
1045         do {
1046                 count = min(min(max(len, max_protohdr), space), n->m_len);
1047                 memcpy(mtod(m, caddr_t) + m->m_len, mtod(n, caddr_t),
1048                     (unsigned)count);
1049                 len -= count;
1050                 m->m_len += count;
1051                 n->m_len -= count;
1052                 space -= count;
1053                 if (n->m_len)
1054                         n->m_data += count;
1055                 else
1056                         n = m_free(n);
1057         } while (len > 0 && n);
1058         if (len > 0) {
1059                 (void) m_free(m);
1060                 goto bad;
1061         }
1062         m->m_next = n;
1063         return (m);
1064  bad:
1065         m_freem(n);
1066         MSFail++;
1067         return (NULL);
1068 }
1069
1070 /*
1071  * Partition an mbuf chain in two pieces, returning the tail --
1072  * all but the first len0 bytes.  In case of failure, it returns NULL and
1073  * attempts to restore the chain to its original state.
1074  *
1075  * Note that the resulting mbufs might be read-only, because the new
1076  * mbuf can end up sharing an mbuf cluster with the original mbuf if
1077  * the "breaking point" happens to lie within a cluster mbuf. Use the
1078  * M_WRITABLE() macro to check for this case.
1079  */
1080 struct mbuf *
1081 m_split(struct mbuf *m0, int len0, int wait)
1082 {
1083         struct mbuf *m, *n;
1084         u_int len = len0, remain;
1085
1086         MBUF_CHECKSLEEP(wait);
1087         for (m = m0; m && len > m->m_len; m = m->m_next)
1088                 len -= m->m_len;
1089         if (m == NULL)
1090                 return (NULL);
1091         remain = m->m_len - len;
1092         if (m0->m_flags & M_PKTHDR && remain == 0) {
1093                 n = m_gethdr(wait, m0->m_type);
1094                 if (n == NULL)
1095                         return (NULL);
1096                 n->m_next = m->m_next;
1097                 m->m_next = NULL;
1098                 n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
1099                 n->m_pkthdr.len = m0->m_pkthdr.len - len0;
1100                 m0->m_pkthdr.len = len0;
1101                 return (n);
1102         } else if (m0->m_flags & M_PKTHDR) {
1103                 n = m_gethdr(wait, m0->m_type);
1104                 if (n == NULL)
1105                         return (NULL);
1106                 n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
1107                 n->m_pkthdr.len = m0->m_pkthdr.len - len0;
1108                 m0->m_pkthdr.len = len0;
1109                 if (m->m_flags & M_EXT)
1110                         goto extpacket;
1111                 if (remain > MHLEN) {
1112                         /* m can't be the lead packet */
1113                         M_ALIGN(n, 0);
1114                         n->m_next = m_split(m, len, wait);
1115                         if (n->m_next == NULL) {
1116                                 (void) m_free(n);
1117                                 return (NULL);
1118                         } else {
1119                                 n->m_len = 0;
1120                                 return (n);
1121                         }
1122                 } else
1123                         M_ALIGN(n, remain);
1124         } else if (remain == 0) {
1125                 n = m->m_next;
1126                 m->m_next = NULL;
1127                 return (n);
1128         } else {
1129                 n = m_get(wait, m->m_type);
1130                 if (n == NULL)
1131                         return (NULL);
1132                 M_ALIGN(n, remain);
1133         }
1134 extpacket:
1135         if (m->m_flags & M_EXT) {
1136                 n->m_data = m->m_data + len;
1137                 mb_dupcl(n, m);
1138         } else {
1139                 bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
1140         }
1141         n->m_len = remain;
1142         m->m_len = len;
1143         n->m_next = m->m_next;
1144         m->m_next = NULL;
1145         return (n);
1146 }
1147 /*
1148  * Routine to copy from device local memory into mbufs.
1149  * Note that `off' argument is offset into first mbuf of target chain from
1150  * which to begin copying the data to.
1151  */
1152 struct mbuf *
1153 m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
1154     void (*copy)(char *from, caddr_t to, u_int len))
1155 {
1156         struct mbuf *m;
1157         struct mbuf *top = NULL, **mp = &top;
1158         int len;
1159
1160         if (off < 0 || off > MHLEN)
1161                 return (NULL);
1162
1163         while (totlen > 0) {
1164                 if (top == NULL) {      /* First one, must be PKTHDR */
1165                         if (totlen + off >= MINCLSIZE) {
1166                                 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1167                                 len = MCLBYTES;
1168                         } else {
1169                                 m = m_gethdr(M_NOWAIT, MT_DATA);
1170                                 len = MHLEN;
1171
1172                                 /* Place initial small packet/header at end of mbuf */
1173                                 if (m && totlen + off + max_linkhdr <= MLEN) {
1174                                         m->m_data += max_linkhdr;
1175                                         len -= max_linkhdr;
1176                                 }
1177                         }
1178                         if (m == NULL)
1179                                 return NULL;
1180                         m->m_pkthdr.rcvif = ifp;
1181                         m->m_pkthdr.len = totlen;
1182                 } else {
1183                         if (totlen + off >= MINCLSIZE) {
1184                                 m = m_getcl(M_NOWAIT, MT_DATA, 0);
1185                                 len = MCLBYTES;
1186                         } else {
1187                                 m = m_get(M_NOWAIT, MT_DATA);
1188                                 len = MLEN;
1189                         }
1190                         if (m == NULL) {
1191                                 m_freem(top);
1192                                 return NULL;
1193                         }
1194                 }
1195                 if (off) {
1196                         m->m_data += off;
1197                         len -= off;
1198                         off = 0;
1199                 }
1200                 m->m_len = len = min(totlen, len);
1201                 if (copy)
1202                         copy(buf, mtod(m, caddr_t), (u_int)len);
1203                 else
1204                         bcopy(buf, mtod(m, caddr_t), (u_int)len);
1205                 buf += len;
1206                 *mp = m;
1207                 mp = &m->m_next;
1208                 totlen -= len;
1209         }
1210         return (top);
1211 }
1212
1213 /*
1214  * Copy data from a buffer back into the indicated mbuf chain,
1215  * starting "off" bytes from the beginning, extending the mbuf
1216  * chain if necessary.
1217  */
1218 void
1219 m_copyback(struct mbuf *m0, int off, int len, c_caddr_t cp)
1220 {
1221         int mlen;
1222         struct mbuf *m = m0, *n;
1223         int totlen = 0;
1224
1225         if (m0 == NULL)
1226                 return;
1227         while (off > (mlen = m->m_len)) {
1228                 off -= mlen;
1229                 totlen += mlen;
1230                 if (m->m_next == NULL) {
1231                         n = m_get(M_NOWAIT, m->m_type);
1232                         if (n == NULL)
1233                                 goto out;
1234                         bzero(mtod(n, caddr_t), MLEN);
1235                         n->m_len = min(MLEN, len + off);
1236                         m->m_next = n;
1237                 }
1238                 m = m->m_next;
1239         }
1240         while (len > 0) {
1241                 if (m->m_next == NULL && (len > m->m_len - off)) {
1242                         m->m_len += min(len - (m->m_len - off),
1243                             M_TRAILINGSPACE(m));
1244                 }
1245                 mlen = min (m->m_len - off, len);
1246                 bcopy(cp, off + mtod(m, caddr_t), (u_int)mlen);
1247                 cp += mlen;
1248                 len -= mlen;
1249                 mlen += off;
1250                 off = 0;
1251                 totlen += mlen;
1252                 if (len == 0)
1253                         break;
1254                 if (m->m_next == NULL) {
1255                         n = m_get(M_NOWAIT, m->m_type);
1256                         if (n == NULL)
1257                                 break;
1258                         n->m_len = min(MLEN, len);
1259                         m->m_next = n;
1260                 }
1261                 m = m->m_next;
1262         }
1263 out:    if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
1264                 m->m_pkthdr.len = totlen;
1265 }
1266
1267 /*
1268  * Append the specified data to the indicated mbuf chain,
1269  * Extend the mbuf chain if the new data does not fit in
1270  * existing space.
1271  *
1272  * Return 1 if able to complete the job; otherwise 0.
1273  */
1274 int
1275 m_append(struct mbuf *m0, int len, c_caddr_t cp)
1276 {
1277         struct mbuf *m, *n;
1278         int remainder, space;
1279
1280         for (m = m0; m->m_next != NULL; m = m->m_next)
1281                 ;
1282         remainder = len;
1283         space = M_TRAILINGSPACE(m);
1284         if (space > 0) {
1285                 /*
1286                  * Copy into available space.
1287                  */
1288                 if (space > remainder)
1289                         space = remainder;
1290                 bcopy(cp, mtod(m, caddr_t) + m->m_len, space);
1291                 m->m_len += space;
1292                 cp += space, remainder -= space;
1293         }
1294         while (remainder > 0) {
1295                 /*
1296                  * Allocate a new mbuf; could check space
1297                  * and allocate a cluster instead.
1298                  */
1299                 n = m_get(M_NOWAIT, m->m_type);
1300                 if (n == NULL)
1301                         break;
1302                 n->m_len = min(MLEN, remainder);
1303                 bcopy(cp, mtod(n, caddr_t), n->m_len);
1304                 cp += n->m_len, remainder -= n->m_len;
1305                 m->m_next = n;
1306                 m = n;
1307         }
1308         if (m0->m_flags & M_PKTHDR)
1309                 m0->m_pkthdr.len += len - remainder;
1310         return (remainder == 0);
1311 }
1312
1313 /*
1314  * Apply function f to the data in an mbuf chain starting "off" bytes from
1315  * the beginning, continuing for "len" bytes.
1316  */
1317 int
1318 m_apply(struct mbuf *m, int off, int len,
1319     int (*f)(void *, void *, u_int), void *arg)
1320 {
1321         u_int count;
1322         int rval;
1323
1324         KASSERT(off >= 0, ("m_apply, negative off %d", off));
1325         KASSERT(len >= 0, ("m_apply, negative len %d", len));
1326         while (off > 0) {
1327                 KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
1328                 if (off < m->m_len)
1329                         break;
1330                 off -= m->m_len;
1331                 m = m->m_next;
1332         }
1333         while (len > 0) {
1334                 KASSERT(m != NULL, ("m_apply, offset > size of mbuf chain"));
1335                 count = min(m->m_len - off, len);
1336                 rval = (*f)(arg, mtod(m, caddr_t) + off, count);
1337                 if (rval)
1338                         return (rval);
1339                 len -= count;
1340                 off = 0;
1341                 m = m->m_next;
1342         }
1343         return (0);
1344 }
1345
1346 /*
1347  * Return a pointer to mbuf/offset of location in mbuf chain.
1348  */
1349 struct mbuf *
1350 m_getptr(struct mbuf *m, int loc, int *off)
1351 {
1352
1353         while (loc >= 0) {
1354                 /* Normal end of search. */
1355                 if (m->m_len > loc) {
1356                         *off = loc;
1357                         return (m);
1358                 } else {
1359                         loc -= m->m_len;
1360                         if (m->m_next == NULL) {
1361                                 if (loc == 0) {
1362                                         /* Point at the end of valid data. */
1363                                         *off = m->m_len;
1364                                         return (m);
1365                                 }
1366                                 return (NULL);
1367                         }
1368                         m = m->m_next;
1369                 }
1370         }
1371         return (NULL);
1372 }
1373
1374 void
1375 m_print(const struct mbuf *m, int maxlen)
1376 {
1377         int len;
1378         int pdata;
1379         const struct mbuf *m2;
1380
1381         if (m == NULL) {
1382                 printf("mbuf: %p\n", m);
1383                 return;
1384         }
1385
1386         if (m->m_flags & M_PKTHDR)
1387                 len = m->m_pkthdr.len;
1388         else
1389                 len = -1;
1390         m2 = m;
1391         while (m2 != NULL && (len == -1 || len)) {
1392                 pdata = m2->m_len;
1393                 if (maxlen != -1 && pdata > maxlen)
1394                         pdata = maxlen;
1395                 printf("mbuf: %p len: %d, next: %p, %b%s", m2, m2->m_len,
1396                     m2->m_next, m2->m_flags, "\20\20freelist\17skipfw"
1397                     "\11proto5\10proto4\7proto3\6proto2\5proto1\4rdonly"
1398                     "\3eor\2pkthdr\1ext", pdata ? "" : "\n");
1399                 if (pdata)
1400                         printf(", %*D\n", pdata, (u_char *)m2->m_data, "-");
1401                 if (len != -1)
1402                         len -= m2->m_len;
1403                 m2 = m2->m_next;
1404         }
1405         if (len > 0)
1406                 printf("%d bytes unaccounted for.\n", len);
1407         return;
1408 }
1409
1410 u_int
1411 m_fixhdr(struct mbuf *m0)
1412 {
1413         u_int len;
1414
1415         len = m_length(m0, NULL);
1416         m0->m_pkthdr.len = len;
1417         return (len);
1418 }
1419
1420 u_int
1421 m_length(struct mbuf *m0, struct mbuf **last)
1422 {
1423         struct mbuf *m;
1424         u_int len;
1425
1426         len = 0;
1427         for (m = m0; m != NULL; m = m->m_next) {
1428                 len += m->m_len;
1429                 if (m->m_next == NULL)
1430                         break;
1431         }
1432         if (last != NULL)
1433                 *last = m;
1434         return (len);
1435 }
1436
1437 /*
1438  * Defragment a mbuf chain, returning the shortest possible
1439  * chain of mbufs and clusters.  If allocation fails and
1440  * this cannot be completed, NULL will be returned, but
1441  * the passed in chain will be unchanged.  Upon success,
1442  * the original chain will be freed, and the new chain
1443  * will be returned.
1444  *
1445  * If a non-packet header is passed in, the original
1446  * mbuf (chain?) will be returned unharmed.
1447  */
1448 struct mbuf *
1449 m_defrag(struct mbuf *m0, int how)
1450 {
1451         struct mbuf *m_new = NULL, *m_final = NULL;
1452         int progress = 0, length;
1453
1454         MBUF_CHECKSLEEP(how);
1455         if (!(m0->m_flags & M_PKTHDR))
1456                 return (m0);
1457
1458         m_fixhdr(m0); /* Needed sanity check */
1459
1460 #ifdef MBUF_STRESS_TEST
1461         if (m_defragrandomfailures) {
1462                 int temp = arc4random() & 0xff;
1463                 if (temp == 0xba)
1464                         goto nospace;
1465         }
1466 #endif
1467
1468         if (m0->m_pkthdr.len > MHLEN)
1469                 m_final = m_getcl(how, MT_DATA, M_PKTHDR);
1470         else
1471                 m_final = m_gethdr(how, MT_DATA);
1472
1473         if (m_final == NULL)
1474                 goto nospace;
1475
1476         if (m_dup_pkthdr(m_final, m0, how) == 0)
1477                 goto nospace;
1478
1479         m_new = m_final;
1480
1481         while (progress < m0->m_pkthdr.len) {
1482                 length = m0->m_pkthdr.len - progress;
1483                 if (length > MCLBYTES)
1484                         length = MCLBYTES;
1485
1486                 if (m_new == NULL) {
1487                         if (length > MLEN)
1488                                 m_new = m_getcl(how, MT_DATA, 0);
1489                         else
1490                                 m_new = m_get(how, MT_DATA);
1491                         if (m_new == NULL)
1492                                 goto nospace;
1493                 }
1494
1495                 m_copydata(m0, progress, length, mtod(m_new, caddr_t));
1496                 progress += length;
1497                 m_new->m_len = length;
1498                 if (m_new != m_final)
1499                         m_cat(m_final, m_new);
1500                 m_new = NULL;
1501         }
1502 #ifdef MBUF_STRESS_TEST
1503         if (m0->m_next == NULL)
1504                 m_defraguseless++;
1505 #endif
1506         m_freem(m0);
1507         m0 = m_final;
1508 #ifdef MBUF_STRESS_TEST
1509         m_defragpackets++;
1510         m_defragbytes += m0->m_pkthdr.len;
1511 #endif
1512         return (m0);
1513 nospace:
1514 #ifdef MBUF_STRESS_TEST
1515         m_defragfailure++;
1516 #endif
1517         if (m_final)
1518                 m_freem(m_final);
1519         return (NULL);
1520 }
1521
1522 /*
1523  * Defragment an mbuf chain, returning at most maxfrags separate
1524  * mbufs+clusters.  If this is not possible NULL is returned and
1525  * the original mbuf chain is left in it's present (potentially
1526  * modified) state.  We use two techniques: collapsing consecutive
1527  * mbufs and replacing consecutive mbufs by a cluster.
1528  *
1529  * NB: this should really be named m_defrag but that name is taken
1530  */
1531 struct mbuf *
1532 m_collapse(struct mbuf *m0, int how, int maxfrags)
1533 {
1534         struct mbuf *m, *n, *n2, **prev;
1535         u_int curfrags;
1536
1537         /*
1538          * Calculate the current number of frags.
1539          */
1540         curfrags = 0;
1541         for (m = m0; m != NULL; m = m->m_next)
1542                 curfrags++;
1543         /*
1544          * First, try to collapse mbufs.  Note that we always collapse
1545          * towards the front so we don't need to deal with moving the
1546          * pkthdr.  This may be suboptimal if the first mbuf has much
1547          * less data than the following.
1548          */
1549         m = m0;
1550 again:
1551         for (;;) {
1552                 n = m->m_next;
1553                 if (n == NULL)
1554                         break;
1555                 if (M_WRITABLE(m) &&
1556                     n->m_len < M_TRAILINGSPACE(m)) {
1557                         bcopy(mtod(n, void *), mtod(m, char *) + m->m_len,
1558                                 n->m_len);
1559                         m->m_len += n->m_len;
1560                         m->m_next = n->m_next;
1561                         m_free(n);
1562                         if (--curfrags <= maxfrags)
1563                                 return m0;
1564                 } else
1565                         m = n;
1566         }
1567         KASSERT(maxfrags > 1,
1568                 ("maxfrags %u, but normal collapse failed", maxfrags));
1569         /*
1570          * Collapse consecutive mbufs to a cluster.
1571          */
1572         prev = &m0->m_next;             /* NB: not the first mbuf */
1573         while ((n = *prev) != NULL) {
1574                 if ((n2 = n->m_next) != NULL &&
1575                     n->m_len + n2->m_len < MCLBYTES) {
1576                         m = m_getcl(how, MT_DATA, 0);
1577                         if (m == NULL)
1578                                 goto bad;
1579                         bcopy(mtod(n, void *), mtod(m, void *), n->m_len);
1580                         bcopy(mtod(n2, void *), mtod(m, char *) + n->m_len,
1581                                 n2->m_len);
1582                         m->m_len = n->m_len + n2->m_len;
1583                         m->m_next = n2->m_next;
1584                         *prev = m;
1585                         m_free(n);
1586                         m_free(n2);
1587                         if (--curfrags <= maxfrags)     /* +1 cl -2 mbufs */
1588                                 return m0;
1589                         /*
1590                          * Still not there, try the normal collapse
1591                          * again before we allocate another cluster.
1592                          */
1593                         goto again;
1594                 }
1595                 prev = &n->m_next;
1596         }
1597         /*
1598          * No place where we can collapse to a cluster; punt.
1599          * This can occur if, for example, you request 2 frags
1600          * but the packet requires that both be clusters (we
1601          * never reallocate the first mbuf to avoid moving the
1602          * packet header).
1603          */
1604 bad:
1605         return NULL;
1606 }
1607
1608 #ifdef MBUF_STRESS_TEST
1609
1610 /*
1611  * Fragment an mbuf chain.  There's no reason you'd ever want to do
1612  * this in normal usage, but it's great for stress testing various
1613  * mbuf consumers.
1614  *
1615  * If fragmentation is not possible, the original chain will be
1616  * returned.
1617  *
1618  * Possible length values:
1619  * 0     no fragmentation will occur
1620  * > 0  each fragment will be of the specified length
1621  * -1   each fragment will be the same random value in length
1622  * -2   each fragment's length will be entirely random
1623  * (Random values range from 1 to 256)
1624  */
1625 struct mbuf *
1626 m_fragment(struct mbuf *m0, int how, int length)
1627 {
1628         struct mbuf *m_new = NULL, *m_final = NULL;
1629         int progress = 0;
1630
1631         if (!(m0->m_flags & M_PKTHDR))
1632                 return (m0);
1633
1634         if ((length == 0) || (length < -2))
1635                 return (m0);
1636
1637         m_fixhdr(m0); /* Needed sanity check */
1638
1639         m_final = m_getcl(how, MT_DATA, M_PKTHDR);
1640
1641         if (m_final == NULL)
1642                 goto nospace;
1643
1644         if (m_dup_pkthdr(m_final, m0, how) == 0)
1645                 goto nospace;
1646
1647         m_new = m_final;
1648
1649         if (length == -1)
1650                 length = 1 + (arc4random() & 255);
1651
1652         while (progress < m0->m_pkthdr.len) {
1653                 int fraglen;
1654
1655                 if (length > 0)
1656                         fraglen = length;
1657                 else
1658                         fraglen = 1 + (arc4random() & 255);
1659                 if (fraglen > m0->m_pkthdr.len - progress)
1660                         fraglen = m0->m_pkthdr.len - progress;
1661
1662                 if (fraglen > MCLBYTES)
1663                         fraglen = MCLBYTES;
1664
1665                 if (m_new == NULL) {
1666                         m_new = m_getcl(how, MT_DATA, 0);
1667                         if (m_new == NULL)
1668                                 goto nospace;
1669                 }
1670
1671                 m_copydata(m0, progress, fraglen, mtod(m_new, caddr_t));
1672                 progress += fraglen;
1673                 m_new->m_len = fraglen;
1674                 if (m_new != m_final)
1675                         m_cat(m_final, m_new);
1676                 m_new = NULL;
1677         }
1678         m_freem(m0);
1679         m0 = m_final;
1680         return (m0);
1681 nospace:
1682         if (m_final)
1683                 m_freem(m_final);
1684         /* Return the original chain on failure */
1685         return (m0);
1686 }
1687
1688 #endif
1689
1690 /*
1691  * Copy the contents of uio into a properly sized mbuf chain.
1692  */
1693 struct mbuf *
1694 m_uiotombuf(struct uio *uio, int how, int len, int align, int flags)
1695 {
1696         struct mbuf *m, *mb;
1697         int error, length;
1698         ssize_t total;
1699         int progress = 0;
1700
1701         /*
1702          * len can be zero or an arbitrary large value bound by
1703          * the total data supplied by the uio.
1704          */
1705         if (len > 0)
1706                 total = min(uio->uio_resid, len);
1707         else
1708                 total = uio->uio_resid;
1709
1710         /*
1711          * The smallest unit returned by m_getm2() is a single mbuf
1712          * with pkthdr.  We can't align past it.
1713          */
1714         if (align >= MHLEN)
1715                 return (NULL);
1716
1717         /*
1718          * Give us the full allocation or nothing.
1719          * If len is zero return the smallest empty mbuf.
1720          */
1721         m = m_getm2(NULL, max(total + align, 1), how, MT_DATA, flags);
1722         if (m == NULL)
1723                 return (NULL);
1724         m->m_data += align;
1725
1726         /* Fill all mbufs with uio data and update header information. */
1727         for (mb = m; mb != NULL; mb = mb->m_next) {
1728                 length = min(M_TRAILINGSPACE(mb), total - progress);
1729
1730                 error = uiomove(mtod(mb, void *), length, uio);
1731                 if (error) {
1732                         m_freem(m);
1733                         return (NULL);
1734                 }
1735
1736                 mb->m_len = length;
1737                 progress += length;
1738                 if (flags & M_PKTHDR)
1739                         m->m_pkthdr.len += length;
1740         }
1741         KASSERT(progress == total, ("%s: progress != total", __func__));
1742
1743         return (m);
1744 }
1745
1746 /*
1747  * Copy an mbuf chain into a uio limited by len if set.
1748  */
1749 int
1750 m_mbuftouio(struct uio *uio, struct mbuf *m, int len)
1751 {
1752         int error, length, total;
1753         int progress = 0;
1754
1755         if (len > 0)
1756                 total = min(uio->uio_resid, len);
1757         else
1758                 total = uio->uio_resid;
1759
1760         /* Fill the uio with data from the mbufs. */
1761         for (; m != NULL; m = m->m_next) {
1762                 length = min(m->m_len, total - progress);
1763
1764                 error = uiomove(mtod(m, void *), length, uio);
1765                 if (error)
1766                         return (error);
1767
1768                 progress += length;
1769         }
1770
1771         return (0);
1772 }
1773
1774 /*
1775  * Create a writable copy of the mbuf chain.  While doing this
1776  * we compact the chain with a goal of producing a chain with
1777  * at most two mbufs.  The second mbuf in this chain is likely
1778  * to be a cluster.  The primary purpose of this work is to create
1779  * a writable packet for encryption, compression, etc.  The
1780  * secondary goal is to linearize the data so the data can be
1781  * passed to crypto hardware in the most efficient manner possible.
1782  */
1783 struct mbuf *
1784 m_unshare(struct mbuf *m0, int how)
1785 {
1786         struct mbuf *m, *mprev;
1787         struct mbuf *n, *mfirst, *mlast;
1788         int len, off;
1789
1790         mprev = NULL;
1791         for (m = m0; m != NULL; m = mprev->m_next) {
1792                 /*
1793                  * Regular mbufs are ignored unless there's a cluster
1794                  * in front of it that we can use to coalesce.  We do
1795                  * the latter mainly so later clusters can be coalesced
1796                  * also w/o having to handle them specially (i.e. convert
1797                  * mbuf+cluster -> cluster).  This optimization is heavily
1798                  * influenced by the assumption that we're running over
1799                  * Ethernet where MCLBYTES is large enough that the max
1800                  * packet size will permit lots of coalescing into a
1801                  * single cluster.  This in turn permits efficient
1802                  * crypto operations, especially when using hardware.
1803                  */
1804                 if ((m->m_flags & M_EXT) == 0) {
1805                         if (mprev && (mprev->m_flags & M_EXT) &&
1806                             m->m_len <= M_TRAILINGSPACE(mprev)) {
1807                                 /* XXX: this ignores mbuf types */
1808                                 memcpy(mtod(mprev, caddr_t) + mprev->m_len,
1809                                     mtod(m, caddr_t), m->m_len);
1810                                 mprev->m_len += m->m_len;
1811                                 mprev->m_next = m->m_next;      /* unlink from chain */
1812                                 m_free(m);                      /* reclaim mbuf */
1813 #if 0
1814                                 newipsecstat.ips_mbcoalesced++;
1815 #endif
1816                         } else {
1817                                 mprev = m;
1818                         }
1819                         continue;
1820                 }
1821                 /*
1822                  * Writable mbufs are left alone (for now).
1823                  */
1824                 if (M_WRITABLE(m)) {
1825                         mprev = m;
1826                         continue;
1827                 }
1828
1829                 /*
1830                  * Not writable, replace with a copy or coalesce with
1831                  * the previous mbuf if possible (since we have to copy
1832                  * it anyway, we try to reduce the number of mbufs and
1833                  * clusters so that future work is easier).
1834                  */
1835                 KASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
1836                 /* NB: we only coalesce into a cluster or larger */
1837                 if (mprev != NULL && (mprev->m_flags & M_EXT) &&
1838                     m->m_len <= M_TRAILINGSPACE(mprev)) {
1839                         /* XXX: this ignores mbuf types */
1840                         memcpy(mtod(mprev, caddr_t) + mprev->m_len,
1841                             mtod(m, caddr_t), m->m_len);
1842                         mprev->m_len += m->m_len;
1843                         mprev->m_next = m->m_next;      /* unlink from chain */
1844                         m_free(m);                      /* reclaim mbuf */
1845 #if 0
1846                         newipsecstat.ips_clcoalesced++;
1847 #endif
1848                         continue;
1849                 }
1850
1851                 /*
1852                  * Allocate new space to hold the copy and copy the data.
1853                  * We deal with jumbo mbufs (i.e. m_len > MCLBYTES) by
1854                  * splitting them into clusters.  We could just malloc a
1855                  * buffer and make it external but too many device drivers
1856                  * don't know how to break up the non-contiguous memory when
1857                  * doing DMA.
1858                  */
1859                 n = m_getcl(how, m->m_type, m->m_flags);
1860                 if (n == NULL) {
1861                         m_freem(m0);
1862                         return (NULL);
1863                 }
1864                 len = m->m_len;
1865                 off = 0;
1866                 mfirst = n;
1867                 mlast = NULL;
1868                 for (;;) {
1869                         int cc = min(len, MCLBYTES);
1870                         memcpy(mtod(n, caddr_t), mtod(m, caddr_t) + off, cc);
1871                         n->m_len = cc;
1872                         if (mlast != NULL)
1873                                 mlast->m_next = n;
1874                         mlast = n;
1875 #if 0
1876                         newipsecstat.ips_clcopied++;
1877 #endif
1878
1879                         len -= cc;
1880                         if (len <= 0)
1881                                 break;
1882                         off += cc;
1883
1884                         n = m_getcl(how, m->m_type, m->m_flags);
1885                         if (n == NULL) {
1886                                 m_freem(mfirst);
1887                                 m_freem(m0);
1888                                 return (NULL);
1889                         }
1890                 }
1891                 n->m_next = m->m_next;
1892                 if (mprev == NULL)
1893                         m0 = mfirst;            /* new head of chain */
1894                 else
1895                         mprev->m_next = mfirst; /* replace old mbuf */
1896                 m_free(m);                      /* release old mbuf */
1897                 mprev = mfirst;
1898         }
1899         return (m0);
1900 }
1901
1902 #ifdef MBUF_PROFILING
1903
1904 #define MP_BUCKETS 32 /* don't just change this as things may overflow.*/
1905 struct mbufprofile {
1906         uintmax_t wasted[MP_BUCKETS];
1907         uintmax_t used[MP_BUCKETS];
1908         uintmax_t segments[MP_BUCKETS];
1909 } mbprof;
1910
1911 #define MP_MAXDIGITS 21 /* strlen("16,000,000,000,000,000,000") == 21 */
1912 #define MP_NUMLINES 6
1913 #define MP_NUMSPERLINE 16
1914 #define MP_EXTRABYTES 64        /* > strlen("used:\nwasted:\nsegments:\n") */
1915 /* work out max space needed and add a bit of spare space too */
1916 #define MP_MAXLINE ((MP_MAXDIGITS+1) * MP_NUMSPERLINE)
1917 #define MP_BUFSIZE ((MP_MAXLINE * MP_NUMLINES) + 1 + MP_EXTRABYTES)
1918
1919 char mbprofbuf[MP_BUFSIZE];
1920
1921 void
1922 m_profile(struct mbuf *m)
1923 {
1924         int segments = 0;
1925         int used = 0;
1926         int wasted = 0;
1927
1928         while (m) {
1929                 segments++;
1930                 used += m->m_len;
1931                 if (m->m_flags & M_EXT) {
1932                         wasted += MHLEN - sizeof(m->m_ext) +
1933                             m->m_ext.ext_size - m->m_len;
1934                 } else {
1935                         if (m->m_flags & M_PKTHDR)
1936                                 wasted += MHLEN - m->m_len;
1937                         else
1938                                 wasted += MLEN - m->m_len;
1939                 }
1940                 m = m->m_next;
1941         }
1942         /* be paranoid.. it helps */
1943         if (segments > MP_BUCKETS - 1)
1944                 segments = MP_BUCKETS - 1;
1945         if (used > 100000)
1946                 used = 100000;
1947         if (wasted > 100000)
1948                 wasted = 100000;
1949         /* store in the appropriate bucket */
1950         /* don't bother locking. if it's slightly off, so what? */
1951         mbprof.segments[segments]++;
1952         mbprof.used[fls(used)]++;
1953         mbprof.wasted[fls(wasted)]++;
1954 }
1955
1956 static void
1957 mbprof_textify(void)
1958 {
1959         int offset;
1960         char *c;
1961         uint64_t *p;
1962
1963         p = &mbprof.wasted[0];
1964         c = mbprofbuf;
1965         offset = snprintf(c, MP_MAXLINE + 10,
1966             "wasted:\n"
1967             "%ju %ju %ju %ju %ju %ju %ju %ju "
1968             "%ju %ju %ju %ju %ju %ju %ju %ju\n",
1969             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
1970             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
1971 #ifdef BIG_ARRAY
1972         p = &mbprof.wasted[16];
1973         c += offset;
1974         offset = snprintf(c, MP_MAXLINE,
1975             "%ju %ju %ju %ju %ju %ju %ju %ju "
1976             "%ju %ju %ju %ju %ju %ju %ju %ju\n",
1977             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
1978             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
1979 #endif
1980         p = &mbprof.used[0];
1981         c += offset;
1982         offset = snprintf(c, MP_MAXLINE + 10,
1983             "used:\n"
1984             "%ju %ju %ju %ju %ju %ju %ju %ju "
1985             "%ju %ju %ju %ju %ju %ju %ju %ju\n",
1986             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
1987             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
1988 #ifdef BIG_ARRAY
1989         p = &mbprof.used[16];
1990         c += offset;
1991         offset = snprintf(c, MP_MAXLINE,
1992             "%ju %ju %ju %ju %ju %ju %ju %ju "
1993             "%ju %ju %ju %ju %ju %ju %ju %ju\n",
1994             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
1995             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
1996 #endif
1997         p = &mbprof.segments[0];
1998         c += offset;
1999         offset = snprintf(c, MP_MAXLINE + 10,
2000             "segments:\n"
2001             "%ju %ju %ju %ju %ju %ju %ju %ju "
2002             "%ju %ju %ju %ju %ju %ju %ju %ju\n",
2003             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
2004             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
2005 #ifdef BIG_ARRAY
2006         p = &mbprof.segments[16];
2007         c += offset;
2008         offset = snprintf(c, MP_MAXLINE,
2009             "%ju %ju %ju %ju %ju %ju %ju %ju "
2010             "%ju %ju %ju %ju %ju %ju %ju %jju",
2011             p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
2012             p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
2013 #endif
2014 }
2015
2016 static int
2017 mbprof_handler(SYSCTL_HANDLER_ARGS)
2018 {
2019         int error;
2020
2021         mbprof_textify();
2022         error = SYSCTL_OUT(req, mbprofbuf, strlen(mbprofbuf) + 1);
2023         return (error);
2024 }
2025
2026 static int
2027 mbprof_clr_handler(SYSCTL_HANDLER_ARGS)
2028 {
2029         int clear, error;
2030
2031         clear = 0;
2032         error = sysctl_handle_int(oidp, &clear, 0, req);
2033         if (error || !req->newptr)
2034                 return (error);
2035
2036         if (clear) {
2037                 bzero(&mbprof, sizeof(mbprof));
2038         }
2039
2040         return (error);
2041 }
2042
2043
2044 SYSCTL_PROC(_kern_ipc, OID_AUTO, mbufprofile, CTLTYPE_STRING|CTLFLAG_RD,
2045             NULL, 0, mbprof_handler, "A", "mbuf profiling statistics");
2046
2047 SYSCTL_PROC(_kern_ipc, OID_AUTO, mbufprofileclr, CTLTYPE_INT|CTLFLAG_RW,
2048             NULL, 0, mbprof_clr_handler, "I", "clear mbuf profiling statistics");
2049 #endif
2050