1 /* $NetBSD: mbuf.h,v 1.68 2002/12/01 22:57:17 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1996 Matt Thomas. All rights reserved. 42 * Copyright (c) 1982, 1986, 1988, 1993 43 * The Regents of the University of California. All rights reserved. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by the University of 56 * California, Berkeley and its contributors. 57 * 4. Neither the name of the University nor the names of its contributors 58 * may be used to endorse or promote products derived from this software 59 * without specific prior written permission. 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 * SUCH DAMAGE. 72 * 73 * @(#)mbuf.h 8.5 (Berkeley) 2/19/95 74 */ 75 76 #ifndef _SYS_MBUF_H_ 77 #define _SYS_MBUF_H_ 78 79 #ifndef M_WAITOK 80 #include <sys/malloc.h> 81 #endif 82 #include <sys/pool.h> 83 84 /* 85 * Mbufs are of a single size, MSIZE (machine/param.h), which 86 * includes overhead. An mbuf may add a single "mbuf cluster" of size 87 * MCLBYTES (also in machine/param.h), which has no additional overhead 88 * and is used instead of the internal data area; this is done when 89 * at least MINCLSIZE of data must be stored. 90 */ 91 92 #define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */ 93 #define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */ 94 95 #define MINCLSIZE (MHLEN+MLEN+1) /* smallest amount to put in cluster */ 96 #define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */ 97 98 /* 99 * Macros for type conversion 100 * mtod(m,t) - convert mbuf pointer to data pointer of correct type 101 */ 102 #define mtod(m,t) ((t)((m)->m_data)) 103 104 /* header at beginning of each mbuf: */ 105 struct m_hdr { 106 struct mbuf *mh_next; /* next buffer in chain */ 107 struct mbuf *mh_nextpkt; /* next chain in queue/record */ 108 caddr_t mh_data; /* location of data */ 109 int mh_len; /* amount of data in this mbuf */ 110 short mh_type; /* type of data in this mbuf */ 111 short mh_flags; /* flags; see below */ 112 }; 113 114 /* 115 * record/packet header in first mbuf of chain; valid if M_PKTHDR set 116 * 117 * A note about csum_data: For the out-bound direction, this indicates the 118 * offset after the L4 header where the final L4 checksum value is to be 119 * stored. For the in-bound direction, it is only valid if the M_CSUM_DATA 120 * flag is set. In this case, an L4 checksum has been calculated by 121 * hardware, but it is up to software to perform final verification. 122 * 123 * Note for in-bound TCP/UDP checksums, we expect the csum_data to NOT 124 * be bit-wise inverted (the final step in the calculation of an IP 125 * checksum) -- this is so we can accumulate the checksum for fragmented 126 * packets during reassembly. 127 */ 128 struct pkthdr { 129 struct ifnet *rcvif; /* rcv interface */ 130 int len; /* total packet length */ 131 int csum_flags; /* checksum flags */ 132 u_int32_t csum_data; /* checksum data */ 133 struct mbuf *aux; /* extra data buffer; ipsec/others */ 134 }; 135 136 /* 137 * Note: These bits are carefully arrange so that the compiler can have 138 * a prayer of generating a jump table. 139 */ 140 #define M_CSUM_TCPv4 0x00000001 /* TCP header/payload */ 141 #define M_CSUM_UDPv4 0x00000002 /* UDP header/payload */ 142 #define M_CSUM_TCP_UDP_BAD 0x00000004 /* TCP/UDP checksum bad */ 143 #define M_CSUM_DATA 0x00000008 /* consult csum_data */ 144 #define M_CSUM_TCPv6 0x00000010 /* IPv6 TCP header/payload */ 145 #define M_CSUM_UDPv6 0x00000020 /* IPv6 UDP header/payload */ 146 #define M_CSUM_IPv4 0x00000040 /* IPv4 header */ 147 #define M_CSUM_IPv4_BAD 0x00000080 /* IPv4 header checksum bad */ 148 149 /* description of external storage mapped into mbuf, valid if M_EXT set */ 150 struct m_ext { 151 caddr_t ext_buf; /* start of buffer */ 152 void (*ext_free) /* free routine if not the usual */ 153 __P((struct mbuf *, caddr_t, u_int, void *)); 154 void *ext_arg; /* argument for ext_free */ 155 u_int ext_size; /* size of buffer, for ext_free */ 156 int ext_type; /* malloc type */ 157 struct mbuf *ext_nextref; 158 struct mbuf *ext_prevref; 159 #ifdef DEBUG 160 const char *ext_ofile; 161 const char *ext_nfile; 162 int ext_oline; 163 int ext_nline; 164 #endif 165 }; 166 167 struct mbuf { 168 struct m_hdr m_hdr; 169 union { 170 struct { 171 struct pkthdr MH_pkthdr; /* M_PKTHDR set */ 172 union { 173 struct m_ext MH_ext; /* M_EXT set */ 174 char MH_databuf[MHLEN]; 175 } MH_dat; 176 } MH; 177 char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */ 178 } M_dat; 179 }; 180 #define m_next m_hdr.mh_next 181 #define m_len m_hdr.mh_len 182 #define m_data m_hdr.mh_data 183 #define m_type m_hdr.mh_type 184 #define m_flags m_hdr.mh_flags 185 #define m_nextpkt m_hdr.mh_nextpkt 186 #define m_pkthdr M_dat.MH.MH_pkthdr 187 #define m_ext M_dat.MH.MH_dat.MH_ext 188 #define m_pktdat M_dat.MH.MH_dat.MH_databuf 189 #define m_dat M_dat.M_databuf 190 191 /* mbuf flags */ 192 #define M_EXT 0x0001 /* has associated external storage */ 193 #define M_PKTHDR 0x0002 /* start of record */ 194 #define M_EOR 0x0004 /* end of record */ 195 #define M_CLUSTER 0x0008 /* external storage is a cluster */ 196 197 /* mbuf pkthdr flags, also in m_flags */ 198 #define M_BCAST 0x0100 /* send/received as link-level broadcast */ 199 #define M_MCAST 0x0200 /* send/received as link-level multicast */ 200 #define M_CANFASTFWD 0x0400 /* used by filters to indicate packet can 201 be fast-forwarded */ 202 #define M_ANYCAST6 0x0800 /* received as IPv6 anycast */ 203 #define M_LINK0 0x1000 /* link layer specific flag */ 204 #define M_LINK1 0x2000 /* link layer specific flag */ 205 #define M_LINK2 0x4000 /* link layer specific flag */ 206 #define M_AUTHIPHDR 0x0010 /* data origin authentication for IP header */ 207 #define M_DECRYPTED 0x0020 /* confidentiality */ 208 #define M_LOOP 0x0040 /* for Mbuf statistics */ 209 #define M_AUTHIPDGM 0x0080 /* data origin authentication */ 210 211 /* flags copied when copying m_pkthdr */ 212 #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_ANYCAST6|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM) 213 214 /* mbuf types */ 215 #define MT_FREE 0 /* should be on free list */ 216 #define MT_DATA 1 /* dynamic (data) allocation */ 217 #define MT_HEADER 2 /* packet header */ 218 #define MT_SONAME 3 /* socket name */ 219 #define MT_SOOPTS 4 /* socket options */ 220 #define MT_FTABLE 5 /* fragment reassembly header */ 221 #define MT_CONTROL 6 /* extra-data protocol message */ 222 #define MT_OOBDATA 7 /* expedited data */ 223 224 /* flags to m_get/MGET */ 225 #define M_DONTWAIT M_NOWAIT 226 #define M_WAIT M_WAITOK 227 228 /* 229 * mbuf utility macros: 230 * 231 * MBUFLOCK(code) 232 * prevents a section of code from from being interrupted by network 233 * drivers. 234 */ 235 #define MBUFLOCK(code) \ 236 do { \ 237 int ms = splvm(); \ 238 { code } \ 239 splx(ms); \ 240 } while (/* CONSTCOND */ 0) 241 242 /* 243 * mbuf allocation/deallocation macros: 244 * 245 * MGET(struct mbuf *m, int how, int type) 246 * allocates an mbuf and initializes it to contain internal data. 247 * 248 * MGETHDR(struct mbuf *m, int how, int type) 249 * allocates an mbuf and initializes it to contain a packet header 250 * and internal data. 251 * 252 * If 'how' is M_WAIT, these macros (and the corresponding functions) 253 * are guaranteed to return successfully. 254 */ 255 #define MGET(m, how, type) \ 256 do { \ 257 MBUFLOCK((m) = pool_cache_get(&mbpool_cache, \ 258 (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0);); \ 259 if (m) { \ 260 MBUFLOCK(mbstat.m_mtypes[type]++;); \ 261 (m)->m_type = (type); \ 262 (m)->m_next = (struct mbuf *)NULL; \ 263 (m)->m_nextpkt = (struct mbuf *)NULL; \ 264 (m)->m_data = (m)->m_dat; \ 265 (m)->m_flags = 0; \ 266 } \ 267 } while (/* CONSTCOND */ 0) 268 269 #define MGETHDR(m, how, type) \ 270 do { \ 271 MBUFLOCK((m) = pool_cache_get(&mbpool_cache, \ 272 (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0);); \ 273 if (m) { \ 274 MBUFLOCK(mbstat.m_mtypes[type]++;); \ 275 (m)->m_type = (type); \ 276 (m)->m_next = (struct mbuf *)NULL; \ 277 (m)->m_nextpkt = (struct mbuf *)NULL; \ 278 (m)->m_data = (m)->m_pktdat; \ 279 (m)->m_flags = M_PKTHDR; \ 280 (m)->m_pkthdr.csum_flags = 0; \ 281 (m)->m_pkthdr.csum_data = 0; \ 282 (m)->m_pkthdr.aux = (struct mbuf *)NULL; \ 283 } \ 284 } while (/* CONSTCOND */ 0) 285 286 /* 287 * Macros for tracking external storage associated with an mbuf. 288 * 289 * Note: add and delete reference must be called at splvm(). 290 */ 291 #ifdef DEBUG 292 #define MCLREFDEBUGN(m, file, line) \ 293 do { \ 294 (m)->m_ext.ext_nfile = (file); \ 295 (m)->m_ext.ext_nline = (line); \ 296 } while (/* CONSTCOND */ 0) 297 298 #define MCLREFDEBUGO(m, file, line) \ 299 do { \ 300 (m)->m_ext.ext_ofile = (file); \ 301 (m)->m_ext.ext_oline = (line); \ 302 } while (/* CONSTCOND */ 0) 303 #else 304 #define MCLREFDEBUGN(m, file, line) 305 #define MCLREFDEBUGO(m, file, line) 306 #endif 307 308 #define MCLBUFREF(p) 309 #define MCLISREFERENCED(m) ((m)->m_ext.ext_nextref != (m)) 310 #define _MCLDEREFERENCE(m) \ 311 do { \ 312 (m)->m_ext.ext_nextref->m_ext.ext_prevref = \ 313 (m)->m_ext.ext_prevref; \ 314 (m)->m_ext.ext_prevref->m_ext.ext_nextref = \ 315 (m)->m_ext.ext_nextref; \ 316 } while (/* CONSTCOND */ 0) 317 318 #define _MCLADDREFERENCE(o, n) \ 319 do { \ 320 (n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER)); \ 321 (n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref; \ 322 (n)->m_ext.ext_prevref = (o); \ 323 (o)->m_ext.ext_nextref = (n); \ 324 (n)->m_ext.ext_nextref->m_ext.ext_prevref = (n); \ 325 MCLREFDEBUGN((n), __FILE__, __LINE__); \ 326 } while (/* CONSTCOND */ 0) 327 328 #define MCLINITREFERENCE(m) \ 329 do { \ 330 (m)->m_ext.ext_prevref = (m); \ 331 (m)->m_ext.ext_nextref = (m); \ 332 MCLREFDEBUGO((m), __FILE__, __LINE__); \ 333 MCLREFDEBUGN((m), NULL, 0); \ 334 } while (/* CONSTCOND */ 0) 335 336 #define MCLADDREFERENCE(o, n) MBUFLOCK(_MCLADDREFERENCE((o), (n));) 337 338 /* 339 * Macros for mbuf external storage. 340 * 341 * MCLGET allocates and adds an mbuf cluster to a normal mbuf; 342 * the flag M_EXT is set upon success. 343 * 344 * MEXTMALLOC allocates external storage and adds it to 345 * a normal mbuf; the flag M_EXT is set upon success. 346 * 347 * MEXTADD adds pre-allocated external storage to 348 * a normal mbuf; the flag M_EXT is set upon success. 349 */ 350 #define MCLGET(m, how) \ 351 do { \ 352 MBUFLOCK( \ 353 (m)->m_ext.ext_buf = \ 354 pool_cache_get(&mclpool_cache, (how) == M_WAIT ? \ 355 (PR_WAITOK|PR_LIMITFAIL) : 0); \ 356 ); \ 357 if ((m)->m_ext.ext_buf != NULL) { \ 358 (m)->m_data = (m)->m_ext.ext_buf; \ 359 (m)->m_flags |= M_EXT|M_CLUSTER; \ 360 (m)->m_ext.ext_size = MCLBYTES; \ 361 (m)->m_ext.ext_free = NULL; \ 362 (m)->m_ext.ext_arg = NULL; \ 363 MCLINITREFERENCE(m); \ 364 } \ 365 } while (/* CONSTCOND */ 0) 366 367 #define MEXTMALLOC(m, size, how) \ 368 do { \ 369 (m)->m_ext.ext_buf = \ 370 (caddr_t)malloc((size), mbtypes[(m)->m_type], (how)); \ 371 if ((m)->m_ext.ext_buf != NULL) { \ 372 (m)->m_data = (m)->m_ext.ext_buf; \ 373 (m)->m_flags |= M_EXT; \ 374 (m)->m_flags &= ~M_CLUSTER; \ 375 (m)->m_ext.ext_size = (size); \ 376 (m)->m_ext.ext_free = NULL; \ 377 (m)->m_ext.ext_arg = NULL; \ 378 (m)->m_ext.ext_type = mbtypes[(m)->m_type]; \ 379 MCLINITREFERENCE(m); \ 380 } \ 381 } while (/* CONSTCOND */ 0) 382 383 #define MEXTADD(m, buf, size, type, free, arg) \ 384 do { \ 385 (m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf); \ 386 (m)->m_flags |= M_EXT; \ 387 (m)->m_flags &= ~M_CLUSTER; \ 388 (m)->m_ext.ext_size = (size); \ 389 (m)->m_ext.ext_free = (free); \ 390 (m)->m_ext.ext_arg = (arg); \ 391 (m)->m_ext.ext_type = (type); \ 392 MCLINITREFERENCE(m); \ 393 } while (/* CONSTCOND */ 0) 394 395 #define MEXTREMOVE(m) \ 396 do { \ 397 int _ms_ = splvm(); /* MBUFLOCK */ \ 398 if (MCLISREFERENCED(m)) { \ 399 _MCLDEREFERENCE(m); \ 400 splx(_ms_); \ 401 } else if ((m)->m_flags & M_CLUSTER) { \ 402 pool_cache_put(&mclpool_cache, (m)->m_ext.ext_buf); \ 403 splx(_ms_); \ 404 } else if ((m)->m_ext.ext_free) { \ 405 /* \ 406 * NOTE: We assume that MEXTREMOVE() is called from \ 407 * code where it is safe to invoke the free routine \ 408 * without the mbuf to perform bookkeeping. \ 409 */ \ 410 splx(_ms_); \ 411 (*((m)->m_ext.ext_free))(NULL, (m)->m_ext.ext_buf, \ 412 (m)->m_ext.ext_size, (m)->m_ext.ext_arg); \ 413 } else { \ 414 splx(_ms_); \ 415 free((m)->m_ext.ext_buf, (m)->m_ext.ext_type); \ 416 } \ 417 (m)->m_flags &= ~(M_CLUSTER|M_EXT); \ 418 (m)->m_ext.ext_size = 0; /* why ??? */ \ 419 } while (/* CONSTCOND */ 0) 420 421 /* 422 * Reset the data pointer on an mbuf. 423 */ 424 #define MRESETDATA(m) \ 425 do { \ 426 if ((m)->m_flags & M_EXT) \ 427 (m)->m_data = (m)->m_ext.ext_buf; \ 428 else if ((m)->m_flags & M_PKTHDR) \ 429 (m)->m_data = (m)->m_pktdat; \ 430 else \ 431 (m)->m_data = (m)->m_dat; \ 432 } while (/* CONSTCOND */ 0) 433 434 /* 435 * MFREE(struct mbuf *m, struct mbuf *n) 436 * Free a single mbuf and associated external storage. 437 * Place the successor, if any, in n. 438 * 439 * we do need to check non-first mbuf for m_aux, since some of existing 440 * code does not call M_PREPEND properly. 441 * (example: call to bpf_mtap from drivers) 442 */ 443 #define MFREE(m, n) \ 444 MBUFLOCK( \ 445 mbstat.m_mtypes[(m)->m_type]--; \ 446 if (((m)->m_flags & M_PKTHDR) != 0 && \ 447 (m)->m_pkthdr.aux != NULL) { \ 448 m_freem((m)->m_pkthdr.aux); \ 449 (m)->m_pkthdr.aux = NULL; \ 450 } \ 451 (n) = (m)->m_next; \ 452 if ((m)->m_flags & M_EXT) { \ 453 if (MCLISREFERENCED(m)) { \ 454 _MCLDEREFERENCE(m); \ 455 pool_cache_put(&mbpool_cache, (m)); \ 456 } else if ((m)->m_flags & M_CLUSTER) { \ 457 pool_cache_put(&mclpool_cache, \ 458 (m)->m_ext.ext_buf); \ 459 pool_cache_put(&mbpool_cache, (m)); \ 460 } else if ((m)->m_ext.ext_free) { \ 461 /* \ 462 * (*ext_free)() is responsible for \ 463 * freeing the mbuf when it is safe. \ 464 */ \ 465 (*((m)->m_ext.ext_free))((m), \ 466 (m)->m_ext.ext_buf, \ 467 (m)->m_ext.ext_size, \ 468 (m)->m_ext.ext_arg); \ 469 } else { \ 470 free((m)->m_ext.ext_buf, \ 471 (m)->m_ext.ext_type); \ 472 pool_cache_put(&mbpool_cache, (m)); \ 473 } \ 474 } else \ 475 pool_cache_put(&mbpool_cache, (m)); \ 476 ) 477 478 /* 479 * Copy mbuf pkthdr from `from' to `to'. 480 * `from' must have M_PKTHDR set, and `to' must be empty. 481 * aux pointer will be moved to `to'. 482 */ 483 #define M_COPY_PKTHDR(to, from) \ 484 do { \ 485 (to)->m_pkthdr = (from)->m_pkthdr; \ 486 (from)->m_pkthdr.aux = (struct mbuf *)NULL; \ 487 (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \ 488 (to)->m_data = (to)->m_pktdat; \ 489 } while (/* CONSTCOND */ 0) 490 491 /* 492 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place 493 * an object of the specified size at the end of the mbuf, longword aligned. 494 */ 495 #define M_ALIGN(m, len) \ 496 do { \ 497 (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); \ 498 } while (/* CONSTCOND */ 0) 499 500 /* 501 * As above, for mbufs allocated with m_gethdr/MGETHDR 502 * or initialized by M_COPY_PKTHDR. 503 */ 504 #define MH_ALIGN(m, len) \ 505 do { \ 506 (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); \ 507 } while (/* CONSTCOND */ 0) 508 509 /* 510 * Determine if an mbuf's data area is read-only. This is true 511 * for non-cluster external storage and for clusters that are 512 * being referenced by more than one mbuf. 513 */ 514 #define M_READONLY(m) \ 515 (((m)->m_flags & M_EXT) != 0 && \ 516 (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m))) 517 518 /* 519 * Compute the amount of space available 520 * before the current start of data in an mbuf. 521 */ 522 #define _M_LEADINGSPACE(m) \ 523 ((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf : \ 524 (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ 525 (m)->m_data - (m)->m_dat) 526 527 #define M_LEADINGSPACE(m) \ 528 (M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m))) 529 530 /* 531 * Compute the amount of space available 532 * after the end of data in an mbuf. 533 */ 534 #define _M_TRAILINGSPACE(m) \ 535 ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \ 536 ((m)->m_data + (m)->m_len) : \ 537 &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len)) 538 539 #define M_TRAILINGSPACE(m) \ 540 (M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m))) 541 542 /* 543 * Arrange to prepend space of size plen to mbuf m. 544 * If a new mbuf must be allocated, how specifies whether to wait. 545 * If how is M_DONTWAIT and allocation fails, the original mbuf chain 546 * is freed and m is set to NULL. 547 */ 548 #define M_PREPEND(m, plen, how) \ 549 do { \ 550 if (M_LEADINGSPACE(m) >= (plen)) { \ 551 (m)->m_data -= (plen); \ 552 (m)->m_len += (plen); \ 553 } else \ 554 (m) = m_prepend((m), (plen), (how)); \ 555 if ((m) && (m)->m_flags & M_PKTHDR) \ 556 (m)->m_pkthdr.len += (plen); \ 557 } while (/* CONSTCOND */ 0) 558 559 /* change mbuf to new type */ 560 #define MCHTYPE(m, t) \ 561 do { \ 562 MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \ 563 (m)->m_type = t; \ 564 } while (/* CONSTCOND */ 0) 565 566 /* length to m_copy to copy all */ 567 #define M_COPYALL 1000000000 568 569 /* compatibility with 4.3 */ 570 #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT) 571 572 /* 573 * Allow drivers and/or protocols to use the rcvif member of 574 * PKTHDR mbufs to store private context information. 575 */ 576 #define M_GETCTX(m, t) ((t) (m)->m_pkthdr.rcvif + 0) 577 #define M_SETCTX(m, c) ((void) ((m)->m_pkthdr.rcvif = (void *) (c))) 578 579 /* 580 * pkthdr.aux type tags. 581 */ 582 struct mauxtag { 583 int af; 584 int type; 585 }; 586 587 /* 588 * Mbuf statistics. 589 * For statistics related to mbuf and cluster allocations, see also the 590 * pool headers (mbpool and mclpool). 591 */ 592 struct mbstat { 593 u_long _m_spare; /* formerly m_mbufs */ 594 u_long _m_spare1; /* formerly m_clusters */ 595 u_long _m_spare2; /* spare field */ 596 u_long _m_spare3; /* formely m_clfree - free clusters */ 597 u_long m_drops; /* times failed to find space */ 598 u_long m_wait; /* times waited for space */ 599 u_long m_drain; /* times drained protocols for space */ 600 u_short m_mtypes[256]; /* type specific mbuf allocations */ 601 }; 602 603 /* 604 * Mbuf sysctl variables. 605 */ 606 #define MBUF_MSIZE 1 /* int: mbuf base size */ 607 #define MBUF_MCLBYTES 2 /* int: mbuf cluster size */ 608 #define MBUF_NMBCLUSTERS 3 /* int: limit on the # of clusters */ 609 #define MBUF_MBLOWAT 4 /* int: mbuf low water mark */ 610 #define MBUF_MCLLOWAT 5 /* int: mbuf cluster low water mark */ 611 #define MBUF_MAXID 6 /* number of valid MBUF ids */ 612 613 #define CTL_MBUF_NAMES { \ 614 { 0, 0 }, \ 615 { "msize", CTLTYPE_INT }, \ 616 { "mclbytes", CTLTYPE_INT }, \ 617 { "nmbclusters", CTLTYPE_INT }, \ 618 { "mblowat", CTLTYPE_INT }, \ 619 { "mcllowat", CTLTYPE_INT }, \ 620 } 621 622 #ifdef _KERNEL 623 /* always use m_pulldown codepath for KAME IPv6/IPsec */ 624 #define PULLDOWN_TEST 625 626 extern struct mbstat mbstat; 627 extern int nmbclusters; /* limit on the # of clusters */ 628 extern int mblowat; /* mbuf low water mark */ 629 extern int mcllowat; /* mbuf cluster low water mark */ 630 extern int max_linkhdr; /* largest link-level header */ 631 extern int max_protohdr; /* largest protocol header */ 632 extern int max_hdr; /* largest link+protocol header */ 633 extern int max_datalen; /* MHLEN - max_hdr */ 634 extern const int msize; /* mbuf base size */ 635 extern const int mclbytes; /* mbuf cluster size */ 636 extern const int mbtypes[]; /* XXX */ 637 extern struct pool mbpool; 638 extern struct pool mclpool; 639 extern struct pool_cache mbpool_cache; 640 extern struct pool_cache mclpool_cache; 641 642 struct mbuf *m_copym __P((struct mbuf *, int, int, int)); 643 struct mbuf *m_copypacket __P((struct mbuf *, int)); 644 struct mbuf *m_devget __P((char *, int, int, struct ifnet *, 645 void (*copy)(const void *, void *, size_t))); 646 struct mbuf *m_dup __P((struct mbuf *, int, int, int)); 647 struct mbuf *m_free __P((struct mbuf *)); 648 struct mbuf *m_get __P((int, int)); 649 struct mbuf *m_getclr __P((int, int)); 650 struct mbuf *m_gethdr __P((int, int)); 651 struct mbuf *m_prepend __P((struct mbuf *,int,int)); 652 struct mbuf *m_pulldown __P((struct mbuf *, int, int, int *)); 653 struct mbuf *m_pullup __P((struct mbuf *, int)); 654 struct mbuf *m_copyup __P((struct mbuf *, int, int)); 655 struct mbuf *m_split __P((struct mbuf *,int,int)); 656 void m_adj __P((struct mbuf *, int)); 657 void m_cat __P((struct mbuf *,struct mbuf *)); 658 int m_mballoc __P((int, int)); 659 void m_copyback __P((struct mbuf *, int, int, caddr_t)); 660 void m_copydata __P((struct mbuf *, int, int, caddr_t)); 661 void m_freem __P((struct mbuf *)); 662 void m_reclaim __P((void *, int)); 663 void mbinit __P((void)); 664 665 struct mbuf *m_aux_add __P((struct mbuf *, int, int)); 666 struct mbuf *m_aux_find __P((struct mbuf *, int, int)); 667 void m_aux_delete __P((struct mbuf *, struct mbuf *)); 668 #endif /* _KERNEL */ 669 #endif /* !_SYS_MBUF_H_ */ 670 671 #ifdef _KERNEL 672 #ifdef MBTYPES 673 const int mbtypes[] = { /* XXX */ 674 M_FREE, /* MT_FREE 0 should be on free list */ 675 M_MBUF, /* MT_DATA 1 dynamic (data) allocation */ 676 M_MBUF, /* MT_HEADER 2 packet header */ 677 M_MBUF, /* MT_SONAME 3 socket name */ 678 M_SOOPTS, /* MT_SOOPTS 4 socket options */ 679 M_FTABLE, /* MT_FTABLE 5 fragment reassembly header */ 680 M_MBUF, /* MT_CONTROL 6 extra-data protocol message */ 681 M_MBUF, /* MT_OOBDATA 7 expedited data */ 682 }; 683 #undef MBTYPES 684 #else 685 extern const int mbtypes[]; 686 #endif /* MBTYPES */ 687 #endif /* _KERNEL */ 688