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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e4659cba583c845785959067322c4b98


[ 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.