home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / os / bsdss4.tz / bsdss4 / bsdss / server / sys / mbuf.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-09  |  13.3 KB  |  416 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1992 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon 
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    mbuf.h,v $
  29.  * Revision 2.2  92/06/25  17:25:50  mrt
  30.  *     Return dtom back to masking.  Allocation routines will now
  31.  *     correctly allign mbufs.
  32.  *     [92/06/23            rwd]
  33.  * 
  34.  * Revision 2.1  92/04/21  17:15:34  rwd
  35.  * BSDSS
  36.  * 
  37.  *
  38.  */
  39.  
  40. /*
  41.  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
  42.  * 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. All advertising materials mentioning features or use of this software
  53.  *    must display the following acknowledgement:
  54.  *    This product includes software developed by the University of
  55.  *    California, Berkeley and its contributors.
  56.  * 4. Neither the name of the University nor the names of its contributors
  57.  *    may be used to endorse or promote products derived from this software
  58.  *    without specific prior written permission.
  59.  *
  60.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  61.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  62.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  63.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  64.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  65.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  66.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  67.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  68.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  69.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  70.  * SUCH DAMAGE.
  71.  *
  72.  *    @(#)mbuf.h    7.14 (Berkeley) 12/5/90
  73.  */
  74.  
  75. #ifndef M_WAITOK
  76. #include <sys/malloc.h>
  77. #endif
  78.  
  79. extern void mcl_free_routine();
  80. extern struct mbuf *mfree;
  81.  
  82. /*
  83.  * Mbufs are of a single size, MSIZE (machine/machparam.h), which
  84.  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
  85.  * MCLBYTES (also in machine/machparam.h), which has no additional overhead
  86.  * and is used instead of the internal data area; this is done when
  87.  * at least MINCLSIZE of data must be stored.
  88.  */
  89.  
  90. #define    MLEN        (MSIZE - sizeof(struct m_hdr))    /* normal data len */
  91. #define    MHLEN        (MLEN - sizeof(struct pkthdr))    /* data len w/pkthdr */
  92.  
  93. #define    MINCLSIZE    (MHLEN + MLEN)    /* smallest amount to put in cluster */
  94. #define    M_MAXCOMPRESS    (MHLEN / 2)    /* max amount to copy for compression */
  95.  
  96. /*
  97.  * Macros for type conversion
  98.  * mtod(m,t) -    convert mbuf pointer to data pointer of correct type
  99.  * dtom(x) -    convert data pointer within mbuf to mbuf pointer (XXX)
  100.  * mtocl(x) -    convert pointer within cluster to cluster index #
  101.  * cltom(x) -    convert cluster # to ptr to beginning of cluster
  102.  */
  103. #define mtod(m,t)    ((t)((m)->m_data))
  104. #define    dtom(x)        ((struct mbuf *)((int)(x) & ~(MSIZE-1)))
  105. #define    mtocl(x)    (((u_int)(x) - (u_int)mbutl) >> MCLSHIFT)
  106. #define    cltom(x)    ((caddr_t)((u_int)mbutl + ((u_int)(x) >> MCLSHIFT)))
  107.  
  108. /* header at beginning of each mbuf: */
  109. struct m_hdr {
  110.     struct    mbuf *mh_next;        /* next buffer in chain */
  111.     struct    mbuf *mh_nextpkt;    /* next chain in queue/record */
  112.     int    mh_len;            /* amount of data in this mbuf */
  113.     caddr_t    mh_data;        /* location of data */
  114.     short    mh_type;        /* type of data in this mbuf */
  115.     short    mh_flags;        /* flags; see below */
  116. };
  117.  
  118. /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
  119. struct    pkthdr {
  120.     int    len;        /* total packet length */
  121.     struct    ifnet *rcvif;    /* rcv interface */
  122. };
  123.  
  124. /* description of external storage mapped into mbuf, valid if M_EXT set */
  125. struct m_ext {
  126.     caddr_t    ext_buf;        /* start of buffer */
  127.     void    (*ext_free)();        /* free routine if not the usual */
  128.     u_int    ext_size;        /* size of buffer, for ext_free */
  129. };
  130.  
  131. struct mbuf {
  132.     struct    m_hdr m_hdr;
  133.     union {
  134.         struct {
  135.             struct    pkthdr MH_pkthdr;    /* M_PKTHDR set */
  136.             union {
  137.                 struct    m_ext MH_ext;    /* M_EXT set */
  138.                 char    MH_databuf[MHLEN];
  139.             } MH_dat;
  140.         } MH;
  141.         char    M_databuf[MLEN];        /* !M_PKTHDR, !M_EXT */
  142.     } M_dat;
  143. };
  144. #define    m_next        m_hdr.mh_next
  145. #define    m_len        m_hdr.mh_len
  146. #define    m_data        m_hdr.mh_data
  147. #define    m_type        m_hdr.mh_type
  148. #define    m_flags        m_hdr.mh_flags
  149. #define    m_nextpkt    m_hdr.mh_nextpkt
  150. #define    m_act        m_nextpkt
  151. #define    m_pkthdr    M_dat.MH.MH_pkthdr
  152. #define    m_ext        M_dat.MH.MH_dat.MH_ext
  153. #define    m_pktdat    M_dat.MH.MH_dat.MH_databuf
  154. #define    m_dat        M_dat.M_databuf
  155.  
  156. /* mbuf flags */
  157. #define    M_EXT        0x0001    /* has associated external storage */
  158. #define    M_PKTHDR    0x0002    /* start of record */
  159. #define    M_EOR        0x0004    /* end of record */
  160.  
  161. /* mbuf pkthdr flags, also in m_flags */
  162. #define    M_BCAST        0x0100    /* send/received as link-level broadcast */
  163. #define    M_MCAST        0x0200    /* send/received as link-level multicast */
  164.  
  165. /* flags copied when copying m_pkthdr */
  166. #define    M_COPYFLAGS    (M_PKTHDR|M_EOR|M_BCAST|M_MCAST)
  167.  
  168. /* mbuf types */
  169. #define    MT_FREE        0    /* should be on free list */
  170. #define    MT_DATA        1    /* dynamic (data) allocation */
  171. #define    MT_HEADER    2    /* packet header */
  172. #define    MT_SOCKET    3    /* socket structure */
  173. #define    MT_PCB        4    /* protocol control block */
  174. #define    MT_RTABLE    5    /* routing tables */
  175. #define    MT_HTABLE    6    /* IMP host tables */
  176. #define    MT_ATABLE    7    /* address resolution tables */
  177. #define    MT_SONAME    8    /* socket name */
  178. #define    MT_SOOPTS    10    /* socket options */
  179. #define    MT_FTABLE    11    /* fragment reassembly header */
  180. #define    MT_RIGHTS    12    /* access rights */
  181. #define    MT_IFADDR    13    /* interface address */
  182. #define MT_CONTROL    14    /* extra-data protocol message */
  183. #define MT_OOBDATA    15    /* expedited data  */
  184.  
  185. /* flags to m_get/MGET */
  186. #define    M_DONTWAIT    M_NOWAIT
  187. #define    M_WAIT        M_WAITOK
  188.  
  189. /*
  190.  * mbuf allocation/deallocation macros:
  191.  *
  192.  *    MGET(struct mbuf *m, int how, int type)
  193.  * allocates an mbuf and initializes it to contain internal data.
  194.  *
  195.  *    MGETHDR(struct mbuf *m, int how, int type)
  196.  * allocates an mbuf and initializes it to contain a packet header
  197.  * and internal data.
  198.  */
  199. #define    MGET(m, how, type) { \
  200.     int ms = splimp(); \
  201.         (m) = mfree; \
  202.     if (m) { \
  203.         mfree = (m)->m_next; \
  204.         (m)->m_type = (type); \
  205.         mbstat.m_mtypes[type]++; \
  206.         (m)->m_next = (struct mbuf *)NULL; \
  207.         (m)->m_nextpkt = (struct mbuf *)NULL; \
  208.         (m)->m_data = (m)->m_dat; \
  209.         (m)->m_flags = 0; \
  210.     } else \
  211.         (m) = m_retry((how), (type)); \
  212.     splx(ms); \
  213. }
  214.  
  215. #define    MGETHDR(m, how, type) { \
  216.     MGET(m, how, type) \
  217.     if (m) { \
  218.             (m)->m_data = (m)->m_pktdat; \
  219.             (m)->m_flags = M_PKTHDR; \
  220.     } else \
  221.         (m) = m_retryhdr((how), (type)); \
  222. }
  223.  
  224. /*
  225.  * Mbuf cluster macros.
  226.  * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster.
  227.  * MCLGET adds such clusters to a normal mbuf;
  228.  * the flag M_EXT is set upon success.
  229.  * MCLFREE releases a reference to a cluster allocated by MCLALLOC,
  230.  * freeing the cluster if the reference count has reached 0.
  231.  *
  232.  * Normal mbuf clusters are normally treated as character arrays
  233.  * after allocation, but use the first word of the buffer as a free list
  234.  * pointer while on the free list.
  235.  */
  236. union mcluster {
  237.     union    mcluster *mcl_next;
  238.     char    mcl_buf[MCLBYTES];
  239. };
  240.  
  241. #define    MCLALLOC(p, how) \
  242.     { int ms = splimp(); \
  243.       if (mclfree == 0) \
  244.         (void)m_clalloc(1, (how)); \
  245.       if ((p) = (caddr_t)mclfree) { \
  246.         ++mclrefcnt[mtocl(p)]; \
  247.         mbstat.m_clfree--; \
  248.         mclfree = ((union mcluster *)(p))->mcl_next; \
  249.       } \
  250.       splx(ms); \
  251.     }
  252.  
  253. #define    MCLGET(m, how) \
  254.     { MCLALLOC((m)->m_ext.ext_buf, (how)); \
  255.       if ((m)->m_ext.ext_buf != NULL) { \
  256.         (m)->m_data = (m)->m_ext.ext_buf; \
  257.         (m)->m_flags |= M_EXT; \
  258.         (m)->m_ext.ext_size = MCLBYTES;  \
  259.             (m)->m_ext.ext_free = mcl_free_routine; \
  260.       } \
  261.     }
  262.  
  263. #define    MCLFREE(p) \
  264.     { int ms = splimp(); \
  265.       if (--mclrefcnt[mtocl(p)] == 0) { \
  266.         ((union mcluster *)(p))->mcl_next = mclfree; \
  267.         mclfree = (union mcluster *)(p); \
  268.         mbstat.m_clfree++; \
  269.       } \
  270.       splx(ms); \
  271.     }
  272.  
  273. /*
  274.  * MFREE(struct mbuf *m, struct mbuf *n)
  275.  * Free a single mbuf and associated external storage.
  276.  * Place the successor, if any, in n.
  277.  */
  278. #define    MFREE(m, n) \
  279.     { int ms = splimp(); \
  280.       mbstat.m_mtypes[(m)->m_type]--; \
  281.       if ((m)->m_flags & M_EXT) { \
  282.         if ((m)->m_ext.ext_free) \
  283.             (*((m)->m_ext.ext_free))((m)->m_ext.ext_buf, \
  284.                 (m)->m_ext.ext_size); \
  285.         else \
  286.             MCLFREE((m)->m_ext.ext_buf); \
  287.       } \
  288.       (n) = (m)->m_next; \
  289.       (m)->m_next = mfree; mfree = (m); \
  290.       splx(ms); \
  291.     }
  292.  
  293. /*
  294.  * Copy mbuf pkthdr from from to to.
  295.  * from must have M_PKTHDR set, and to must be empty.
  296.  */
  297. #define    M_COPY_PKTHDR(to, from) { \
  298.     (to)->m_pkthdr = (from)->m_pkthdr; \
  299.     (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
  300.     (to)->m_data = (to)->m_pktdat; \
  301. }
  302.  
  303. /*
  304.  * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
  305.  * an object of the specified size at the end of the mbuf, longword aligned.
  306.  */
  307. #define    M_ALIGN(m, len) \
  308.     { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); }
  309. /*
  310.  * As above, for mbufs allocated with m_gethdr/MGETHDR
  311.  * or initialized by M_COPY_PKTHDR.
  312.  */
  313. #define    MH_ALIGN(m, len) \
  314.     { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); }
  315.  
  316. /*
  317.  * Compute the amount of space available
  318.  * before the current start of data in an mbuf.
  319.  */
  320. #define    M_LEADINGSPACE(m) \
  321.     ((m)->m_flags & M_EXT ? /* (m)->m_data - (m)->m_ext.ext_buf */ 0 : \
  322.         (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
  323.         (m)->m_data - (m)->m_dat)
  324.  
  325. /*
  326.  * Compute the amount of space available
  327.  * after the end of data in an mbuf.
  328.  */
  329. #define    M_TRAILINGSPACE(m) \
  330.     ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
  331.         ((m)->m_data + (m)->m_len) : \
  332.         &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
  333.  
  334. /*
  335.  * Arrange to prepend space of size plen to mbuf m.
  336.  * If a new mbuf must be allocated, how specifies whether to wait.
  337.  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
  338.  * is freed and m is set to NULL.
  339.  */
  340. #define    M_PREPEND(m, plen, how) { \
  341.     if (M_LEADINGSPACE(m) >= (plen)) { \
  342.         (m)->m_data -= (plen); \
  343.         (m)->m_len += (plen); \
  344.     } else \
  345.         (m) = m_prepend((m), (plen), (how)); \
  346.     if ((m) && (m)->m_flags & M_PKTHDR) \
  347.         (m)->m_pkthdr.len += (plen); \
  348. }
  349.  
  350. /* change mbuf to new type */
  351. #define MCHTYPE(m, t) { \
  352.     mbstat.m_mtypes[(m)->m_type]--; \
  353.     mbstat.m_mtypes[t]++; \
  354.     (m)->m_type = t;\
  355. }
  356.  
  357. /* length to m_copy to copy all */
  358. #define    M_COPYALL    1000000000
  359.  
  360. /* compatiblity with 4.3 */
  361. #define  m_copy(m, o, l)    m_copym((m), (o), (l), M_DONTWAIT)
  362.  
  363. /*
  364.  * Mbuf statistics.
  365.  */
  366. struct mbstat {
  367.     u_long    m_mbufs;    /* mbufs obtained from page pool */
  368.     u_long    m_clusters;    /* clusters obtained from page pool */
  369.     u_long    m_spare;    /* spare field */
  370.     u_long    m_clfree;    /* free clusters */
  371.     u_long    m_drops;    /* times failed to find space */
  372.     u_long    m_wait;        /* times waited for space */
  373.     u_long    m_drain;    /* times drained protocols for space */
  374.     u_short    m_mtypes[256];    /* type specific mbuf allocations */
  375. };
  376.  
  377. #ifdef    KERNEL
  378. extern    struct mbuf *mbutl;        /* virtual address of mclusters */
  379. extern    char *mclrefcnt;        /* cluster reference counts */
  380. struct    mbstat mbstat;
  381. int    nmbclusters;
  382. union    mcluster *mclfree;
  383. int    max_linkhdr;            /* largest link-level header */
  384. int    max_protohdr;            /* largest protocol header */
  385. int    max_hdr;            /* largest link+protocol header */
  386. int    max_datalen;            /* MHLEN - max_hdr */
  387. struct    mbuf *m_get(), *m_gethdr(), *m_getclr(), *m_retry(), *m_retryhdr();
  388. struct    mbuf *m_free(), *m_copym(), *m_pullup(), *m_prepend();
  389. int    m_clalloc();
  390. extern    int mbtypes[];            /* XXX */
  391.  
  392. #ifdef MBTYPES
  393. int mbtypes[] = {                /* XXX */
  394.     M_FREE,        /* MT_FREE    0    /* should be on free list */
  395.     M_MBUF,        /* MT_DATA    1    /* dynamic (data) allocation */
  396.     M_MBUF,        /* MT_HEADER    2    /* packet header */
  397.     M_SOCKET,    /* MT_SOCKET    3    /* socket structure */
  398.     M_PCB,        /* MT_PCB    4    /* protocol control block */
  399.     M_RTABLE,    /* MT_RTABLE    5    /* routing tables */
  400.     M_HTABLE,    /* MT_HTABLE    6    /* IMP host tables */
  401.     0,        /* MT_ATABLE    7    /* address resolution tables */
  402.     M_MBUF,        /* MT_SONAME    8    /* socket name */
  403.     0,        /*         9 */
  404.     M_SOOPTS,    /* MT_SOOPTS    10    /* socket options */
  405.     M_FTABLE,    /* MT_FTABLE    11    /* fragment reassembly header */
  406.     M_MBUF,        /* MT_RIGHTS    12    /* access rights */
  407.     M_IFADDR,    /* MT_IFADDR    13    /* interface address */
  408.     M_MBUF,        /* MT_CONTROL    14    /* extra-data protocol message */
  409.     M_MBUF,        /* MT_OOBDATA    15    /* expedited data  */
  410. #ifdef DATAKIT
  411.     25, 26, 27, 28, 29, 30, 31, 32        /* datakit ugliness */
  412. #endif
  413. };
  414. #endif
  415. #endif
  416.