|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1982, 1986, 1988, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * Redistribution and use in source and binary forms, with or without ! 31: * modification, are permitted provided that the following conditions ! 32: * are met: ! 33: * 1. Redistributions of source code must retain the above copyright ! 34: * notice, this list of conditions and the following disclaimer. ! 35: * 2. Redistributions in binary form must reproduce the above copyright ! 36: * notice, this list of conditions and the following disclaimer in the ! 37: * documentation and/or other materials provided with the distribution. ! 38: * 3. All advertising materials mentioning features or use of this software ! 39: * must display the following acknowledgement: ! 40: * This product includes software developed by the University of ! 41: * California, Berkeley and its contributors. ! 42: * 4. Neither the name of the University nor the names of its contributors ! 43: * may be used to endorse or promote products derived from this software ! 44: * without specific prior written permission. ! 45: * ! 46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 56: * SUCH DAMAGE. ! 57: * ! 58: * @(#)mbuf.h 8.5 (Berkeley) 2/19/95 ! 59: */ ! 60: ! 61: #ifndef _SYS_MBUF_H_ ! 62: #define _SYS_MBUF_H_ ! 63: ! 64: /* ! 65: * Mbufs are of a single size, MSIZE (machine/param.h), which ! 66: * includes overhead. An mbuf may add a single "mbuf cluster" of size ! 67: * MCLBYTES (also in machine/param.h), which has no additional overhead ! 68: * and is used instead of the internal data area; this is done when ! 69: * at least MINCLSIZE of data must be stored. ! 70: */ ! 71: ! 72: #define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */ ! 73: #define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */ ! 74: ! 75: #define MINCLSIZE (MHLEN + MLEN) /* smallest amount to put in cluster */ ! 76: #define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */ ! 77: ! 78: #define NMBPCL (sizeof(union mcluster) / sizeof(struct mbuf)) ! 79: ! 80: ! 81: /* ! 82: * Macros for type conversion ! 83: * mtod(m,t) - convert mbuf pointer to data pointer of correct type ! 84: * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX) ! 85: * mtocl(x) - convert pointer within cluster to cluster index # ! 86: * cltom(x) - convert cluster # to ptr to beginning of cluster ! 87: */ ! 88: #define mtod(m,t) ((t)((m)->m_data)) ! 89: #define dtom(x) ((struct mbuf *)((u_long)(x) & ~(MSIZE-1))) ! 90: #define mtocl(x) ((union mcluster *)(x) - (union mcluster *)mbutl) ! 91: #define cltom(x) ((union mcluster *)(mbutl + (x))) ! 92: ! 93: #define MCLREF(p) (++mclrefcnt[mtocl(p)]) ! 94: #define MCLUNREF(p) (--mclrefcnt[mtocl(p)] == 0) ! 95: ! 96: /* header at beginning of each mbuf: */ ! 97: struct m_hdr { ! 98: struct mbuf *mh_next; /* next buffer in chain */ ! 99: struct mbuf *mh_nextpkt; /* next chain in queue/record */ ! 100: long mh_len; /* amount of data in this mbuf */ ! 101: caddr_t mh_data; /* location of data */ ! 102: short mh_type; /* type of data in this mbuf */ ! 103: short mh_flags; /* flags; see below */ ! 104: }; ! 105: ! 106: /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */ ! 107: struct pkthdr { ! 108: int len; /* total packet length */ ! 109: struct ifnet *rcvif; /* rcv interface */ ! 110: }; ! 111: ! 112: ! 113: /* description of external storage mapped into mbuf, valid if M_EXT set */ ! 114: struct m_ext { ! 115: caddr_t ext_buf; /* start of buffer */ ! 116: void (*ext_free)(); /* free routine if not the usual */ ! 117: u_int ext_size; /* size of buffer, for ext_free */ ! 118: caddr_t ext_arg; /* additional ext_free argument */ ! 119: struct ext_refsq { /* references held */ ! 120: struct ext_refsq *forward, *backward; ! 121: } ext_refs; ! 122: }; ! 123: ! 124: struct mbuf { ! 125: struct m_hdr m_hdr; ! 126: union { ! 127: struct { ! 128: struct pkthdr MH_pkthdr; /* M_PKTHDR set */ ! 129: union { ! 130: struct m_ext MH_ext; /* M_EXT set */ ! 131: char MH_databuf[MHLEN]; ! 132: } MH_dat; ! 133: } MH; ! 134: char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */ ! 135: } M_dat; ! 136: }; ! 137: ! 138: #define m_next m_hdr.mh_next ! 139: #define m_len m_hdr.mh_len ! 140: #define m_data m_hdr.mh_data ! 141: #define m_type m_hdr.mh_type ! 142: #define m_flags m_hdr.mh_flags ! 143: #define m_nextpkt m_hdr.mh_nextpkt ! 144: #define m_act m_nextpkt ! 145: #define m_pkthdr M_dat.MH.MH_pkthdr ! 146: #define m_ext M_dat.MH.MH_dat.MH_ext ! 147: #define m_pktdat M_dat.MH.MH_dat.MH_databuf ! 148: #define m_dat M_dat.M_databuf ! 149: ! 150: /* mbuf flags */ ! 151: #define M_EXT 0x0001 /* has associated external storage */ ! 152: #define M_PKTHDR 0x0002 /* start of record */ ! 153: #define M_EOR 0x0004 /* end of record */ ! 154: ! 155: /* mbuf pkthdr flags, also in m_flags */ ! 156: #define M_BCAST 0x0100 /* send/received as link-level broadcast */ ! 157: #define M_MCAST 0x0200 /* send/received as link-level multicast */ ! 158: ! 159: /* flags copied when copying m_pkthdr */ ! 160: #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST) ! 161: ! 162: /* mbuf types */ ! 163: #define MT_FREE 0 /* should be on free list */ ! 164: #define MT_DATA 1 /* dynamic (data) allocation */ ! 165: #define MT_HEADER 2 /* packet header */ ! 166: #define MT_SOCKET 3 /* socket structure */ ! 167: #define MT_PCB 4 /* protocol control block */ ! 168: #define MT_RTABLE 5 /* routing tables */ ! 169: #define MT_HTABLE 6 /* IMP host tables */ ! 170: #define MT_ATABLE 7 /* address resolution tables */ ! 171: #define MT_SONAME 8 /* socket name */ ! 172: #define MT_SOOPTS 10 /* socket options */ ! 173: #define MT_FTABLE 11 /* fragment reassembly header */ ! 174: #define MT_RIGHTS 12 /* access rights */ ! 175: #define MT_IFADDR 13 /* interface address */ ! 176: #define MT_CONTROL 14 /* extra-data protocol message */ ! 177: #define MT_OOBDATA 15 /* expedited data */ ! 178: #define MT_MAX 32 /* enough? */ ! 179: ! 180: /* flags to m_get/MGET */ ! 181: #define M_DONTWAIT 0 ! 182: #define M_WAIT 1 ! 183: ! 184: /* ! 185: * mbuf utility macros: ! 186: * ! 187: * MBUFLOCK(code) ! 188: * prevents a section of code from from being interrupted by network ! 189: * drivers. ! 190: */ ! 191: #define MBUF_LOCK() ! 192: #define MBUF_UNLOCK() ! 193: #define MBUF_LOCKINIT() ! 194: ! 195: /* ! 196: * mbuf allocation/deallocation macros: ! 197: * ! 198: * MGET(struct mbuf *m, int how, int type) ! 199: * allocates an mbuf and initializes it to contain internal data. ! 200: * ! 201: * MGETHDR(struct mbuf *m, int how, int type) ! 202: * allocates an mbuf and initializes it to contain a packet header ! 203: * and internal data. ! 204: */ ! 205: ! 206: #ifdef DIAGNOSE ! 207: #define MCHECK(m) if ((m)->m_type != MT_FREE) panic("mget") ! 208: #else ! 209: #define MCHECK(m) ! 210: #endif ! 211: ! 212: extern struct mbuf *mfree; /* mbuf free list */ ! 213: ! 214: #define _MINTGET(m, type) { \ ! 215: int _ms = splimp(); \ ! 216: MBUF_LOCK(); \ ! 217: if (((m) = mfree) != 0) { \ ! 218: MCHECK(m); \ ! 219: ++mclrefcnt[mtocl(m)]; \ ! 220: mbstat.m_mtypes[MT_FREE]--; \ ! 221: mbstat.m_mtypes[type]++; \ ! 222: mfree = (m)->m_next; \ ! 223: } \ ! 224: MBUF_UNLOCK(); \ ! 225: splx(_ms); \ ! 226: } ! 227: ! 228: #define MGET(m, how, type) { \ ! 229: _MINTGET(m, type); \ ! 230: if (m) { \ ! 231: (m)->m_next = (m)->m_nextpkt = 0; \ ! 232: (m)->m_type = (type); \ ! 233: (m)->m_data = (m)->m_dat; \ ! 234: (m)->m_flags = 0; \ ! 235: } else \ ! 236: (m) = m_retry((how), (type)); \ ! 237: } ! 238: ! 239: #define MGETHDR(m, how, type) { \ ! 240: _MINTGET(m, type); \ ! 241: if (m) { \ ! 242: (m)->m_next = (m)->m_nextpkt = 0; \ ! 243: (m)->m_type = (type); \ ! 244: (m)->m_data = (m)->m_pktdat; \ ! 245: (m)->m_flags = M_PKTHDR; \ ! 246: } else \ ! 247: (m) = m_retryhdr((how), (type)); \ ! 248: } ! 249: ! 250: /* ! 251: * Mbuf cluster macros. ! 252: * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster. ! 253: * MCLGET adds such clusters to a normal mbuf; ! 254: * the flag M_EXT is set upon success. ! 255: * MCLFREE releases a reference to a cluster allocated by MCLALLOC, ! 256: * freeing the cluster if the reference count has reached 0. ! 257: * ! 258: * Normal mbuf clusters are normally treated as character arrays ! 259: * after allocation, but use the first word of the buffer as a free list ! 260: * pointer while on the free list. ! 261: */ ! 262: union mcluster { ! 263: union mcluster *mcl_next; ! 264: char mcl_buf[MCLBYTES]; ! 265: }; ! 266: ! 267: #define MCLALLOC(p, how) { \ ! 268: int _ms = splimp(); \ ! 269: MBUF_LOCK(); \ ! 270: (void)m_clalloc(1, (how)); \ ! 271: if (((p) = (caddr_t)mclfree)) { \ ! 272: ++mclrefcnt[mtocl(p)]; \ ! 273: mbstat.m_clfree--; \ ! 274: mclfree = ((union mcluster *)(p))->mcl_next; \ ! 275: } \ ! 276: MBUF_UNLOCK(); \ ! 277: splx(_ms); \ ! 278: } ! 279: ! 280: #define MCLGET(m, how) { \ ! 281: MCLALLOC((m)->m_ext.ext_buf, (how)); \ ! 282: if ((m)->m_ext.ext_buf) { \ ! 283: (m)->m_data = (m)->m_ext.ext_buf; \ ! 284: (m)->m_flags |= M_EXT; \ ! 285: (m)->m_ext.ext_size = MCLBYTES; \ ! 286: (m)->m_ext.ext_free = 0; \ ! 287: (m)->m_ext.ext_refs.forward = (m)->m_ext.ext_refs.backward = \ ! 288: &(m)->m_ext.ext_refs; \ ! 289: } \ ! 290: } ! 291: ! 292: #define MCLFREE(p) { \ ! 293: int _ms = splimp(); \ ! 294: MBUF_LOCK(); \ ! 295: if (--mclrefcnt[mtocl(p)] == 0) { \ ! 296: ((union mcluster *)(p))->mcl_next = mclfree; \ ! 297: mclfree = (union mcluster *)(p); \ ! 298: mbstat.m_clfree++; \ ! 299: } \ ! 300: MBUF_UNLOCK(); \ ! 301: splx(_ms); \ ! 302: } ! 303: ! 304: #define MCLHASREFERENCE(m) \ ! 305: ((m)->m_ext.ext_refs.forward != &((m)->m_ext.ext_refs)) ! 306: ! 307: /* ! 308: * MFREE(struct mbuf *m, struct mbuf *n) ! 309: * Free a single mbuf and associated external storage. ! 310: * Place the successor, if any, in n. ! 311: */ ! 312: ! 313: #define MFREE(m, n) (n) = m_free(m) ! 314: ! 315: /* ! 316: * Copy mbuf pkthdr from from to to. ! 317: * from must have M_PKTHDR set, and to must be empty. ! 318: */ ! 319: #define M_COPY_PKTHDR(to, from) { \ ! 320: (to)->m_pkthdr = (from)->m_pkthdr; \ ! 321: (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \ ! 322: (to)->m_data = (to)->m_pktdat; \ ! 323: } ! 324: ! 325: /* ! 326: * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place ! 327: * an object of the specified size at the end of the mbuf, longword aligned. ! 328: */ ! 329: #define M_ALIGN(m, len) \ ! 330: { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); } ! 331: /* ! 332: * As above, for mbufs allocated with m_gethdr/MGETHDR ! 333: * or initialized by M_COPY_PKTHDR. ! 334: */ ! 335: #define MH_ALIGN(m, len) \ ! 336: { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); } ! 337: ! 338: /* ! 339: * Compute the amount of space available ! 340: * before the current start of data in an mbuf. ! 341: * Subroutine - data not available if certain references. ! 342: */ ! 343: int m_leadingspace(struct mbuf *); ! 344: #define M_LEADINGSPACE(m) m_leadingspace(m) ! 345: ! 346: /* ! 347: * Compute the amount of space available ! 348: * after the end of data in an mbuf. ! 349: * Subroutine - data not available if certain references. ! 350: */ ! 351: int m_trailingspace(struct mbuf *); ! 352: #define M_TRAILINGSPACE(m) m_trailingspace(m) ! 353: ! 354: /* ! 355: * Arrange to prepend space of size plen to mbuf m. ! 356: * If a new mbuf must be allocated, how specifies whether to wait. ! 357: * If how is M_DONTWAIT and allocation fails, the original mbuf chain ! 358: * is freed and m is set to NULL. ! 359: */ ! 360: #define M_PREPEND(m, plen, how) { \ ! 361: if (M_LEADINGSPACE(m) >= (plen)) { \ ! 362: (m)->m_data -= (plen); \ ! 363: (m)->m_len += (plen); \ ! 364: } else \ ! 365: (m) = m_prepend((m), (plen), (how)); \ ! 366: if ((m) && (m)->m_flags & M_PKTHDR) \ ! 367: (m)->m_pkthdr.len += (plen); \ ! 368: } ! 369: ! 370: /* change mbuf to new type */ ! 371: #define MCHTYPE(m, t) { \ ! 372: int _ms = splimp(); \ ! 373: MBUF_LOCK(); \ ! 374: mbstat.m_mtypes[(m)->m_type]--; \ ! 375: mbstat.m_mtypes[t]++; \ ! 376: (m)->m_type = t; \ ! 377: MBUF_UNLOCK(); \ ! 378: splx(_ms); \ ! 379: } ! 380: ! 381: /* length to m_copy to copy all */ ! 382: #define M_COPYALL 1000000000 ! 383: ! 384: /* compatiblity with 4.3 */ ! 385: #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT) ! 386: ! 387: /* ! 388: * Mbuf statistics. ! 389: */ ! 390: struct mbstat { ! 391: u_long m_mbufs; /* mbufs obtained from page pool */ ! 392: u_long m_clusters; /* clusters obtained from page pool */ ! 393: u_long m_spare; /* spare field */ ! 394: u_long m_clfree; /* free clusters */ ! 395: u_long m_drops; /* times failed to find space */ ! 396: u_long m_wait; /* times waited for space */ ! 397: u_long m_drain; /* times drained protocols for space */ ! 398: u_short m_mtypes[256]; /* type specific mbuf allocations */ ! 399: }; ! 400: ! 401: #ifdef _KERNEL ! 402: extern union mcluster *mbutl; /* virtual address of mclusters */ ! 403: extern union mcluster embutl; /* virtual address of mclusters */ ! 404: extern short *mclrefcnt; /* cluster reference counts */ ! 405: extern struct mbstat mbstat; /* statistics */ ! 406: extern int nmbclusters; /* number of mapped clusters */ ! 407: extern union mcluster *mclfree; /* free mapped cluster list */ ! 408: extern int max_linkhdr; /* largest link-level header */ ! 409: extern int max_protohdr; /* largest protocol header */ ! 410: extern int max_hdr; /* largest link+protocol header */ ! 411: extern int max_datalen; /* MHLEN - max_hdr */ ! 412: ! 413: struct mbuf *m_copym __P((struct mbuf *, int, int, int)); ! 414: struct mbuf *m_free __P((struct mbuf *)); ! 415: struct mbuf *m_get __P((int, int)); ! 416: struct mbuf *m_getclr __P((int, int)); ! 417: struct mbuf *m_gethdr __P((int, int)); ! 418: struct mbuf *m_prepend __P((struct mbuf *, int, int)); ! 419: struct mbuf *m_pullup __P((struct mbuf *, int)); ! 420: struct mbuf *m_retry __P((int, int)); ! 421: struct mbuf *m_retryhdr __P((int, int)); ! 422: void m_adj __P((struct mbuf *, int)); ! 423: int m_clalloc __P((int, int)); ! 424: void m_freem __P((struct mbuf *)); ! 425: struct mbuf *m_devget __P((char *, int, int, struct ifnet *, void (*)())); ! 426: #endif ! 427: #endif /* !_SYS_MBUF_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.