The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sys/mbuf.h

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: mbuf.h,v 1.105.2.1 2005/04/28 10:48:07 tron Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
    9  * NASA Ames Research Center and Matt Thomas of 3am Software Foundry.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Copyright (c) 1982, 1986, 1988, 1993
   42  *      The Regents of the University of California.  All rights reserved.
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. Neither the name of the University nor the names of its contributors
   53  *    may be used to endorse or promote products derived from this software
   54  *    without specific prior written permission.
   55  *
   56  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   57  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   59  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   60  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   61  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   62  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   66  * SUCH DAMAGE.
   67  *
   68  *      @(#)mbuf.h      8.5 (Berkeley) 2/19/95
   69  */
   70 
   71 #ifndef _SYS_MBUF_H_
   72 #define _SYS_MBUF_H_
   73 
   74 #ifdef _KERNEL_OPT
   75 #include "opt_mbuftrace.h"
   76 #endif
   77 
   78 #ifndef M_WAITOK
   79 #include <sys/malloc.h>
   80 #endif
   81 #include <sys/pool.h>
   82 #include <sys/queue.h>
   83 
   84 /* For offsetof() */
   85 #if defined(_KERNEL) || defined(_STANDALONE)
   86 #include <sys/systm.h>
   87 #else
   88 #include <stddef.h>
   89 #endif
   90 
   91 #include <uvm/uvm_param.h>      /* for MIN_PAGE_SIZE */
   92 
   93 /*
   94  * Mbufs are of a single size, MSIZE (machine/param.h), which
   95  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
   96  * MCLBYTES (also in machine/param.h), which has no additional overhead
   97  * and is used instead of the internal data area; this is done when
   98  * at least MINCLSIZE of data must be stored.
   99  */
  100 
  101 /* Packet tags structure */
  102 struct m_tag {
  103         SLIST_ENTRY(m_tag)      m_tag_link;     /* List of packet tags */
  104         u_int16_t               m_tag_id;       /* Tag ID */
  105         u_int16_t               m_tag_len;      /* Length of data */
  106 };
  107 
  108 /* mbuf ownership structure */
  109 struct mowner {
  110         char mo_name[16];               /* owner name (fxp0) */
  111         char mo_descr[16];              /* owner description (input) */
  112         LIST_ENTRY(mowner) mo_link;     /* */
  113         u_long mo_claims;               /* # of small mbuf claimed */
  114         u_long mo_releases;             /* # of small mbuf released */
  115         u_long mo_cluster_claims;       /* # of M_CLUSTER mbuf claimed */
  116         u_long mo_cluster_releases;     /* # of M_CLUSTER mbuf released */
  117         u_long mo_ext_claims;           /* # of M_EXT mbuf claimed */
  118         u_long mo_ext_releases;         /* # of M_EXT mbuf released */
  119 };
  120 
  121 /*
  122  * Macros for type conversion
  123  * mtod(m,t) -  convert mbuf pointer to data pointer of correct type
  124  */
  125 #define mtod(m,t)       ((t)((m)->m_data))
  126 
  127 /* header at beginning of each mbuf: */
  128 struct m_hdr {
  129         struct  mbuf *mh_next;          /* next buffer in chain */
  130         struct  mbuf *mh_nextpkt;       /* next chain in queue/record */
  131         caddr_t mh_data;                /* location of data */
  132         struct  mowner *mh_owner;       /* mbuf owner */
  133         int     mh_len;                 /* amount of data in this mbuf */
  134         int     mh_flags;               /* flags; see below */
  135         paddr_t mh_paddr;               /* physical address of mbuf */
  136         short   mh_type;                /* type of data in this mbuf */
  137 };
  138 
  139 /*
  140  * record/packet header in first mbuf of chain; valid if M_PKTHDR set
  141  *
  142  * A note about csum_data: For the out-bound direction, the low 16 bits
  143  * indicates the offset after the L4 header where the final L4 checksum value
  144  * is to be stored and the high 16 bits is the length of the L3 header (the
  145  * start of the data to be checksumed).  For the in-bound direction, it is only
  146  * valid if the M_CSUM_DATA flag is set.  In this case, an L4 checksum has been
  147  * calculated by hardware, but it is up to software to perform final
  148  * verification.
  149  *
  150  * Note for in-bound TCP/UDP checksums, we expect the csum_data to NOT
  151  * be bit-wise inverted (the final step in the calculation of an IP
  152  * checksum) -- this is so we can accumulate the checksum for fragmented
  153  * packets during reassembly.
  154  */
  155 struct  pkthdr {
  156         struct  ifnet *rcvif;           /* rcv interface */
  157         SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
  158         int     len;                    /* total packet length */
  159         int     csum_flags;             /* checksum flags */
  160         u_int32_t csum_data;            /* checksum data */
  161         u_int   segsz;                  /* segment size */
  162 };
  163 
  164 /*
  165  * Note: These bits are carefully arrange so that the compiler can have
  166  * a prayer of generating a jump table.
  167  */
  168 #define M_CSUM_TCPv4            0x00000001      /* TCP header/payload */
  169 #define M_CSUM_UDPv4            0x00000002      /* UDP header/payload */
  170 #define M_CSUM_TCP_UDP_BAD      0x00000004      /* TCP/UDP checksum bad */
  171 #define M_CSUM_DATA             0x00000008      /* consult csum_data */
  172 #define M_CSUM_TCPv6            0x00000010      /* IPv6 TCP header/payload */
  173 #define M_CSUM_UDPv6            0x00000020      /* IPv6 UDP header/payload */
  174 #define M_CSUM_IPv4             0x00000040      /* IPv4 header */
  175 #define M_CSUM_IPv4_BAD         0x00000080      /* IPv4 header checksum bad */
  176 #define M_CSUM_TSOv4            0x00000100      /* TCPv4 segmentation offload */
  177 
  178 /* Checksum-assist quirks: keep separate from jump-table bits. */
  179 #define M_CSUM_NO_PSEUDOHDR     0x80000000      /* Rx csum_data does not include
  180                                                  * the UDP/TCP pseudo-hdr, and
  181                                                  * is not yet 1s-complemented.
  182                                                  */
  183 
  184 /*
  185  * Macros for manipulating csum_data on outgoing packets.  These are
  186  * used to pass information down from the L4/L3 to the L2.
  187  */
  188 #define M_CSUM_DATA_IPv4_IPHL(x)        ((x) >> 16)
  189 #define M_CSUM_DATA_IPv4_OFFSET(x)      ((x) & 0xffff)
  190 
  191 /*
  192  * Max # of pages we can attach to m_ext.  This is carefully chosen
  193  * to be able to handle SOSEND_LOAN_CHUNK with our minimum sized page.
  194  */
  195 #ifdef MIN_PAGE_SIZE
  196 #define M_EXT_MAXPAGES          ((65536 / MIN_PAGE_SIZE) + 1)
  197 #endif
  198 
  199 /* description of external storage mapped into mbuf, valid if M_EXT set */
  200 struct _m_ext {
  201         caddr_t ext_buf;                /* start of buffer */
  202         void    (*ext_free)             /* free routine if not the usual */
  203                 (struct mbuf *, caddr_t, size_t, void *);
  204         void    *ext_arg;               /* argument for ext_free */
  205         size_t  ext_size;               /* size of buffer, for ext_free */
  206         struct malloc_type *ext_type;   /* malloc type */
  207         struct mbuf *ext_nextref;
  208         struct mbuf *ext_prevref;
  209         union {
  210                 paddr_t extun_paddr;    /* physical address (M_EXT_CLUSTER) */
  211                                         /* pages (M_EXT_PAGES) */
  212         /*
  213          * XXX This is gross, but it doesn't really matter; this is
  214          * XXX overlaid on top of the mbuf data area.
  215          */
  216 #ifdef M_EXT_MAXPAGES
  217                 struct vm_page *extun_pgs[M_EXT_MAXPAGES];
  218 #endif
  219         } ext_un;
  220 #define ext_paddr       ext_un.extun_paddr
  221 #define ext_pgs         ext_un.extun_pgs
  222 #ifdef DEBUG
  223         const char *ext_ofile;
  224         const char *ext_nfile;
  225         int ext_oline;
  226         int ext_nline;
  227 #endif
  228 };
  229 
  230 #define M_PADDR_INVALID         POOL_PADDR_INVALID
  231 
  232 /*
  233  * Definition of "struct mbuf".
  234  * Don't change this without understanding how MHLEN/MLEN are defined.
  235  */
  236 #define MBUF_DEFINE(name, mhlen, mlen)                                  \
  237         struct name {                                                   \
  238                 struct  m_hdr m_hdr;                                    \
  239                 union {                                                 \
  240                         struct {                                        \
  241                                 struct  pkthdr MH_pkthdr;               \
  242                                 union {                                 \
  243                                         struct  _m_ext MH_ext;          \
  244                                         char MH_databuf[(mhlen)];       \
  245                                 } MH_dat;                               \
  246                         } MH;                                           \
  247                         char M_databuf[(mlen)];                         \
  248                 } M_dat;                                                \
  249         }
  250 #define m_next          m_hdr.mh_next
  251 #define m_len           m_hdr.mh_len
  252 #define m_data          m_hdr.mh_data
  253 #define m_owner         m_hdr.mh_owner
  254 #define m_type          m_hdr.mh_type
  255 #define m_flags         m_hdr.mh_flags
  256 #define m_nextpkt       m_hdr.mh_nextpkt
  257 #define m_paddr         m_hdr.mh_paddr
  258 #define m_pkthdr        M_dat.MH.MH_pkthdr
  259 #define m_ext           M_dat.MH.MH_dat.MH_ext
  260 #define m_pktdat        M_dat.MH.MH_dat.MH_databuf
  261 #define m_dat           M_dat.M_databuf
  262 
  263 /*
  264  * Dummy mbuf structure to calculate the right values for MLEN/MHLEN, taking
  265  * into account inter-structure padding.
  266  */
  267 MBUF_DEFINE(_mbuf_dummy, 1, 1);
  268 
  269 /* normal data len */
  270 #define MLEN            (MSIZE - offsetof(struct _mbuf_dummy, m_dat))
  271 /* data len w/pkthdr */
  272 #define MHLEN           (MSIZE - offsetof(struct _mbuf_dummy, m_pktdat))
  273 
  274 #define MINCLSIZE       (MHLEN+MLEN+1)  /* smallest amount to put in cluster */
  275 #define M_MAXCOMPRESS   (MHLEN / 2)     /* max amount to copy for compression */
  276 
  277 /*
  278  * The *real* struct mbuf
  279  */
  280 MBUF_DEFINE(mbuf, MHLEN, MLEN);
  281 
  282 /* mbuf flags */
  283 #define M_EXT           0x0001  /* has associated external storage */
  284 #define M_PKTHDR        0x0002  /* start of record */
  285 #define M_EOR           0x0004  /* end of record */
  286 #define M_PROTO1        0x0008  /* protocol-specific */
  287 
  288 /* mbuf pkthdr flags, also in m_flags */
  289 #define M_AUTHIPHDR     0x0010  /* data origin authentication for IP header */
  290 #define M_DECRYPTED     0x0020  /* confidentiality */
  291 #define M_LOOP          0x0040  /* for Mbuf statistics */
  292 #define M_AUTHIPDGM     0x0080  /* data origin authentication */
  293 #define M_BCAST         0x0100  /* send/received as link-level broadcast */
  294 #define M_MCAST         0x0200  /* send/received as link-level multicast */
  295 #define M_CANFASTFWD    0x0400  /* used by filters to indicate packet can
  296                                    be fast-forwarded */
  297 #define M_ANYCAST6      0x0800  /* received as IPv6 anycast */
  298 #define M_LINK0         0x1000  /* link layer specific flag */
  299 #define M_LINK1         0x2000  /* link layer specific flag */
  300 #define M_LINK2         0x4000  /* link layer specific flag */
  301 
  302 /* additional flags for M_EXT mbufs */
  303 #define M_EXT_FLAGS     0xff000000
  304 #define M_EXT_CLUSTER   0x01000000      /* ext is a cluster */
  305 #define M_EXT_PAGES     0x02000000      /* ext_pgs is valid */
  306 #define M_EXT_ROMAP     0x04000000      /* ext mapping is r-o at MMU */
  307 #define M_EXT_RW        0x08000000      /* ext storage is writable */
  308 
  309 /* for source-level compatibility */
  310 #define M_CLUSTER       M_EXT_CLUSTER
  311 
  312 /* flags copied when copying m_pkthdr */
  313 #define M_COPYFLAGS     (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_ANYCAST6|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM)
  314 
  315 /* flag copied when shallow-copying external storage */
  316 #define M_EXTCOPYFLAGS  (M_EXT|M_EXT_FLAGS)
  317 
  318 /* mbuf types */
  319 #define MT_FREE         0       /* should be on free list */
  320 #define MT_DATA         1       /* dynamic (data) allocation */
  321 #define MT_HEADER       2       /* packet header */
  322 #define MT_SONAME       3       /* socket name */
  323 #define MT_SOOPTS       4       /* socket options */
  324 #define MT_FTABLE       5       /* fragment reassembly header */
  325 #define MT_CONTROL      6       /* extra-data protocol message */
  326 #define MT_OOBDATA      7       /* expedited data  */
  327 
  328 /* flags to m_get/MGET */
  329 #define M_DONTWAIT      M_NOWAIT
  330 #define M_WAIT          M_WAITOK
  331 
  332 /*
  333  * mbuf utility macros:
  334  *
  335  *      MBUFLOCK(code)
  336  * prevents a section of code from from being interrupted by network
  337  * drivers.
  338  */
  339 #define MBUFLOCK(code)                                                  \
  340 do {                                                                    \
  341         int ms = splvm();                                               \
  342         { code }                                                        \
  343         splx(ms);                                                       \
  344 } while (/* CONSTCOND */ 0)
  345 
  346 #ifdef MBUFTRACE
  347 /*
  348  * mbuf allocation tracing macros
  349  *
  350  */
  351 #define _MOWNERINIT(m, type)                                            \
  352         ((m)->m_owner = &unknown_mowners[(type)], (m)->m_owner->mo_claims++)
  353 
  354 #define _MOWNERREF(m, flags)    do {                                    \
  355         if ((flags) & M_EXT)                                            \
  356                 (m)->m_owner->mo_ext_claims++;                          \
  357         if ((flags) & M_CLUSTER)                                        \
  358                 (m)->m_owner->mo_cluster_claims++;                      \
  359 } while (/* CONSTCOND */ 0)
  360 
  361 #define MOWNERREF(m, flags)     MBUFLOCK( _MOWNERREF((m), (flags)); );
  362 
  363 #define _MOWNERREVOKE(m, all, flags)    do {                            \
  364         if ((flags) & M_EXT)                                            \
  365                 (m)->m_owner->mo_ext_releases++;                        \
  366         if ((flags) & M_CLUSTER)                                        \
  367                 (m)->m_owner->mo_cluster_releases++;                    \
  368         if (all) {                                                      \
  369                 (m)->m_owner->mo_releases++;                            \
  370                 (m)->m_owner = &revoked_mowner;                         \
  371         }                                                               \
  372 } while (/* CONSTCOND */ 0)
  373 
  374 #define _MOWNERCLAIM(m, mowner) do {                                    \
  375         (m)->m_owner = (mowner);                                        \
  376         (mowner)->mo_claims++;                                          \
  377         if ((m)->m_flags & M_EXT)                                       \
  378                 (mowner)->mo_ext_claims++;                              \
  379         if ((m)->m_flags & M_CLUSTER)                                   \
  380                 (mowner)->mo_cluster_claims++;                          \
  381 } while (/* CONSTCOND */ 0)
  382 
  383 #define MCLAIM(m, mowner)                                               \
  384         MBUFLOCK(                                                       \
  385                 if ((m)->m_owner != (mowner) && (mowner) != NULL) {     \
  386                         _MOWNERREVOKE((m), 1, (m)->m_flags);            \
  387                         _MOWNERCLAIM((m), (mowner));                    \
  388                 }                                                       \
  389         )
  390 
  391 #define MOWNER_ATTACH(mo)       LIST_INSERT_HEAD(&mowners, (mo), mo_link)
  392 #define MOWNER_DETACH(mo)       LIST_REMOVE((mo), mo_link)
  393 #define MBUFTRACE_ASSERT(cond)  KASSERT(cond)
  394 #else
  395 #define _MOWNERINIT(m, type)            do { } while (/* CONSTCOND */ 0)
  396 #define _MOWNERREF(m, flags)            do { } while (/* CONSTCOND */ 0)
  397 #define MOWNERREF(m, flags)             do { } while (/* CONSTCOND */ 0)
  398 #define _MOWNERREVOKE(m, all, flags)    do { } while (/* CONSTCOND */ 0)
  399 #define _MOWNERCLAIM(m, mowner)         do { } while (/* CONSTCOND */ 0)
  400 #define MCLAIM(m, mowner)               do { } while (/* CONSTCOND */ 0)
  401 #define MOWNER_ATTACH(mo)               do { } while (/* CONSTCOND */ 0)
  402 #define MOWNER_DETACH(mo)               do { } while (/* CONSTCOND */ 0)
  403 #define m_claimm(m, mo)                 do { } while (/* CONSTCOND */ 0)
  404 #define MBUFTRACE_ASSERT(cond)          do { } while (/* CONSTCOND */ 0)
  405 #endif
  406 
  407 
  408 /*
  409  * mbuf allocation/deallocation macros:
  410  *
  411  *      MGET(struct mbuf *m, int how, int type)
  412  * allocates an mbuf and initializes it to contain internal data.
  413  *
  414  *      MGETHDR(struct mbuf *m, int how, int type)
  415  * allocates an mbuf and initializes it to contain a packet header
  416  * and internal data.
  417  *
  418  * If 'how' is M_WAIT, these macros (and the corresponding functions)
  419  * are guaranteed to return successfully.
  420  */
  421 #define MGET(m, how, type)                                              \
  422 do {                                                                    \
  423         MBUFLOCK((m) = pool_cache_get(&mbpool_cache,                    \
  424             (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0););            \
  425         if (m) {                                                        \
  426                 MBUFLOCK(mbstat.m_mtypes[type]++;                       \
  427                     _MOWNERINIT((m), (type)); );                        \
  428                 (m)->m_type = (type);                                   \
  429                 (m)->m_next = (struct mbuf *)NULL;                      \
  430                 (m)->m_nextpkt = (struct mbuf *)NULL;                   \
  431                 (m)->m_data = (m)->m_dat;                               \
  432                 (m)->m_flags = 0;                                       \
  433         }                                                               \
  434 } while (/* CONSTCOND */ 0)
  435 
  436 #define MGETHDR(m, how, type)                                           \
  437 do {                                                                    \
  438         MBUFLOCK((m) = pool_cache_get(&mbpool_cache,                    \
  439             (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0););            \
  440         if (m) {                                                        \
  441                 MBUFLOCK(mbstat.m_mtypes[type]++;                       \
  442                     _MOWNERINIT((m), (type)); );                        \
  443                 (m)->m_type = (type);                                   \
  444                 (m)->m_next = (struct mbuf *)NULL;                      \
  445                 (m)->m_nextpkt = (struct mbuf *)NULL;                   \
  446                 (m)->m_data = (m)->m_pktdat;                            \
  447                 (m)->m_flags = M_PKTHDR;                                \
  448                 (m)->m_pkthdr.rcvif = NULL;                             \
  449                 (m)->m_pkthdr.csum_flags = 0;                           \
  450                 (m)->m_pkthdr.csum_data = 0;                            \
  451                 SLIST_INIT(&(m)->m_pkthdr.tags);                        \
  452         }                                                               \
  453 } while (/* CONSTCOND */ 0)
  454 
  455 #if defined(_KERNEL)
  456 #define _M_
  457 /*
  458  * Macros for tracking external storage associated with an mbuf.
  459  *
  460  * Note: add and delete reference must be called at splvm().
  461  */
  462 #ifdef DEBUG
  463 #define MCLREFDEBUGN(m, file, line)                                     \
  464 do {                                                                    \
  465         (m)->m_ext.ext_nfile = (file);                                  \
  466         (m)->m_ext.ext_nline = (line);                                  \
  467 } while (/* CONSTCOND */ 0)
  468 
  469 #define MCLREFDEBUGO(m, file, line)                                     \
  470 do {                                                                    \
  471         (m)->m_ext.ext_ofile = (file);                                  \
  472         (m)->m_ext.ext_oline = (line);                                  \
  473 } while (/* CONSTCOND */ 0)
  474 #else
  475 #define MCLREFDEBUGN(m, file, line)
  476 #define MCLREFDEBUGO(m, file, line)
  477 #endif
  478 
  479 #define MCLBUFREF(p)
  480 #define MCLISREFERENCED(m)      ((m)->m_ext.ext_nextref != (m))
  481 #define _MCLDEREFERENCE(m)                                              \
  482 do {                                                                    \
  483         (m)->m_ext.ext_nextref->m_ext.ext_prevref =                     \
  484                 (m)->m_ext.ext_prevref;                                 \
  485         (m)->m_ext.ext_prevref->m_ext.ext_nextref =                     \
  486                 (m)->m_ext.ext_nextref;                                 \
  487 } while (/* CONSTCOND */ 0)
  488 
  489 #define _MCLADDREFERENCE(o, n)                                          \
  490 do {                                                                    \
  491         (n)->m_flags |= ((o)->m_flags & M_EXTCOPYFLAGS);                \
  492         (n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref;                \
  493         (n)->m_ext.ext_prevref = (o);                                   \
  494         (o)->m_ext.ext_nextref = (n);                                   \
  495         (n)->m_ext.ext_nextref->m_ext.ext_prevref = (n);                \
  496         _MOWNERREF((n), (n)->m_flags);                                  \
  497         MCLREFDEBUGN((n), __FILE__, __LINE__);                          \
  498 } while (/* CONSTCOND */ 0)
  499 
  500 #define MCLINITREFERENCE(m)                                             \
  501 do {                                                                    \
  502         (m)->m_ext.ext_prevref = (m);                                   \
  503         (m)->m_ext.ext_nextref = (m);                                   \
  504         MCLREFDEBUGO((m), __FILE__, __LINE__);                          \
  505         MCLREFDEBUGN((m), NULL, 0);                                     \
  506 } while (/* CONSTCOND */ 0)
  507 
  508 #define MCLADDREFERENCE(o, n)   MBUFLOCK(_MCLADDREFERENCE((o), (n));)
  509 
  510 /*
  511  * Macros for mbuf external storage.
  512  *
  513  * MCLGET allocates and adds an mbuf cluster to a normal mbuf;
  514  * the flag M_EXT is set upon success.
  515  *
  516  * MEXTMALLOC allocates external storage and adds it to
  517  * a normal mbuf; the flag M_EXT is set upon success.
  518  *
  519  * MEXTADD adds pre-allocated external storage to
  520  * a normal mbuf; the flag M_EXT is set upon success.
  521  */
  522 #define _MCLGET(m, pool_cache, size, how)                               \
  523 do {                                                                    \
  524         MBUFLOCK(                                                       \
  525                 (m)->m_ext.ext_buf =                                    \
  526                     pool_cache_get_paddr((pool_cache),                  \
  527                         (how) == M_WAIT ? (PR_WAITOK|PR_LIMITFAIL) : 0, \
  528                         &(m)->m_ext.ext_paddr);                         \
  529                 if ((m)->m_ext.ext_buf != NULL)                         \
  530                         _MOWNERREF((m), M_EXT|M_CLUSTER);               \
  531         );                                                              \
  532         if ((m)->m_ext.ext_buf != NULL) {                               \
  533                 (m)->m_data = (m)->m_ext.ext_buf;                       \
  534                 (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) |       \
  535                                 M_EXT|M_CLUSTER|M_EXT_RW;               \
  536                 (m)->m_ext.ext_size = (size);                           \
  537                 (m)->m_ext.ext_free = NULL;                             \
  538                 (m)->m_ext.ext_arg = (pool_cache);                      \
  539                 /* ext_paddr initialized above */                       \
  540                 MCLINITREFERENCE(m);                                    \
  541         }                                                               \
  542 } while (/* CONSTCOND */ 0)
  543 
  544 /*
  545  * The standard mbuf cluster pool.
  546  */
  547 #define MCLGET(m, how)  _MCLGET((m), &mclpool_cache, MCLBYTES, (how))
  548 
  549 #define MEXTMALLOC(m, size, how)                                        \
  550 do {                                                                    \
  551         (m)->m_ext.ext_buf =                                            \
  552             (caddr_t)malloc((size), mbtypes[(m)->m_type], (how));       \
  553         if ((m)->m_ext.ext_buf != NULL) {                               \
  554                 (m)->m_data = (m)->m_ext.ext_buf;                       \
  555                 (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) |       \
  556                                 M_EXT|M_EXT_RW;                         \
  557                 (m)->m_ext.ext_size = (size);                           \
  558                 (m)->m_ext.ext_free = NULL;                             \
  559                 (m)->m_ext.ext_arg = NULL;                              \
  560                 (m)->m_ext.ext_type = mbtypes[(m)->m_type];             \
  561                 MCLINITREFERENCE(m);                                    \
  562                 MOWNERREF((m), M_EXT);                                  \
  563         }                                                               \
  564 } while (/* CONSTCOND */ 0)
  565 
  566 #define MEXTADD(m, buf, size, type, free, arg)                          \
  567 do {                                                                    \
  568         (m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf);              \
  569         (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | M_EXT;        \
  570         (m)->m_ext.ext_size = (size);                                   \
  571         (m)->m_ext.ext_free = (free);                                   \
  572         (m)->m_ext.ext_arg = (arg);                                     \
  573         (m)->m_ext.ext_type = (type);                                   \
  574         MCLINITREFERENCE(m);                                            \
  575         MOWNERREF((m), M_EXT);                                          \
  576 } while (/* CONSTCOND */ 0)
  577 
  578 #define MEXTREMOVE(m)                                                   \
  579 do {                                                                    \
  580         int _ms_ = splvm(); /* MBUFLOCK */                              \
  581         _MOWNERREVOKE((m), 0, (m)->m_flags);                            \
  582         m_ext_free(m, FALSE);                                           \
  583         splx(_ms_);                                                     \
  584         (m)->m_flags &= ~M_EXTCOPYFLAGS;                                \
  585         (m)->m_ext.ext_size = 0;        /* why ??? */                   \
  586 } while (/* CONSTCOND */ 0)
  587 
  588 /*
  589  * Reset the data pointer on an mbuf.
  590  */
  591 #define MRESETDATA(m)                                                   \
  592 do {                                                                    \
  593         if ((m)->m_flags & M_EXT)                                       \
  594                 (m)->m_data = (m)->m_ext.ext_buf;                       \
  595         else if ((m)->m_flags & M_PKTHDR)                               \
  596                 (m)->m_data = (m)->m_pktdat;                            \
  597         else                                                            \
  598                 (m)->m_data = (m)->m_dat;                               \
  599 } while (/* CONSTCOND */ 0)
  600 
  601 /*
  602  * MFREE(struct mbuf *m, struct mbuf *n)
  603  * Free a single mbuf and associated external storage.
  604  * Place the successor, if any, in n.
  605  */
  606 #define MFREE(m, n)                                                     \
  607         MBUFLOCK(                                                       \
  608                 mbstat.m_mtypes[(m)->m_type]--;                         \
  609                 if ((m)->m_flags & M_PKTHDR)                            \
  610                         m_tag_delete_chain((m), NULL);                  \
  611                 (n) = (m)->m_next;                                      \
  612                 _MOWNERREVOKE((m), 1, m->m_flags);                      \
  613                 if ((m)->m_flags & M_EXT) {                             \
  614                         m_ext_free(m, TRUE);                            \
  615                 } else {                                                \
  616                         pool_cache_put(&mbpool_cache, (m));             \
  617                 }                                                       \
  618         )
  619 
  620 /*
  621  * Copy mbuf pkthdr from `from' to `to'.
  622  * `from' must have M_PKTHDR set, and `to' must be empty.
  623  */
  624 #define M_COPY_PKTHDR(to, from)                                         \
  625 do {                                                                    \
  626         (to)->m_pkthdr = (from)->m_pkthdr;                              \
  627         (to)->m_flags = (from)->m_flags & M_COPYFLAGS;                  \
  628         SLIST_INIT(&(to)->m_pkthdr.tags);                               \
  629         m_tag_copy_chain((to), (from));                                 \
  630         (to)->m_data = (to)->m_pktdat;                                  \
  631 } while (/* CONSTCOND */ 0)
  632 
  633 /*
  634  * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
  635  * an object of the specified size at the end of the mbuf, longword aligned.
  636  */
  637 #define M_ALIGN(m, len)                                                 \
  638 do {                                                                    \
  639         (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1);            \
  640 } while (/* CONSTCOND */ 0)
  641 
  642 /*
  643  * As above, for mbufs allocated with m_gethdr/MGETHDR
  644  * or initialized by M_COPY_PKTHDR.
  645  */
  646 #define MH_ALIGN(m, len)                                                \
  647 do {                                                                    \
  648         (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1);           \
  649 } while (/* CONSTCOND */ 0)
  650 
  651 /*
  652  * Determine if an mbuf's data area is read-only.  This is true
  653  * if external storage is read-only mapped, or not marked as R/W,
  654  * or referenced by more than one mbuf.
  655  */
  656 #define M_READONLY(m)                                                   \
  657         (((m)->m_flags & M_EXT) != 0 &&                                 \
  658           (((m)->m_flags & (M_EXT_ROMAP|M_EXT_RW)) != M_EXT_RW ||       \
  659           MCLISREFERENCED(m)))
  660 
  661 /*
  662  * Determine if an mbuf's data area is read-only at the MMU.
  663  */
  664 #define M_ROMAP(m)                                                      \
  665         (((m)->m_flags & (M_EXT|M_EXT_ROMAP)) == (M_EXT|M_EXT_ROMAP))
  666 
  667 /*
  668  * Compute the amount of space available
  669  * before the current start of data in an mbuf.
  670  */
  671 #define _M_LEADINGSPACE(m)                                              \
  672         ((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf :      \
  673          (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat :        \
  674          (m)->m_data - (m)->m_dat)
  675 
  676 #define M_LEADINGSPACE(m)                                               \
  677         (M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m)))
  678 
  679 /*
  680  * Compute the amount of space available
  681  * after the end of data in an mbuf.
  682  */
  683 #define _M_TRAILINGSPACE(m)                                             \
  684         ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
  685          ((m)->m_data + (m)->m_len) :                                   \
  686          &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
  687 
  688 #define M_TRAILINGSPACE(m)                                              \
  689         (M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m)))
  690 
  691 /*
  692  * Compute the address of an mbuf's data area.
  693  */
  694 #define M_BUFADDR(m)                                                    \
  695         (((m)->m_flags & M_PKTHDR) ? (m)->m_pktdat : (m)->m_dat)
  696 
  697 /*
  698  * Compute the offset of the beginning of the data buffer of a non-ext
  699  * mbuf.
  700  */
  701 #define M_BUFOFFSET(m)                                                  \
  702         (((m)->m_flags & M_PKTHDR) ?                                    \
  703          offsetof(struct mbuf, m_pktdat) : offsetof(struct mbuf, m_dat))
  704 
  705 /*
  706  * Arrange to prepend space of size plen to mbuf m.
  707  * If a new mbuf must be allocated, how specifies whether to wait.
  708  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
  709  * is freed and m is set to NULL.
  710  */
  711 #define M_PREPEND(m, plen, how)                                         \
  712 do {                                                                    \
  713         if (M_LEADINGSPACE(m) >= (plen)) {                              \
  714                 (m)->m_data -= (plen);                                  \
  715                 (m)->m_len += (plen);                                   \
  716         } else                                                          \
  717                 (m) = m_prepend((m), (plen), (how));                    \
  718         if ((m) && (m)->m_flags & M_PKTHDR)                             \
  719                 (m)->m_pkthdr.len += (plen);                            \
  720 } while (/* CONSTCOND */ 0)
  721 
  722 /* change mbuf to new type */
  723 #define MCHTYPE(m, t)                                                   \
  724 do {                                                                    \
  725         MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \
  726         (m)->m_type = t;                                                \
  727 } while (/* CONSTCOND */ 0)
  728 
  729 /* length to m_copy to copy all */
  730 #define M_COPYALL       1000000000
  731 
  732 /* compatibility with 4.3 */
  733 #define  m_copy(m, o, l)        m_copym((m), (o), (l), M_DONTWAIT)
  734 
  735 /*
  736  * Allow drivers and/or protocols to use the rcvif member of
  737  * PKTHDR mbufs to store private context information.
  738  */
  739 #define M_GETCTX(m, t)          ((t) (m)->m_pkthdr.rcvif + 0)
  740 #define M_SETCTX(m, c)          ((void) ((m)->m_pkthdr.rcvif = (void *) (c)))
  741 
  742 #endif /* defined(_KERNEL) */
  743 
  744 /*
  745  * Mbuf statistics.
  746  * For statistics related to mbuf and cluster allocations, see also the
  747  * pool headers (mbpool and mclpool).
  748  */
  749 struct mbstat {
  750         u_long  _m_spare;       /* formerly m_mbufs */
  751         u_long  _m_spare1;      /* formerly m_clusters */
  752         u_long  _m_spare2;      /* spare field */
  753         u_long  _m_spare3;      /* formely m_clfree - free clusters */
  754         u_long  m_drops;        /* times failed to find space */
  755         u_long  m_wait;         /* times waited for space */
  756         u_long  m_drain;        /* times drained protocols for space */
  757         u_short m_mtypes[256];  /* type specific mbuf allocations */
  758 };
  759 
  760 /*
  761  * Mbuf sysctl variables.
  762  */
  763 #define MBUF_MSIZE              1       /* int: mbuf base size */
  764 #define MBUF_MCLBYTES           2       /* int: mbuf cluster size */
  765 #define MBUF_NMBCLUSTERS        3       /* int: limit on the # of clusters */
  766 #define MBUF_MBLOWAT            4       /* int: mbuf low water mark */
  767 #define MBUF_MCLLOWAT           5       /* int: mbuf cluster low water mark */
  768 #define MBUF_STATS              6       /* struct: mbstat */
  769 #define MBUF_MOWNERS            7       /* struct: m_owner[] */
  770 #define MBUF_MAXID              8       /* number of valid MBUF ids */
  771 
  772 #define CTL_MBUF_NAMES {                                                \
  773         { 0, 0 },                                                       \
  774         { "msize", CTLTYPE_INT },                                       \
  775         { "mclbytes", CTLTYPE_INT },                                    \
  776         { "nmbclusters", CTLTYPE_INT },                                 \
  777         { "mblowat", CTLTYPE_INT },                                     \
  778         { "mcllowat", CTLTYPE_INT },                                    \
  779         { 0 /* "stats" */, CTLTYPE_STRUCT },                            \
  780         { 0 /* "mowners" */, CTLTYPE_STRUCT },                          \
  781 }
  782 
  783 #ifdef  _KERNEL
  784 extern struct mbstat mbstat;
  785 extern int      nmbclusters;            /* limit on the # of clusters */
  786 extern int      mblowat;                /* mbuf low water mark */
  787 extern int      mcllowat;               /* mbuf cluster low water mark */
  788 extern int      max_linkhdr;            /* largest link-level header */
  789 extern int      max_protohdr;           /* largest protocol header */
  790 extern int      max_hdr;                /* largest link+protocol header */
  791 extern int      max_datalen;            /* MHLEN - max_hdr */
  792 extern const int msize;                 /* mbuf base size */
  793 extern const int mclbytes;              /* mbuf cluster size */
  794 extern struct pool mbpool;
  795 extern struct pool mclpool;
  796 extern struct pool_cache mbpool_cache;
  797 extern struct pool_cache mclpool_cache;
  798 #ifdef MBUFTRACE
  799 LIST_HEAD(mownerhead, mowner);
  800 extern struct mownerhead mowners;
  801 extern struct mowner unknown_mowners[];
  802 extern struct mowner revoked_mowner;
  803 #endif
  804 
  805 MALLOC_DECLARE(M_MBUF);
  806 MALLOC_DECLARE(M_SONAME);
  807 MALLOC_DECLARE(M_SOOPTS);
  808 
  809 struct  mbuf *m_copym(struct mbuf *, int, int, int);
  810 struct  mbuf *m_copypacket(struct mbuf *, int);
  811 struct  mbuf *m_devget(char *, int, int, struct ifnet *,
  812                             void (*copy)(const void *, void *, size_t));
  813 struct  mbuf *m_dup(struct mbuf *, int, int, int);
  814 struct  mbuf *m_free(struct mbuf *);
  815 struct  mbuf *m_get(int, int);
  816 struct  mbuf *m_getclr(int, int);
  817 struct  mbuf *m_gethdr(int, int);
  818 struct  mbuf *m_prepend(struct mbuf *,int, int);
  819 struct  mbuf *m_pulldown(struct mbuf *, int, int, int *);
  820 struct  mbuf *m_pullup(struct mbuf *, int);
  821 struct  mbuf *m_copyup(struct mbuf *, int, int);
  822 struct  mbuf *m_split(struct mbuf *,int, int);
  823 struct  mbuf *m_getptr(struct mbuf *, int, int *);
  824 void    m_adj(struct mbuf *, int);
  825 int     m_apply(struct mbuf *, int, int,
  826                 int (*)(void *, caddr_t, unsigned int), void *);
  827 void    m_cat(struct mbuf *,struct mbuf *);
  828 #ifdef MBUFTRACE
  829 void    m_claimm(struct mbuf *, struct mowner *);
  830 #endif
  831 void    m_clget(struct mbuf *, int);
  832 int     m_mballoc(int, int);
  833 void    m_copyback(struct mbuf *, int, int, const void *);
  834 struct  mbuf *m_copyback_cow(struct mbuf *, int, int, const void *, int);
  835 int     m_makewritable(struct mbuf **, int, int, int);
  836 void    m_copydata(struct mbuf *, int, int, void *);
  837 void    m_freem(struct mbuf *);
  838 void    m_reclaim(void *, int);
  839 void    mbinit(void);
  840 
  841 /* Inline routines. */
  842 static __inline u_int m_length(struct mbuf *) __unused;
  843 static __inline void m_ext_free(struct mbuf *, boolean_t) __unused;
  844 
  845 /* Packet tag routines */
  846 struct  m_tag *m_tag_get(int, int, int);
  847 void    m_tag_free(struct m_tag *);
  848 void    m_tag_prepend(struct mbuf *, struct m_tag *);
  849 void    m_tag_unlink(struct mbuf *, struct m_tag *);
  850 void    m_tag_delete(struct mbuf *, struct m_tag *);
  851 void    m_tag_delete_chain(struct mbuf *, struct m_tag *);
  852 void    m_tag_delete_nonpersistent(struct mbuf *);
  853 struct  m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
  854 struct  m_tag *m_tag_copy(struct m_tag *);
  855 int     m_tag_copy_chain(struct mbuf *, struct mbuf *);
  856 void    m_tag_init(struct mbuf *);
  857 struct  m_tag *m_tag_first(struct mbuf *);
  858 struct  m_tag *m_tag_next(struct mbuf *, struct m_tag *);
  859 
  860 /* Packet tag types */
  861 #define PACKET_TAG_NONE                         0  /* Nothing */
  862 #define PACKET_TAG_VLAN                         1  /* VLAN ID */
  863 #define PACKET_TAG_ENCAP                        2  /* encapsulation data */
  864 #define PACKET_TAG_ESP                          3  /* ESP information */
  865 #define PACKET_TAG_PF_GENERATED                 11 /* PF generated, pass always */
  866 #define PACKET_TAG_PF_ROUTED                    12 /* PF routed, no route loops */
  867 #define PACKET_TAG_PF_FRAGCACHE                 13 /* PF fragment cached */
  868 #define PACKET_TAG_PF_QID                       14 /* PF queue id */
  869 #define PACKET_TAG_PF_TAG                       15 /* PF tags */
  870 
  871 #define PACKET_TAG_IPSEC_IN_CRYPTO_DONE         16
  872 #define PACKET_TAG_IPSEC_IN_DONE                17
  873 #define PACKET_TAG_IPSEC_OUT_DONE               18
  874 #define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED      19  /* NIC IPsec crypto req'ed */
  875 #define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO     20  /* NIC notifies IPsec */
  876 #define PACKET_TAG_IPSEC_PENDING_TDB            21  /* Reminder to do IPsec */
  877 
  878 #define PACKET_TAG_IPSEC_SOCKET                 22 /* IPSEC socket ref */
  879 #define PACKET_TAG_IPSEC_HISTORY                23 /* IPSEC history */
  880 
  881 #define PACKET_TAG_PF_TRANSLATE_LOCALHOST       24 /* translated to localhost */
  882 #define PACKET_TAG_IPSEC_NAT_T_PORTS            25 /* two u_int16_t */
  883 
  884 /*
  885  * Return the number of bytes in the mbuf chain, m.
  886  */
  887 static __inline u_int
  888 m_length(struct mbuf *m)
  889 {
  890         struct mbuf *m0;
  891         u_int pktlen;
  892 
  893         if ((m->m_flags & M_PKTHDR) != 0)
  894                 return m->m_pkthdr.len;
  895 
  896         pktlen = 0;
  897         for (m0 = m; m0 != NULL; m0 = m0->m_next)
  898                 pktlen += m0->m_len;
  899         return pktlen;
  900 }
  901 
  902 /*
  903  * m_ext_free: release a reference to the mbuf external storage.
  904  *
  905  * => if 'dofree', free the mbuf m itsself as well.
  906  * => called at splvm.
  907  */
  908 static __inline void
  909 m_ext_free(struct mbuf *m, boolean_t dofree)
  910 {
  911 
  912         if (MCLISREFERENCED(m)) {
  913                 _MCLDEREFERENCE(m);
  914         } else if (m->m_flags & M_CLUSTER) {
  915                 pool_cache_put_paddr(m->m_ext.ext_arg,
  916                     m->m_ext.ext_buf, m->m_ext.ext_paddr);
  917         } else if (m->m_ext.ext_free) {
  918                 (*m->m_ext.ext_free)(dofree ? m : NULL, m->m_ext.ext_buf,
  919                     m->m_ext.ext_size, m->m_ext.ext_arg);
  920                 dofree = FALSE;
  921         } else {
  922                 free(m->m_ext.ext_buf, m->m_ext.ext_type);
  923         }
  924         if (dofree)
  925                 pool_cache_put(&mbpool_cache, m);
  926 }
  927 
  928 
  929 #endif /* _KERNEL */
  930 #endif /* !_SYS_MBUF_H_ */
  931 
  932 #ifdef _KERNEL
  933 #ifdef MBTYPES
  934 struct malloc_type *mbtypes[] = {               /* XXX */
  935         M_FREE,         /* MT_FREE      0       should be on free list */
  936         M_MBUF,         /* MT_DATA      1       dynamic (data) allocation */
  937         M_MBUF,         /* MT_HEADER    2       packet header */
  938         M_SONAME,       /* MT_SONAME    3       socket name */
  939         M_SOOPTS,       /* MT_SOOPTS    4       socket options */
  940         M_FTABLE,       /* MT_FTABLE    5       fragment reassembly header */
  941         M_MBUF,         /* MT_CONTROL   6       extra-data protocol message */
  942         M_MBUF,         /* MT_OOBDATA   7       expedited data  */
  943 };
  944 #undef MBTYPES
  945 #else
  946 extern struct malloc_type *mbtypes[];
  947 #endif /* MBTYPES */
  948 #endif /* _KERNEL */

Cache object: 1edeab2afa65257b6c806499c739d5e0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.