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