1/* 2 * Copyright (c) 1999-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */ 29/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 30/* 31 * Mach Operating System 32 * Copyright (c) 1987 Carnegie-Mellon University 33 * All rights reserved. The CMU software License Agreement specifies 34 * the terms and conditions for use and redistribution. 35 */ 36/* 37 * Copyright (c) 1994 NeXT Computer, Inc. All rights reserved. 38 * 39 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 40 * All rights reserved. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 71 */ 72/* 73 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 74 * support for mandatory and extensible security protections. This notice 75 * is included in support of clause 2.2 (b) of the Apple Public License, 76 * Version 2.0. 77 */ 78 79#ifndef _SYS_MBUF_H_ 80#define _SYS_MBUF_H_ 81 82#include <sys/cdefs.h> 83#include <sys/appleapiopts.h> 84 85#ifdef XNU_KERNEL_PRIVATE 86 87#include <sys/lock.h> 88#include <sys/queue.h> 89 90/* 91 * Mbufs are of a single size, MSIZE (machine/param.h), which 92 * includes overhead. An mbuf may add a single "mbuf cluster" of size 93 * MCLBYTES/MBIGCLBYTES/M16KCLBYTES (also in machine/param.h), which has 94 * no additional overhead and is used instead of the internal data area; 95 * this is done when at least MINCLSIZE of data must be stored. 96 */ 97 98/* 99 * The following _MLEN and _MHLEN macros are private to xnu. Private code 100 * that are outside of xnu must use the mbuf_get_{mlen,mhlen} routines since 101 * the sizes of the structures are dependent upon specific xnu configs. 102 */ 103#define _MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */ 104#define _MHLEN (_MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */ 105 106#define NMBPBGSHIFT (MBIGCLSHIFT - MSIZESHIFT) 107#define NMBPBG (1 << NMBPBGSHIFT) /* # of mbufs per big cl */ 108 109#define NCLPBGSHIFT (MBIGCLSHIFT - MCLSHIFT) 110#define NCLPBG (1 << NCLPBGSHIFT) /* # of cl per big cl */ 111 112#define NMBPCLSHIFT (NMBPBGSHIFT - NCLPBGSHIFT) 113#define NMBPCL (1 << NMBPCLSHIFT) /* # of mbufs per cl */ 114 115#define NCLPJCLSHIFT ((M16KCLSHIFT - MBIGCLSHIFT) + NCLPBGSHIFT) 116#define NCLPJCL (1 << NCLPJCLSHIFT) /* # of cl per jumbo cl */ 117 118/* 119 * Macros for type conversion 120 * mtod(m,t) - convert mbuf pointer to data pointer of correct type 121 * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX) 122 */ 123#define mtod(m, t) ((t)m_mtod(m)) 124#define dtom(x) m_dtom(x) 125 126/* header at beginning of each mbuf: */ 127struct m_hdr { 128 struct mbuf *mh_next; /* next buffer in chain */ 129 struct mbuf *mh_nextpkt; /* next chain in queue/record */ 130 int32_t mh_len; /* amount of data in this mbuf */ 131 caddr_t mh_data; /* location of data */ 132 short mh_type; /* type of data in this mbuf */ 133 short mh_flags; /* flags; see below */ 134}; 135 136/* 137 * Packet tag structure (see below for details). 138 */ 139struct m_tag { 140 u_int64_t m_tag_cookie; /* Error checking */ 141#ifndef __LP64__ 142 u_int32_t pad; /* For structure alignment */ 143#endif /* !__LP64__ */ 144 SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */ 145 u_int16_t m_tag_type; /* Module specific type */ 146 u_int16_t m_tag_len; /* Length of data */ 147 u_int32_t m_tag_id; /* Module ID */ 148}; 149 150#define M_TAG_ALIGN(len) \ 151 (P2ROUNDUP(len, sizeof (u_int64_t)) + sizeof (struct m_tag)) 152 153#define M_TAG_VALID_PATTERN 0xfeedfacefeedfaceULL 154#define M_TAG_FREE_PATTERN 0xdeadbeefdeadbeefULL 155 156/* 157 * Packet tag header structure (at the top of mbuf). Pointers are 158 * 32-bit in ILP32; m_tag needs 64-bit alignment, hence padded. 159 */ 160struct m_taghdr { 161#ifndef __LP64__ 162 u_int32_t pad; /* For structure alignment */ 163#endif /* !__LP64__ */ 164 u_int64_t refcnt; /* Number of tags in this mbuf */ 165}; 166 167/* Values for pftag_flags */ 168#define PF_TAG_GENERATED 0x000001 /* pkt generated by PF */ 169#define PF_TAG_FRAGCACHE 0x000002 170#define PF_TAG_TRANSLATE_LOCALHOST 0x000004 171#define PF_TAG_FLOWHASH 0x000100 /* valid flowhash value */ 172#define PF_TAG_HDR_INET 0x000200 /* hdr points to IPv4 */ 173#define PF_TAG_HDR_INET6 0x000400 /* hdr points to IPv6 */ 174#define PF_TAG_TCP 0x000800 /* payload is TCP */ 175#define PF_TAG_FLOWADV 0x010000 /* local flow advisory */ 176#define PF_TAG_QUEUE1 0x100000 /* queue-specific */ 177 178#define IF_PKTSEQ_SHIFT 4 179 180/* PF mbuf tag */ 181struct pf_mtag { 182 void *pftag_hdr; /* saved hdr pos in mbuf, for ECN */ 183 unsigned int pftag_rtableid; /* alternate routing table id */ 184 union { 185 struct { 186 u_int32_t qid; 187 union { 188 u_int8_t val8[4]; 189 u_int16_t val16[2]; 190 u_int32_t val32; 191 } __qpriv_u; /* for queue-specific use */ 192 } __pf_data; 193 u_int64_t pktseq; 194 } __pfifseq_u; /* Used for pf or interface bandwidth measurement */ 195#define pftag_qid __pfifseq_u.__pf_data.qid 196#define pftag_qpriv8 __pfifseq_u.__pf_data.__qpriv_u.val8 197#define pftag_qpriv16 __pfifseq_u.__pf_data.__qpriv_u.val16 198#define pftag_qpriv32 __pfifseq_u.__pf_data.__qpriv_u.val32 199#define pftag_pktseq __pfifseq_u.pktseq 200 u_int32_t pftag_flowhash; 201 u_int16_t pftag_tag; 202 u_int16_t pftag_routed; 203 u_int32_t pftag_flags; /* PF_TAG flags */ 204}; 205 206/* TCP specific mbuf tag */ 207struct tcp_mtag { 208 u_int tm_tso_segz; /* TSO segment size (actual MSS) */ 209 u_int16_t tm_pktlen; /* LRO - max segment size encountered */ 210 u_int16_t tm_npkts; /* LRO - number of coalesced TCP pkts */ 211}; 212 213/* record/packet header in first mbuf of chain; valid if M_PKTHDR set */ 214struct pkthdr { 215 int len; /* total packet length */ 216 struct ifnet *rcvif; /* rcv interface */ 217 218 /* variables for ip and tcp reassembly */ 219 void *header; /* pointer to packet header */ 220 /* variables for hardware checksum */ 221 /* Note: csum_flags is used for hardware checksum and VLAN */ 222 int csum_flags; /* flags regarding checksum */ 223 int csum_data; /* data field used by csum routines */ 224 u_short vlan_tag; /* VLAN tag, host byte order */ 225 u_short socket_id; /* socket id */ 226 SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */ 227 struct pf_mtag pf_mtag; /* built-in PF tag */ 228#define m_flowhash pf_mtag.pftag_flowhash 229#define m_fhflags pf_mtag.pftag_flags 230 u_int32_t svc; /* MBUF_SVC value */ 231 u_int16_t vt_nrecs; /* # of IGMPv3/MLDv2 records */ 232 u_int16_t aux_flags; /* auxiliary packet flags */ 233 struct tcp_mtag tcp_mtag; /* tcp related data */ 234#define tso_segsz tcp_mtag.tm_tso_segz 235#define lro_pktlen tcp_mtag.tm_pktlen 236#define lro_npkts tcp_mtag.tm_npkts 237}; 238 239/* description of external storage mapped into mbuf, valid if M_EXT set */ 240struct m_ext { 241 caddr_t ext_buf; /* start of buffer */ 242 void (*ext_free)(caddr_t, u_int, caddr_t); /* free routine if not the usual */ 243 u_int ext_size; /* size of buffer, for ext_free */ 244 caddr_t ext_arg; /* additional ext_free argument */ 245 struct ext_refsq { /* references held */ 246 struct ext_refsq *forward, *backward; 247 } ext_refs; 248 struct ext_ref { 249 u_int32_t refcnt; 250 u_int32_t flags; 251 } *ext_refflags; 252}; 253 254/* define m_ext to a type since it gets redefined below */ 255typedef struct m_ext _m_ext_t; 256 257struct mbuf { 258 struct m_hdr m_hdr; 259 union { 260 struct { 261 struct pkthdr MH_pkthdr; /* M_PKTHDR set */ 262 union { 263 struct m_ext MH_ext; /* M_EXT set */ 264 char MH_databuf[_MHLEN]; 265 } MH_dat; 266 } MH; 267 char M_databuf[_MLEN]; /* !M_PKTHDR, !M_EXT */ 268 } M_dat; 269}; 270 271#define m_next m_hdr.mh_next 272#define m_len m_hdr.mh_len 273#define m_data m_hdr.mh_data 274#define m_type m_hdr.mh_type 275#define m_flags m_hdr.mh_flags 276#define m_nextpkt m_hdr.mh_nextpkt 277#define m_act m_nextpkt 278#define m_pkthdr M_dat.MH.MH_pkthdr 279#define m_ext M_dat.MH.MH_dat.MH_ext 280#define m_pktdat M_dat.MH.MH_dat.MH_databuf 281#define m_dat M_dat.M_databuf 282#define m_pktlen(_m) ((_m)->m_pkthdr.len) 283#define m_pftag(_m) (&(_m)->m_pkthdr.pf_mtag) 284 285/* mbuf flags (private) */ 286#define M_EXT 0x0001 /* has associated external storage */ 287#define M_PKTHDR 0x0002 /* start of record */ 288#define M_EOR 0x0004 /* end of record */ 289#define M_PROTO1 0x0008 /* protocol-specific */ 290#define M_PROTO2 0x0010 /* protocol-specific */ 291#define M_PROTO3 0x0020 /* protocol-specific */ 292#define M_LOOP 0x0040 /* packet is looped back */ 293#define M_PROTO5 0x0080 /* protocol-specific */ 294 295/* mbuf pkthdr flags, also in m_flags (private) */ 296#define M_BCAST 0x0100 /* send/received as link-level broadcast */ 297#define M_MCAST 0x0200 /* send/received as link-level multicast */ 298#define M_FRAG 0x0400 /* packet is a fragment of a larger packet */ 299#define M_FIRSTFRAG 0x0800 /* packet is first fragment */ 300#define M_LASTFRAG 0x1000 /* packet is last fragment */ 301#define M_PROMISC 0x2000 /* packet is promiscuous (shouldn't go to stack) */ 302#define M_HASFCS 0x4000 /* packet has FCS */ 303#define M_TAGHDR 0x8000 /* m_tag hdr structure at top of mbuf data */ 304 305/* 306 * Flags to purge when crossing layers. 307 */ 308#define M_PROTOFLAGS \ 309 (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO5) 310 311/* flags copied when copying m_pkthdr */ 312#define M_COPYFLAGS \ 313 (M_PKTHDR|M_EOR|M_PROTO1|M_PROTO2|M_PROTO3 | \ 314 M_LOOP|M_PROTO5|M_BCAST|M_MCAST|M_FRAG | \ 315 M_FIRSTFRAG|M_LASTFRAG|M_PROMISC|M_HASFCS) 316 317/* flags indicating hw checksum support and sw checksum requirements */ 318#define CSUM_IP 0x0001 /* will csum IP */ 319#define CSUM_TCP 0x0002 /* will csum TCP */ 320#define CSUM_UDP 0x0004 /* will csum UDP */ 321#define CSUM_IP_FRAGS 0x0008 /* will csum IP fragments */ 322#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */ 323#define CSUM_TCPIPV6 0x0020 /* will csum TCP for IPv6 */ 324#define CSUM_UDPIPV6 0x0040 /* will csum UDP for IPv6 */ 325#define CSUM_FRAGMENT_IPV6 0x0080 /* will do IPv6 fragmentation */ 326 327#define CSUM_IP_CHECKED 0x0100 /* did csum IP */ 328#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */ 329#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */ 330#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */ 331#define CSUM_TCP_SUM16 0x1000 /* simple TCP Sum16 computation */ 332 333#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP) 334#define CSUM_DELAY_IP (CSUM_IP) /* IPv4 only: no IPv6 IP cksum */ 335#define CSUM_DELAY_IPV6_DATA (CSUM_TCPIPV6 | CSUM_UDPIPV6) 336#define CSUM_DATA_IPV6_VALID CSUM_DATA_VALID /* csum_data field is valid */ 337/* 338 * Note: see also IF_HWASSIST_CSUM defined in <net/if_var.h> 339 */ 340/* bottom 16 bits reserved for hardware checksum */ 341#define CSUM_CHECKSUM_MASK 0xffff 342 343/* VLAN tag present */ 344#define CSUM_VLAN_TAG_VALID 0x10000 /* vlan_tag field is valid */ 345 346/* TCP Segment Offloading requested on this mbuf */ 347#define CSUM_TSO_IPV4 0x100000 /* This mbuf needs to be segmented by the NIC */ 348#define CSUM_TSO_IPV6 0x200000 /* This mbuf needs to be segmented by the NIC */ 349 350/* 351 * Auxiliary packet flags. Unlike m_flags, all auxiliary flags are copied 352 * along when copying m_pkthdr, i.e. no equivalent of M_COPYFLAGS here. 353 * Note that this flag is 16-bit wide. 354 */ 355#define MAUXF_PRIO_PRIVILEGED 0x0001 /* packet priority is privileged */ 356#define MAUXF_PROXY_DST 0x0002 /* processed but not locally destined */ 357#define MAUXF_INET_RESOLVE_RTR 0x0004 /* pkt is for resolving IPv4 router */ 358#define MAUXF_INET6_RESOLVE_RTR 0x0008 /* pkt is for resolving IPv6 router */ 359#define MAUXF_SW_LRO_PKT 0x0010 /* pkt is a large coalesced pkt */ 360#define MAUXF_SW_LRO_DID_CSUM 0x0020 /* IP and TCP checksums done by LRO*/ 361#endif /* XNU_KERNEL_PRIVATE */ 362 363/* mbuf types */ 364#define MT_FREE 0 /* should be on free list */ 365#define MT_DATA 1 /* dynamic (data) allocation */ 366#define MT_HEADER 2 /* packet header */ 367#define MT_SOCKET 3 /* socket structure */ 368#define MT_PCB 4 /* protocol control block */ 369#define MT_RTABLE 5 /* routing tables */ 370#define MT_HTABLE 6 /* IMP host tables */ 371#define MT_ATABLE 7 /* address resolution tables */ 372#define MT_SONAME 8 /* socket name */ 373#define MT_SOOPTS 10 /* socket options */ 374#define MT_FTABLE 11 /* fragment reassembly header */ 375#define MT_RIGHTS 12 /* access rights */ 376#define MT_IFADDR 13 /* interface address */ 377#define MT_CONTROL 14 /* extra-data protocol message */ 378#define MT_OOBDATA 15 /* expedited data */ 379#define MT_TAG 16 /* volatile metadata associated to pkts */ 380#define MT_MAX 32 /* enough? */ 381 382#ifdef XNU_KERNEL_PRIVATE 383/* 384 * mbuf allocation/deallocation macros: 385 * 386 * MGET(struct mbuf *m, int how, int type) 387 * allocates an mbuf and initializes it to contain internal data. 388 * 389 * MGETHDR(struct mbuf *m, int how, int type) 390 * allocates an mbuf and initializes it to contain a packet header 391 * and internal data. 392 */ 393 394#if 1 395#define MCHECK(m) m_mcheck(m) 396#else 397#define MCHECK(m) 398#endif 399 400#define MGET(m, how, type) ((m) = m_get((how), (type))) 401 402#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type))) 403 404/* 405 * Mbuf cluster macros. 406 * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster. 407 * MCLGET adds such clusters to a normal mbuf; 408 * the flag M_EXT is set upon success. 409 * MCLFREE releases a reference to a cluster allocated by MCLALLOC, 410 * freeing the cluster if the reference count has reached 0. 411 * 412 * Normal mbuf clusters are normally treated as character arrays 413 * after allocation, but use the first word of the buffer as a free list 414 * pointer while on the free list. 415 */ 416union mcluster { 417 union mcluster *mcl_next; 418 char mcl_buf[MCLBYTES]; 419}; 420 421#define MCLALLOC(p, how) ((p) = m_mclalloc(how)) 422 423#define MCLFREE(p) m_mclfree(p) 424 425#define MCLGET(m, how) ((m) = m_mclget(m, how)) 426 427/* 428 * Mbuf big cluster 429 */ 430union mbigcluster { 431 union mbigcluster *mbc_next; 432 char mbc_buf[MBIGCLBYTES]; 433}; 434 435/* 436 * Mbuf jumbo cluster 437 */ 438union m16kcluster { 439 union m16kcluster *m16kcl_next; 440 char m16kcl_buf[M16KCLBYTES]; 441}; 442 443#define MCLHASREFERENCE(m) m_mclhasreference(m) 444 445/* 446 * MFREE(struct mbuf *m, struct mbuf *n) 447 * Free a single mbuf and associated external storage. 448 * Place the successor, if any, in n. 449 */ 450 451#define MFREE(m, n) ((n) = m_free(m)) 452 453/* 454 * Copy mbuf pkthdr from from to to. 455 * from must have M_PKTHDR set, and to must be empty. 456 * aux pointer will be moved to `to'. 457 */ 458#define M_COPY_PKTHDR(to, from) m_copy_pkthdr(to, from) 459 460#define M_COPY_PFTAG(to, from) m_copy_pftag(to, from) 461 462/* 463 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place 464 * an object of the specified size at the end of the mbuf, longword aligned. 465 */ 466#define M_ALIGN(m, len) \ 467do { \ 468 (m)->m_data += (MLEN - (len)) &~ (sizeof (long) - 1); \ 469} while (0) 470 471/* 472 * As above, for mbufs allocated with m_gethdr/MGETHDR 473 * or initialized by M_COPY_PKTHDR. 474 */ 475#define MH_ALIGN(m, len) \ 476do { \ 477 (m)->m_data += (MHLEN - (len)) &~ (sizeof (long) - 1); \ 478} while (0) 479 480/* 481 * Compute the amount of space available 482 * before the current start of data in an mbuf. 483 * Subroutine - data not available if certain references. 484 */ 485#define M_LEADINGSPACE(m) m_leadingspace(m) 486 487/* 488 * Compute the amount of space available 489 * after the end of data in an mbuf. 490 * Subroutine - data not available if certain references. 491 */ 492#define M_TRAILINGSPACE(m) m_trailingspace(m) 493 494/* 495 * Arrange to prepend space of size plen to mbuf m. 496 * If a new mbuf must be allocated, how specifies whether to wait. 497 * If how is M_DONTWAIT and allocation fails, the original mbuf chain 498 * is freed and m is set to NULL. 499 */ 500#define M_PREPEND(m, plen, how) ((m) = m_prepend_2((m), (plen), (how))) 501 502/* change mbuf to new type */ 503#define MCHTYPE(m, t) m_mchtype(m, t) 504 505/* compatiblity with 4.3 */ 506#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT) 507 508#define MBSHIFT 20 /* 1MB */ 509#define MBSIZE (1 << MBSHIFT) 510#define GBSHIFT 30 /* 1GB */ 511#define GBSIZE (1 << GBSHIFT) 512 513/* 514 * M_STRUCT_GET ensures that intermediate protocol header (from "off" to 515 * "off+len") is located in single mbuf, on contiguous memory region. 516 * The pointer to the region will be returned to pointer variable "val", 517 * with type "typ". 518 * 519 * M_STRUCT_GET0 does the same, except that it aligns the structure at 520 * very top of mbuf. GET0 is likely to make memory copy than GET. 521 */ 522#define M_STRUCT_GET(val, typ, m, off, len) \ 523do { \ 524 struct mbuf *t; \ 525 int tmp; \ 526 \ 527 if ((m)->m_len >= (off) + (len)) { \ 528 (val) = (typ)(mtod((m), caddr_t) + (off)); \ 529 } else { \ 530 t = m_pulldown((m), (off), (len), &tmp); \ 531 if (t != NULL) { \ 532 if (t->m_len < tmp + (len)) \ 533 panic("m_pulldown malfunction"); \ 534 (val) = (typ)(mtod(t, caddr_t) + tmp); \ 535 } else { \ 536 (val) = (typ)NULL; \ 537 (m) = NULL; \ 538 } \ 539 } \ 540} while (0) 541 542#define M_STRUCT_GET0(val, typ, m, off, len) \ 543do { \ 544 struct mbuf *t; \ 545 \ 546 if ((off) == 0 && ((m)->m_len >= (len))) { \ 547 (val) = (typ)(void *)mtod(m, caddr_t); \ 548 } else { \ 549 t = m_pulldown((m), (off), (len), NULL); \ 550 if (t != NULL) { \ 551 if (t->m_len < (len)) \ 552 panic("m_pulldown malfunction"); \ 553 (val) = (typ)(void *)mtod(t, caddr_t); \ 554 } else { \ 555 (val) = (typ)NULL; \ 556 (m) = NULL; \ 557 } \ 558 } \ 559} while (0) 560 561#define MBUF_INPUT_CHECK(m, rcvif) \ 562do { \ 563 if (!(m->m_flags & MBUF_PKTHDR) || \ 564 m->m_len < 0 || \ 565 m->m_len > ((njcl > 0) ? njclbytes : MBIGCLBYTES) || \ 566 m->m_type == MT_FREE || \ 567 ((m->m_flags & M_EXT) != 0 && m->m_ext.ext_buf == NULL)) { \ 568 panic_plain("Failed mbuf validity check: mbuf %p len %d " \ 569 "type %d flags 0x%x data %p rcvif %s%d ifflags 0x%x", \ 570 m, m->m_len, m->m_type, m->m_flags, \ 571 ((m->m_flags & M_EXT) ? m->m_ext.ext_buf : m->m_data), \ 572 rcvif->if_name, rcvif->if_unit, \ 573 (rcvif->if_flags & 0xffff)); \ 574 } \ 575} while (0) 576 577/* 578 * Simple mbuf queueing system 579 * 580 * This is basically a SIMPLEQ adapted to mbuf use (i.e. using 581 * m_nextpkt instead of field.sqe_next). 582 * 583 * m_next is ignored, so queueing chains of mbufs is possible 584 */ 585#define MBUFQ_HEAD(name) \ 586struct name { \ 587 struct mbuf *mq_first; /* first packet */ \ 588 struct mbuf **mq_last; /* addr of last next packet */ \ 589} 590 591#define MBUFQ_INIT(q) do { \ 592 MBUFQ_FIRST(q) = NULL; \ 593 (q)->mq_last = &MBUFQ_FIRST(q); \ 594} while (0) 595 596#define MBUFQ_PREPEND(q, m) do { \ 597 if ((MBUFQ_NEXT(m) = MBUFQ_FIRST(q)) == NULL) \ 598 (q)->mq_last = &MBUFQ_NEXT(m); \ 599 MBUFQ_FIRST(q) = (m); \ 600} while (0) 601 602#define MBUFQ_ENQUEUE(q, m) do { \ 603 MBUFQ_NEXT(m) = NULL; \ 604 *(q)->mq_last = (m); \ 605 (q)->mq_last = &MBUFQ_NEXT(m); \ 606} while (0) 607 608#define MBUFQ_ENQUEUE_MULTI(q, m, n) do { \ 609 MBUFQ_NEXT(n) = NULL; \ 610 *(q)->mq_last = (m); \ 611 (q)->mq_last = &MBUFQ_NEXT(n); \ 612} while (0) 613 614#define MBUFQ_DEQUEUE(q, m) do { \ 615 if (((m) = MBUFQ_FIRST(q)) != NULL) { \ 616 if ((MBUFQ_FIRST(q) = MBUFQ_NEXT(m)) == NULL) \ 617 (q)->mq_last = &MBUFQ_FIRST(q); \ 618 else \ 619 MBUFQ_NEXT(m) = NULL; \ 620 } \ 621} while (0) 622 623#define MBUFQ_REMOVE(q, m) do { \ 624 if (MBUFQ_FIRST(q) == (m)) { \ 625 MBUFQ_DEQUEUE(q, m); \ 626 } else { \ 627 struct mbuf *_m = MBUFQ_FIRST(q); \ 628 while (MBUFQ_NEXT(_m) != (m)) \ 629 _m = MBUFQ_NEXT(_m); \ 630 if ((MBUFQ_NEXT(_m) = \ 631 MBUFQ_NEXT(MBUFQ_NEXT(_m))) == NULL) \ 632 (q)->mq_last = &MBUFQ_NEXT(_m); \ 633 } \ 634} while (0) 635 636#define MBUFQ_DRAIN(q) do { \ 637 struct mbuf *__m0; \ 638 while ((__m0 = MBUFQ_FIRST(q)) != NULL) { \ 639 MBUFQ_FIRST(q) = MBUFQ_NEXT(__m0); \ 640 MBUFQ_NEXT(__m0) = NULL; \ 641 m_freem(__m0); \ 642 } \ 643 (q)->mq_last = &MBUFQ_FIRST(q); \ 644} while (0) 645 646#define MBUFQ_FOREACH(m, q) \ 647 for ((m) = MBUFQ_FIRST(q); \ 648 (m); \ 649 (m) = MBUFQ_NEXT(m)) 650 651#define MBUFQ_FOREACH_SAFE(m, q, tvar) \ 652 for ((m) = MBUFQ_FIRST(q); \ 653 (m) && ((tvar) = MBUFQ_NEXT(m), 1); \ 654 (m) = (tvar)) 655 656#define MBUFQ_EMPTY(q) ((q)->mq_first == NULL) 657#define MBUFQ_FIRST(q) ((q)->mq_first) 658#define MBUFQ_NEXT(m) ((m)->m_nextpkt) 659#define MBUFQ_LAST(q) (*(q)->mq_last) 660 661#define max_linkhdr P2ROUNDUP(_max_linkhdr, sizeof (u_int32_t)) 662#define max_protohdr P2ROUNDUP(_max_protohdr, sizeof (u_int32_t)) 663#endif /* XNU_KERNEL_PRIVATE */ 664 665/* 666 * Mbuf statistics (legacy). 667 */ 668struct mbstat { 669 u_int32_t m_mbufs; /* mbufs obtained from page pool */ 670 u_int32_t m_clusters; /* clusters obtained from page pool */ 671 u_int32_t m_spare; /* spare field */ 672 u_int32_t m_clfree; /* free clusters */ 673 u_int32_t m_drops; /* times failed to find space */ 674 u_int32_t m_wait; /* times waited for space */ 675 u_int32_t m_drain; /* times drained protocols for space */ 676 u_short m_mtypes[256]; /* type specific mbuf allocations */ 677 u_int32_t m_mcfail; /* times m_copym failed */ 678 u_int32_t m_mpfail; /* times m_pullup failed */ 679 u_int32_t m_msize; /* length of an mbuf */ 680 u_int32_t m_mclbytes; /* length of an mbuf cluster */ 681 u_int32_t m_minclsize; /* min length of data to allocate a cluster */ 682 u_int32_t m_mlen; /* length of data in an mbuf */ 683 u_int32_t m_mhlen; /* length of data in a header mbuf */ 684 u_int32_t m_bigclusters; /* clusters obtained from page pool */ 685 u_int32_t m_bigclfree; /* free clusters */ 686 u_int32_t m_bigmclbytes; /* length of an mbuf cluster */ 687}; 688 689/* Compatibillity with 10.3 */ 690struct ombstat { 691 u_int32_t m_mbufs; /* mbufs obtained from page pool */ 692 u_int32_t m_clusters; /* clusters obtained from page pool */ 693 u_int32_t m_spare; /* spare field */ 694 u_int32_t m_clfree; /* free clusters */ 695 u_int32_t m_drops; /* times failed to find space */ 696 u_int32_t m_wait; /* times waited for space */ 697 u_int32_t m_drain; /* times drained protocols for space */ 698 u_short m_mtypes[256]; /* type specific mbuf allocations */ 699 u_int32_t m_mcfail; /* times m_copym failed */ 700 u_int32_t m_mpfail; /* times m_pullup failed */ 701 u_int32_t m_msize; /* length of an mbuf */ 702 u_int32_t m_mclbytes; /* length of an mbuf cluster */ 703 u_int32_t m_minclsize; /* min length of data to allocate a cluster */ 704 u_int32_t m_mlen; /* length of data in an mbuf */ 705 u_int32_t m_mhlen; /* length of data in a header mbuf */ 706}; 707 708/* 709 * mbuf class statistics. 710 */ 711#define MAX_MBUF_CNAME 15 712 713#if defined(XNU_KERNEL_PRIVATE) 714/* For backwards compatibility with 32-bit userland process */ 715struct omb_class_stat { 716 char mbcl_cname[MAX_MBUF_CNAME + 1]; /* class name */ 717 u_int32_t mbcl_size; /* buffer size */ 718 u_int32_t mbcl_total; /* # of buffers created */ 719 u_int32_t mbcl_active; /* # of active buffers */ 720 u_int32_t mbcl_infree; /* # of available buffers */ 721 u_int32_t mbcl_slab_cnt; /* # of available slabs */ 722 u_int64_t mbcl_alloc_cnt; /* # of times alloc is called */ 723 u_int64_t mbcl_free_cnt; /* # of times free is called */ 724 u_int64_t mbcl_notified; /* # of notified wakeups */ 725 u_int64_t mbcl_purge_cnt; /* # of purges so far */ 726 u_int64_t mbcl_fail_cnt; /* # of allocation failures */ 727 u_int32_t mbcl_ctotal; /* total only for this class */ 728 /* 729 * Cache layer statistics 730 */ 731 u_int32_t mbcl_mc_state; /* cache state (see below) */ 732 u_int32_t mbcl_mc_cached; /* # of cached buffers */ 733 u_int32_t mbcl_mc_waiter_cnt; /* # waiters on the cache */ 734 u_int32_t mbcl_mc_wretry_cnt; /* # of wait retries */ 735 u_int32_t mbcl_mc_nwretry_cnt; /* # of no-wait retry attempts */ 736 u_int64_t mbcl_reserved[4]; /* for future use */ 737} __attribute__((__packed__)); 738#endif /* XNU_KERNEL_PRIVATE */ 739 740typedef struct mb_class_stat { 741 char mbcl_cname[MAX_MBUF_CNAME + 1]; /* class name */ 742 u_int32_t mbcl_size; /* buffer size */ 743 u_int32_t mbcl_total; /* # of buffers created */ 744 u_int32_t mbcl_active; /* # of active buffers */ 745 u_int32_t mbcl_infree; /* # of available buffers */ 746 u_int32_t mbcl_slab_cnt; /* # of available slabs */ 747#if defined(KERNEL) || defined(__LP64__) 748 u_int32_t mbcl_pad; /* padding */ 749#endif /* KERNEL || __LP64__ */ 750 u_int64_t mbcl_alloc_cnt; /* # of times alloc is called */ 751 u_int64_t mbcl_free_cnt; /* # of times free is called */ 752 u_int64_t mbcl_notified; /* # of notified wakeups */ 753 u_int64_t mbcl_purge_cnt; /* # of purges so far */ 754 u_int64_t mbcl_fail_cnt; /* # of allocation failures */ 755 u_int32_t mbcl_ctotal; /* total only for this class */ 756 /* 757 * Cache layer statistics 758 */ 759 u_int32_t mbcl_mc_state; /* cache state (see below) */ 760 u_int32_t mbcl_mc_cached; /* # of cached buffers */ 761 u_int32_t mbcl_mc_waiter_cnt; /* # waiters on the cache */ 762 u_int32_t mbcl_mc_wretry_cnt; /* # of wait retries */ 763 u_int32_t mbcl_mc_nwretry_cnt; /* # of no-wait retry attempts */ 764 u_int64_t mbcl_reserved[4]; /* for future use */ 765} mb_class_stat_t; 766 767#define MCS_DISABLED 0 /* cache is permanently disabled */ 768#define MCS_ONLINE 1 /* cache is online */ 769#define MCS_PURGING 2 /* cache is being purged */ 770#define MCS_OFFLINE 3 /* cache is offline (resizing) */ 771 772#if defined(XNU_KERNEL_PRIVATE) 773/* For backwards compatibility with 32-bit userland process */ 774struct omb_stat { 775 u_int32_t mbs_cnt; /* number of classes */ 776 struct omb_class_stat mbs_class[1]; /* class array */ 777} __attribute__((__packed__)); 778#endif /* XNU_KERNEL_PRIVATE */ 779 780typedef struct mb_stat { 781 u_int32_t mbs_cnt; /* number of classes */ 782#if defined(KERNEL) || defined(__LP64__) 783 u_int32_t mbs_pad; /* padding */ 784#endif /* KERNEL || __LP64__ */ 785 mb_class_stat_t mbs_class[1]; /* class array */ 786} mb_stat_t; 787 788#ifdef PRIVATE 789#define MLEAK_STACK_DEPTH 16 /* Max PC stack depth */ 790 791typedef struct mleak_trace_stat { 792 u_int64_t mltr_collisions; 793 u_int64_t mltr_hitcount; 794 u_int64_t mltr_allocs; 795 u_int64_t mltr_depth; 796 u_int64_t mltr_addr[MLEAK_STACK_DEPTH]; 797} mleak_trace_stat_t; 798 799typedef struct mleak_stat { 800 u_int32_t ml_isaddr64; /* 64-bit KVA? */ 801 u_int32_t ml_cnt; /* number of traces */ 802 mleak_trace_stat_t ml_trace[1]; /* trace array */ 803} mleak_stat_t; 804 805struct mleak_table { 806 u_int32_t mleak_capture; /* sampling capture counter */ 807 u_int32_t mleak_sample_factor; /* sample factor */ 808 809 /* Times two active records want to occupy the same spot */ 810 u_int64_t alloc_collisions; 811 u_int64_t trace_collisions; 812 813 /* Times new record lands on spot previously occupied by freed alloc */ 814 u_int64_t alloc_overwrites; 815 u_int64_t trace_overwrites; 816 817 /* Times a new alloc or trace is put into the hash table */ 818 u_int64_t alloc_recorded; 819 u_int64_t trace_recorded; 820 821 /* Total number of outstanding allocs */ 822 u_int64_t outstanding_allocs; 823 824 /* Times mleak_log returned false because couldn't acquire the lock */ 825 u_int64_t total_conflicts; 826}; 827#endif /* PRIVATE */ 828 829#ifdef KERNEL_PRIVATE 830__BEGIN_DECLS 831 832/* 833 * Exported (private) 834 */ 835 836extern struct mbstat mbstat; /* statistics */ 837 838__END_DECLS 839#endif /* KERNEL_PRIVATE */ 840 841#ifdef XNU_KERNEL_PRIVATE 842__BEGIN_DECLS 843 844/* 845 * Not exported (xnu private) 846 */ 847 848/* flags to m_get/MGET */ 849/* Need to include malloc.h to get right options for malloc */ 850#include <sys/malloc.h> 851 852struct mbuf; 853 854/* length to m_copy to copy all */ 855#define M_COPYALL 1000000000 856 857#define M_DONTWAIT M_NOWAIT 858#define M_WAIT M_WAITOK 859 860/* 861 * These macros are mapped to the appropriate KPIs, so that private code 862 * can be simply recompiled in order to be forward-compatible with future 863 * changes toward the struture sizes. 864 */ 865#define MLEN mbuf_get_mlen() /* normal data len */ 866#define MHLEN mbuf_get_mhlen() /* data len w/pkthdr */ 867 868#define MINCLSIZE mbuf_get_minclsize() /* cluster usage threshold */ 869 870extern void m_freem(struct mbuf *); 871extern char *mcl_to_paddr(char *); 872extern void m_adj(struct mbuf *, int); 873extern void m_cat(struct mbuf *, struct mbuf *); 874extern void m_copydata(struct mbuf *, int, int, void *); 875extern struct mbuf *m_copym(struct mbuf *, int, int, int); 876extern struct mbuf *m_get(int, int); 877extern struct mbuf *m_gethdr(int, int); 878extern struct mbuf *m_getpacket(void); 879extern struct mbuf *m_getpackets(int, int, int); 880extern struct mbuf *m_mclget(struct mbuf *, int); 881extern void *m_mtod(struct mbuf *); 882extern struct mbuf *m_prepend_2(struct mbuf *, int, int); 883extern struct mbuf *m_pullup(struct mbuf *, int); 884extern struct mbuf *m_split(struct mbuf *, int, int); 885extern void m_mclfree(caddr_t p); 886 887/* 888 * On platforms which require strict alignment (currently for anything but 889 * i386 or x86_64), this macro checks whether the data pointer of an mbuf 890 * is 32-bit aligned (this is the expected minimum alignment for protocol 891 * headers), and assert otherwise. 892 */ 893#if defined(__i386__) || defined(__x86_64__) 894#define MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(_m) 895#else /* !__i386__ && !__x86_64__ */ 896#define MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(_m) do { \ 897 if (!IS_P2ALIGNED((_m)->m_data, sizeof (u_int32_t))) { \ 898 if (((_m)->m_flags & M_PKTHDR) && \ 899 (_m)->m_pkthdr.rcvif != NULL) { \ 900 panic_plain("\n%s: mbuf %p data ptr %p is not " \ 901 "32-bit aligned [%s%d: alignerrs=%lld]\n", \ 902 __func__, (_m), (_m)->m_data, \ 903 (_m)->m_pkthdr.rcvif->if_name, \ 904 (_m)->m_pkthdr.rcvif->if_unit, \ 905 (_m)->m_pkthdr.rcvif->if_alignerrs); \ 906 } else { \ 907 panic_plain("\n%s: mbuf %p data ptr %p is not " \ 908 "32-bit aligned\n", \ 909 __func__, (_m), (_m)->m_data); \ 910 } \ 911 } \ 912} while (0) 913#endif /* !__i386__ && !__x86_64__ */ 914 915/* Maximum number of MBUF_SC values (excluding MBUF_SC_UNSPEC) */ 916#define MBUF_SC_MAX_CLASSES 10 917 918/* 919 * These conversion macros rely on the corresponding MBUF_SC and 920 * MBUF_TC values in order to establish the following mapping: 921 * 922 * MBUF_SC_BK_SYS ] ==> MBUF_TC_BK 923 * MBUF_SC_BK ] 924 * 925 * MBUF_SC_BE ] ==> MBUF_TC_BE 926 * MBUF_SC_RD ] 927 * MBUF_SC_OAM ] 928 * 929 * MBUF_SC_AV ] ==> MBUF_TC_VI 930 * MBUF_SC_RV ] 931 * MBUF_SC_VI ] 932 * 933 * MBUF_SC_VO ] ==> MBUF_TC_VO 934 * MBUF_SC_CTL ] 935 * 936 * The values assigned to each service class allows for a fast mapping to 937 * the corresponding MBUF_TC traffic class values, as well as to retrieve the 938 * assigned index; therefore care must be taken when comparing against these 939 * values. Use the corresponding class and index macros to retrieve the 940 * corresponding portion, and never assume that a higher class corresponds 941 * to a higher index. 942 */ 943#define MBUF_SCVAL(x) ((x) & 0xffff) 944#define MBUF_SCIDX(x) ((((x) >> 16) & 0xff) >> 3) 945#define MBUF_SC2TC(_sc) (MBUF_SCVAL(_sc) >> 7) 946#define MBUF_TC2SCVAL(_tc) ((_tc) << 7) 947#define IS_MBUF_SC_BACKGROUND(_sc) (((_sc) == MBUF_SC_BK_SYS) || \ 948 ((_sc) == MBUF_SC_BK)) 949 950#define SCIDX_BK_SYS MBUF_SCIDX(MBUF_SC_BK_SYS) 951#define SCIDX_BK MBUF_SCIDX(MBUF_SC_BK) 952#define SCIDX_BE MBUF_SCIDX(MBUF_SC_BE) 953#define SCIDX_RD MBUF_SCIDX(MBUF_SC_RD) 954#define SCIDX_OAM MBUF_SCIDX(MBUF_SC_OAM) 955#define SCIDX_AV MBUF_SCIDX(MBUF_SC_AV) 956#define SCIDX_RV MBUF_SCIDX(MBUF_SC_RV) 957#define SCIDX_VI MBUF_SCIDX(MBUF_SC_VI) 958#define SCIDX_VO MBUF_SCIDX(MBUF_SC_VO) 959#define SCIDX_CTL MBUF_SCIDX(MBUF_SC_CTL) 960 961#define SCVAL_BK_SYS MBUF_SCVAL(MBUF_SC_BK_SYS) 962#define SCVAL_BK MBUF_SCVAL(MBUF_SC_BK) 963#define SCVAL_BE MBUF_SCVAL(MBUF_SC_BE) 964#define SCVAL_RD MBUF_SCVAL(MBUF_SC_RD) 965#define SCVAL_OAM MBUF_SCVAL(MBUF_SC_OAM) 966#define SCVAL_AV MBUF_SCVAL(MBUF_SC_AV) 967#define SCVAL_RV MBUF_SCVAL(MBUF_SC_RV) 968#define SCVAL_VI MBUF_SCVAL(MBUF_SC_VI) 969#define SCVAL_VO MBUF_SCVAL(MBUF_SC_VO) 970#define SCVAL_CTL MBUF_SCVAL(MBUF_SC_CTL) 971 972#define MBUF_VALID_SC(c) \ 973 (c == MBUF_SC_BK_SYS || c == MBUF_SC_BK || c == MBUF_SC_BE || \ 974 c == MBUF_SC_RD || c == MBUF_SC_OAM || c == MBUF_SC_AV || \ 975 c == MBUF_SC_RV || c == MBUF_SC_VI || c == MBUF_SC_VO || \ 976 c == MBUF_SC_CTL) 977 978#define MBUF_VALID_SCIDX(c) \ 979 (c == SCIDX_BK_SYS || c == SCIDX_BK || c == SCIDX_BE || \ 980 c == SCIDX_RD || c == SCIDX_OAM || c == SCIDX_AV || \ 981 c == SCIDX_RV || c == SCIDX_VI || c == SCIDX_VO || \ 982 c == SCIDX_CTL) 983 984#define MBUF_VALID_SCVAL(c) \ 985 (c == SCVAL_BK_SYS || c == SCVAL_BK || c == SCVAL_BE || \ 986 c == SCVAL_RD || c == SCVAL_OAM || c == SCVAL_AV || \ 987 c == SCVAL_RV || c == SCVAL_VI || c == SCVAL_VO || \ 988 c == SCVAL_CTL) 989 990__private_extern__ union mbigcluster *mbutl; /* start VA of mbuf pool */ 991__private_extern__ union mbigcluster *embutl; /* end VA of mbuf pool */ 992__private_extern__ unsigned int nmbclusters; /* number of mapped clusters */ 993__private_extern__ int njcl; /* # of jumbo clusters */ 994__private_extern__ int njclbytes; /* size of a jumbo cluster */ 995__private_extern__ int max_hdr; /* largest link+protocol header */ 996__private_extern__ int max_datalen; /* MHLEN - max_hdr */ 997 998/* Use max_linkhdr instead of _max_linkhdr */ 999__private_extern__ int _max_linkhdr; /* largest link-level header */ 1000 1001/* Use max_protohdr instead of _max_protohdr */ 1002__private_extern__ int _max_protohdr; /* largest protocol header */ 1003 1004__private_extern__ unsigned int mbuf_default_ncl(int, u_int64_t); 1005__private_extern__ void mbinit(void); 1006__private_extern__ struct mbuf *m_clattach(struct mbuf *, int, caddr_t, 1007 void (*)(caddr_t, u_int, caddr_t), u_int, caddr_t, int); 1008__private_extern__ caddr_t m_bigalloc(int); 1009__private_extern__ void m_bigfree(caddr_t, u_int, caddr_t); 1010__private_extern__ struct mbuf *m_mbigget(struct mbuf *, int); 1011__private_extern__ caddr_t m_16kalloc(int); 1012__private_extern__ void m_16kfree(caddr_t, u_int, caddr_t); 1013__private_extern__ struct mbuf *m_m16kget(struct mbuf *, int); 1014 1015__private_extern__ struct mbuf *m_free(struct mbuf *); 1016__private_extern__ struct mbuf *m_getclr(int, int); 1017__private_extern__ struct mbuf *m_getptr(struct mbuf *, int, int *); 1018__private_extern__ unsigned int m_length(struct mbuf *); 1019__private_extern__ unsigned int m_length2(struct mbuf *, struct mbuf **); 1020__private_extern__ unsigned int m_fixhdr(struct mbuf *); 1021__private_extern__ struct mbuf *m_defrag(struct mbuf *, int); 1022__private_extern__ struct mbuf *m_defrag_offset(struct mbuf *, u_int32_t, int); 1023__private_extern__ struct mbuf *m_prepend(struct mbuf *, int, int); 1024__private_extern__ struct mbuf *m_copyup(struct mbuf *, int, int); 1025__private_extern__ struct mbuf *m_retry(int, int); 1026__private_extern__ struct mbuf *m_retryhdr(int, int); 1027__private_extern__ int m_freem_list(struct mbuf *); 1028__private_extern__ int m_append(struct mbuf *, int, caddr_t); 1029__private_extern__ struct mbuf *m_last(struct mbuf *); 1030__private_extern__ struct mbuf *m_devget(char *, int, int, struct ifnet *, 1031 void (*)(const void *, void *, size_t)); 1032__private_extern__ struct mbuf *m_pulldown(struct mbuf *, int, int, int *); 1033 1034__private_extern__ struct mbuf *m_getcl(int, int, int); 1035__private_extern__ caddr_t m_mclalloc(int); 1036__private_extern__ int m_mclhasreference(struct mbuf *); 1037__private_extern__ void m_copy_pkthdr(struct mbuf *, struct mbuf *); 1038__private_extern__ void m_copy_pftag(struct mbuf *, struct mbuf *); 1039 1040__private_extern__ struct mbuf *m_dtom(void *); 1041__private_extern__ int m_mtocl(void *); 1042__private_extern__ union mcluster *m_cltom(int); 1043 1044__private_extern__ int m_trailingspace(struct mbuf *); 1045__private_extern__ int m_leadingspace(struct mbuf *); 1046 1047__private_extern__ struct mbuf *m_normalize(struct mbuf *m); 1048__private_extern__ void m_mchtype(struct mbuf *m, int t); 1049__private_extern__ void m_mcheck(struct mbuf *); 1050 1051__private_extern__ void m_copyback(struct mbuf *, int, int, const void *); 1052__private_extern__ struct mbuf *m_copyback_cow(struct mbuf *, int, int, 1053 const void *, int); 1054__private_extern__ int m_makewritable(struct mbuf **, int, int, int); 1055__private_extern__ struct mbuf *m_dup(struct mbuf *m, int how); 1056__private_extern__ struct mbuf *m_copym_with_hdrs(struct mbuf *, int, int, int, 1057 struct mbuf **, int *); 1058__private_extern__ struct mbuf *m_getpackethdrs(int, int); 1059__private_extern__ struct mbuf *m_getpacket_how(int); 1060__private_extern__ struct mbuf *m_getpackets_internal(unsigned int *, int, 1061 int, int, size_t); 1062__private_extern__ struct mbuf *m_allocpacket_internal(unsigned int *, size_t, 1063 unsigned int *, int, int, size_t); 1064 1065/* 1066 * Packets may have annotations attached by affixing a list of "packet 1067 * tags" to the pkthdr structure. Packet tags are dynamically allocated 1068 * semi-opaque data structures that have a fixed header (struct m_tag) 1069 * that specifies the size of the memory block and an <id,type> pair that 1070 * identifies it. The id identifies the module and the type identifies the 1071 * type of data for that module. The id of zero is reserved for the kernel. 1072 * 1073 * Note that the packet tag returned by m_tag_allocate has the default 1074 * memory alignment implemented by malloc. To reference private data one 1075 * can use a construct like: 1076 * 1077 * struct m_tag *mtag = m_tag_allocate(...); 1078 * struct foo *p = (struct foo *)(mtag+1); 1079 * 1080 * if the alignment of struct m_tag is sufficient for referencing members 1081 * of struct foo. Otherwise it is necessary to embed struct m_tag within 1082 * the private data structure to insure proper alignment; e.g. 1083 * 1084 * struct foo { 1085 * struct m_tag tag; 1086 * ... 1087 * }; 1088 * struct foo *p = (struct foo *) m_tag_allocate(...); 1089 * struct m_tag *mtag = &p->tag; 1090 */ 1091 1092#define KERNEL_MODULE_TAG_ID 0 1093 1094enum { 1095 KERNEL_TAG_TYPE_NONE = 0, 1096 KERNEL_TAG_TYPE_DUMMYNET = 1, 1097 KERNEL_TAG_TYPE_DIVERT = 2, 1098 KERNEL_TAG_TYPE_IPFORWARD = 3, 1099 KERNEL_TAG_TYPE_IPFILT = 4, 1100 KERNEL_TAG_TYPE_MACLABEL = 5, 1101 KERNEL_TAG_TYPE_MAC_POLICY_LABEL = 6, 1102 KERNEL_TAG_TYPE_ENCAP = 8, 1103 KERNEL_TAG_TYPE_INET6 = 9, 1104 KERNEL_TAG_TYPE_IPSEC = 10, 1105 KERNEL_TAG_TYPE_PF = 11 1106}; 1107 1108/* Packet tag routines */ 1109__private_extern__ struct m_tag *m_tag_alloc(u_int32_t, u_int16_t, int, int); 1110__private_extern__ struct m_tag *m_tag_create(u_int32_t, u_int16_t, int, int, 1111 struct mbuf *); 1112__private_extern__ void m_tag_free(struct m_tag *); 1113__private_extern__ void m_tag_prepend(struct mbuf *, struct m_tag *); 1114__private_extern__ void m_tag_unlink(struct mbuf *, struct m_tag *); 1115__private_extern__ void m_tag_delete(struct mbuf *, struct m_tag *); 1116__private_extern__ void m_tag_delete_chain(struct mbuf *, struct m_tag *); 1117__private_extern__ struct m_tag *m_tag_locate(struct mbuf *, u_int32_t, 1118 u_int16_t, struct m_tag *); 1119__private_extern__ struct m_tag *m_tag_copy(struct m_tag *, int); 1120__private_extern__ int m_tag_copy_chain(struct mbuf *, struct mbuf *, int); 1121__private_extern__ void m_tag_init(struct mbuf *); 1122__private_extern__ struct m_tag *m_tag_first(struct mbuf *); 1123__private_extern__ struct m_tag *m_tag_next(struct mbuf *, struct m_tag *); 1124 1125__END_DECLS 1126#endif /* XNU_KERNEL_PRIVATE */ 1127#ifdef KERNEL 1128#include <sys/kpi_mbuf.h> 1129#ifdef XNU_KERNEL_PRIVATE 1130__BEGIN_DECLS 1131 1132__private_extern__ void m_service_class_init(struct mbuf *); 1133__private_extern__ int m_set_service_class(struct mbuf *, mbuf_svc_class_t); 1134__private_extern__ mbuf_svc_class_t m_get_service_class(struct mbuf *); 1135__private_extern__ mbuf_svc_class_t m_service_class_from_idx(u_int32_t); 1136__private_extern__ mbuf_svc_class_t m_service_class_from_val(u_int32_t); 1137__private_extern__ int m_set_traffic_class(struct mbuf *, mbuf_traffic_class_t); 1138__private_extern__ mbuf_traffic_class_t m_get_traffic_class(struct mbuf *); 1139 1140__END_DECLS 1141#endif /* XNU_KERNEL_PRIVATE */ 1142#endif /* KERNEL */ 1143#endif /* !_SYS_MBUF_H_ */ 1144