1.\" $OpenBSD: mbuf.9,v 1.75 2014/07/13 10:59:49 jmc Exp $ 2.\" 3.\" Copyright (c) 2001 Jean-Jacques Bernard-Gundol <jjbg@openbsd.org> 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 3. The name of the author may not be used to endorse or promote products 15.\" derived from this software without specific prior written permission 16.\" 17.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27.\" 28.Dd $Mdocdate: July 13 2014 $ 29.Dt MBUF 9 30.Os 31.Sh NAME 32.Nm mbuf 33.Nd kernel memory management for networking protocols 34.Sh SYNOPSIS 35.In sys/mbuf.h 36.Ft struct mbuf * 37.Fn m_copym2 "struct mbuf *m" "int off" "int len" "int wait" 38.Ft struct mbuf * 39.Fn m_copym "struct mbuf *m" "int off" "int len" "int wait" 40.Ft struct mbuf * 41.Fn m_free "struct mbuf *m" 42.Fn MFREE "struct mbuf *m" "struct mbuf *n" 43.Ft struct mbuf * 44.Fn m_get "int how" "int type" 45.Fn MGET "struct mbuf *m" "int how" "int type" 46.Ft struct mbuf * 47.Fn m_getclr "int how" "int type" 48.Ft struct mbuf * 49.Fn m_gethdr "int how" "int type" 50.Fn MGETHDR "struct mbuf *m" "int how" "int type" 51.Ft struct mbuf * 52.Fn m_prepend "struct mbuf *m" "int len" "int how" 53.Fn M_PREPEND "struct mbuf *m" "int plen" "int how" 54.Ft struct mbuf * 55.Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp" 56.Ft struct mbuf * 57.Fn m_pullup "struct mbuf *n" "int len" 58.Ft struct mbuf * 59.Fn m_split "struct mbuf *m0" "int len0" "int wait" 60.Ft struct mbuf * 61.Fn m_inject "struct mbuf *m0" "int len0" "int siz" "int wait" 62.Ft struct mbuf * 63.Fn m_getptr "struct mbuf *m" "int loc" "int *off" 64.Ft void 65.Fn m_adj "struct mbuf *mp" "int req_len" 66.Ft int 67.Fn m_copyback "struct mbuf *m0" "int off" "int len" "const void *cp" "int wait" 68.Ft int 69.Fn m_defrag "struct mbuf *m" "int wait" 70.Ft void 71.Fn m_freem "struct mbuf *m" 72.Ft void 73.Fn m_reclaim "void" 74.Ft void 75.Fn m_copydata "struct mbuf *m" "int off" "int len" "caddr_t cp" 76.Ft void 77.Fn m_cat "struct mbuf *m" "struct mbuf *n" 78.Ft struct mbuf * 79.Fn m_devget "char *buf" "int totlen" "int off" "struct ifnet *ifp" 80.Ft int 81.Fn m_apply "struct mbuf *m" "int off" "int len" \ 82"int (*func)(caddr_t, caddr_t, unsigned int)" "caddr_t fstate" 83.Fn MCLGET "struct mbuf *m" "int how" 84.Ft struct mbuf * 85.Fn MCLGETI "struct mbuf *m" "int how" "struct ifnet *ifp" "int len" 86.Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \ 87"void (*free)(caddr_t, u_int, void *)" "void *arg" 88.Fn M_ALIGN "struct mbuf *m" "int len" 89.Fn MH_ALIGN "struct mbuf *m" "int len" 90.Fn M_READONLY "struct mbuf *m" 91.Fn M_LEADINGSPACE "struct mbuf *m" 92.Fn M_TRAILINGSPACE "struct mbuf *m" 93.Ft int 94.Fn m_dup_pkthdr "struct mbuf *to" "struct mbuf *from" "int how" 95.Bd -literal 96#define MLEN (MSIZE - sizeof(struct m_hdr)) 97#define MHLEN (MLEN - sizeof(struct pkthdr)) 98 99#define MINCLSIZE (MHLEN + MLEN + 1) 100#define M_MAXCOMPRESS (MHLEN / 2) 101 102#define mtod(m,t) ((t)((m)-\*(Gtm_data)) 103 104struct m_hdr { 105 struct mbuf *mh_next; 106 struct mbuf *mh_nextpkt; 107 caddr_t mh_data; 108 u_int mh_len; 109 short mh_type; 110 u_short mh_flags; 111}; 112 113struct pkthdr { 114 struct ifnet *rcvif; 115 SLIST_HEAD(packet_tags, m_tag) tags; 116 int len; 117 u_int16_t tagsset; 118 u_int16_t pad; 119 u_int16_t csum_flags; 120 u_int16_t ether_vtag; 121 u_int ph_rtableid; 122 void *ph_cookie; 123 struct pkthdr_pf pf; 124}; 125 126struct pkthdr_pf { 127 void *statekey; 128 u_int32_t qid; 129 u_int16_t tag; 130 u_int8_t flags; 131 u_int8_t routed; 132 u_int8_t prio; 133 u_int8_t pad[3]; 134}; 135 136struct mbuf_ext { 137 caddr_t ext_buf; 138 void (*ext_free)(caddr_t, u_int, void *); 139 void *ext_arg; 140 u_int ext_size; 141 int ext_type; 142 u_short ext_ifidx; 143 int ext_backend; 144 struct mbuf *ext_nextref; 145 struct mbuf *ext_prevref; 146}; 147 148struct mbuf { 149 struct m_hdr m_hdr; 150 union { 151 struct { 152 struct pkthdr MH_pkthdr; 153 union { 154 struct mbuf_ext MH_ext; 155 char MH_databuf[MHLEN]; 156 } MH_dat; 157 } MH; 158 char M_databuf[MLEN]; 159 } M_dat; 160}; 161 162#define m_next m_hdr.mh_next 163#define m_len m_hdr.mh_len 164#define m_data m_hdr.mh_data 165#define m_type m_hdr.mh_type 166#define m_flags m_hdr.mh_flags 167#define m_nextpkt m_hdr.mh_nextpkt 168#define m_act m_nextpkt 169#define m_pkthdr M_dat.MH.MH_pkthdr 170#define m_ext M_dat.MH.MH_dat.MH_ext 171#define m_pktdat M_dat.MH.MH_dat.MH_databuf 172#define m_dat M_dat.M_databuf 173.Ed 174.Sh DESCRIPTION 175The 176.Nm 177functions provide a way to manage the memory buffers used by the kernel's 178networking subsystem. 179Several functions and macros are used to allocate and deallocate mbufs, 180but also to get, inject, remove, copy, modify, prepend or append data 181inside these mbufs. 182The size of an 183.Nm 184is MSIZE 185.Pq defined in In sys/param.h . 186.Pp 187An 188.Nm 189structure is defined as an 190.Fa m_hdr 191structure followed by a 192union. 193The header contains the following elements: 194.Bl -tag -width foobarmoocow 195.It Fa mh_next 196A pointer to the next mbuf in the mbuf chain. 197.It Fa mh_nextpkt 198A pointer to the next mbuf chain (i.e., packet) in the queue. 199.It Fa mh_data 200Indicates the address of the beginning of data in the mbuf. 201.It Fa mh_len 202Indicates the amount of data in the mbuf. 203.It Fa mh_type 204Indicates the type of data contained in the mbuf (see below). 205.It Fa mh_flags 206Flags (see below). 207.El 208.Pp 209The 210.Fa mh_type 211variable can take the following values: 212.Pp 213.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX 214.It Dv MT_FREE 215the mbuf should be on the free list. 216.It Dv MT_DATA 217the data in the mbuf was dynamically allocated. 218.It Dv MT_HEADER 219the data contains a packet header. 220.It Dv MT_SONAME 221the data is a socket name. 222.It Dv MT_SOOPTS 223the data are socket options. 224.It Dv MT_FTABLE 225the data is a fragment reassembly header. 226.It Dv MT_CONTROL 227the mbuf contains extra-data protocol message. 228.It Dv MT_OOBDATA 229the data consists of out-of-band data. 230.El 231.Pp 232The 233.Fa mh_flags 234variable can take the following values: 235.Pp 236.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX 237.It Dv M_EXT 238mbuf has associated external storage. 239.It Dv M_PKTHDR 240the mbuf is the first that forms a packet. 241.It Dv M_EOR 242end of record. 243.It Dv M_CLUSTER 244the external storage is a cluster. 245.It Dv M_PROTO1 246protocol-specific. 247.It Dv M_BCAST 248packet send/received as link-level broadcast. 249.It Dv M_MCAST 250packet send/received as link-level multicast. 251.It Dv M_CONF 252packet was encrypted (ESP-transport). 253.It Dv M_AUTH 254packet was authenticated (AH or ESP). 255.It Dv M_ZEROIZE 256Zero the data part of the mbufs in the mbuf chain pointed to by 257.Nm m_free . 258.It Dv M_TUNNEL 259header was IP-in-IP encapsulated by tunnel mode IPsec. 260.It Dv M_LINK0 261link layer specific flag. 262.It Dv M_LOOP 263for mbuf statistics. 264.It Dv M_FILDROP 265dropped by 266.Xr bpf 4 267filter. 268.It Dv M_VLANTAG 269.Fa m_pkthdr.ether_vtag 270variable is valid. 271.El 272.Pp 273An external cluster is used when the data to hold in the mbuf is 274large. 275The size of an external cluster is between MCLBYTES and MAXMCLBYTES 276.Pq also defined in In sys/param.h . 277A cluster should be used when the size of the data reach MINCLSIZE 278(the minimum size to be held by an external cluster). 279.Pp 280The combination of the M_EXT and M_PKTHDR flags give four types of 281mbuf. 282When none of these constants are in use, the mbuf is a "normal" 283one, where the data part of the mbuf has the following elements: 284.Bl -tag -width foobarmoocow 285.It Fa m_dat 286buffer holding the data (size MLEN). 287.El 288.Pp 289When only M_PKTHDR is set, the data contained in the mbuf is a packet header. 290The data itself is contained in the mbuf (just like the previous case), 291but part of the mbuf is used to store a packet header. 292The data part has then the following elements: 293.Bl -tag -width foobarmoocow 294.It Fa m_pkthdr 295packet header, containing the length of the data, a pointer to the 296interface on which the data was received, checksum information 297and list of 298.Xr mbuf_tags 9 . 299.It Fa m_pktdat 300buffer holding the data (size MHLEN). 301.El 302.Pp 303The 304.Fa m_pkthdr.csum_flags 305variable can take the following values: 306.Pp 307.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX 308.It Dv M_IPV4_CSUM_OUT 309IPv4 checksum needed. 310.It Dv M_TCP_CSUM_OUT 311TCP checksum needed. 312.It Dv M_UDP_CSUM_OUT 313UDP checksum needed. 314.It Dv M_ICMP_CSUM_OUT 315ICMP/ICMPv6 checksum needed. 316.It Dv M_IPV4_CSUM_IN_OK 317IPv4 checksum verified. 318.It Dv M_IPV4_CSUM_IN_BAD 319IPv4 checksum bad. 320.It Dv M_TCP_CSUM_IN_OK 321TCP checksum verified. 322.It Dv M_TCP_CSUM_IN_BAD 323TCP checksum bad. 324.It Dv M_UDP_CSUM_IN_OK 325UDP checksum verified. 326.It Dv M_UDP_CSUM_IN_BAD 327UDP checksum bad. 328.It Dv M_ICMP_CSUM_IN_OK 329ICMP/ICMPv6 checksum verified. 330.It Dv M_ICMP_CSUM_IN_BAD 331ICMP/ICMPv6 checksum bad. 332.El 333.Pp 334When only M_EXT flag is set, an external storage buffer is being used to 335hold the data, which is no longer stored in the mbuf. 336The data part of the mbuf has now the following elements: 337.Bl -tag -width foobarmoocow 338.It Fa m_pkthdr 339a packet header, just like the previous case, but it is empty. 340No information is stored here 341.It Fa m_ext 342a structure containing information about the external storage 343buffer. 344The information consists of the address of the external buffer, 345a pointer to the function used to free the buffer, a pointer to the 346arguments of the function, the size of the buffer, the type of the 347buffer, and pointers to the previous and next mbufs using this 348cluster. 349.El 350.Pp 351When both the M_EXT and M_PKTHDR flags are set, an external storage buffer 352is being used to store the data and this data contains a packet header. 353The structure used is the same as the previous one except that the 354.Fa m_pkthdr 355element is not empty, it contains the same information as when 356M_PKTHDR is used alone. 357.Bl -tag -width Ds 358.It Fn m_copym "struct mbuf *m" "int off" "int len" "int wait" 359Copy an mbuf chain starting at 360.Fa off 361bytes from the beginning 362and continuing for 363.Fa len 364bytes. 365If 366.Fa off 367is zero and 368.Fa m 369has the M_PKTHDR flag set, 370the header is copied. 371If 372.Fa len 373is M_COPYALL 374the whole mbuf is copied. 375The 376.Fa wait 377parameter can be M_WAIT or 378M_DONTWAIT. 379It does not copy clusters, it just increases their reference count. 380.It Fn m_copym2 "struct mbuf *m" "int off" "int len" "int wait" 381The same as 382.Fn m_copym 383except that it copies cluster mbufs, whereas 384.Fn m_copym 385just increases the reference count of the clusters. 386.It Fn m_free "struct mbuf *m" 387Free the mbuf pointed to by 388.Fa m . 389A pointer to the successor of the mbuf, 390if it exists, is returned by the function. 391.It Fn MFREE "struct mbuf *m" "struct mbuf *n" 392Free the mbuf pointed to by 393.Fa m 394and use 395.Fa n 396to point to the next mbuf in 397the chain if it exists. 398See 399.Fn m_free . 400.It Fn m_get "int how" "int type" 401Return a pointer to an mbuf of the type specified. 402If the 403.Fa how 404argument is 405.Fa M_WAITOK , 406the function may call 407.Xr tsleep 9 408to await resources. 409If 410.Fa how 411is 412.Fa M_DONTWAIT 413and resources are not available, 414.Fn m_get 415returns NULL. 416.It Fn MGET "struct mbuf *m" "int how" "int type" 417Return a pointer to an mbuf in 418.Fa m 419of the type specified. 420See 421.Fn m_get 422for a description of 423.Fa how . 424.It Fn m_getclr "int how" "int type" 425Return a pointer to an mbuf of the type specified, and clear the data 426area of the mbuf. 427See 428.Fn m_get 429for a description of 430.Fa how . 431.It Fn m_gethdr "int how" "int type" 432Return a pointer to an mbuf of the type specified after initializing 433it to contain a packet header. 434See 435.Fn m_get 436for a description of 437.Fa how . 438.It Fn MGETHDR "struct mbuf *m" "int how" "int type" 439Return a pointer to an mbuf of the type specified after initializing 440it to contain a packet header. 441See 442.Fn m_get 443for a description of 444.Fa how . 445.It Fn m_prepend "struct mbuf *m" "int len" "int how" 446Allocate a new mbuf and prepend it to the mbuf chain pointed to by 447.Fa m . 448If 449.Fa m 450points to an mbuf with a packet header, it is moved to the new 451mbuf that has been prepended. 452The return value is a pointer on the new mbuf chain. 453If this function fails to allocate a new mbuf, 454.Fa m 455is freed. 456See 457.Fn m_get 458for a description of 459.Fa how . 460.Pp 461.Fn m_prepend 462should never be called directly. 463Use 464.Fn M_PREPEND 465instead. 466.It Fn M_PREPEND "struct mbuf *m" "int plen" "int how" 467Prepend space of size 468.Fa plen 469to the mbuf pointed to by 470.Fa m . 471If a new mbuf must be allocated, 472.Fa how 473specifies whether to wait or not. 474If this function fails to allocate a new mbuf, 475.Fa m 476is freed. 477.It Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp" 478Ensure that the data in the mbuf chain starting at 479.Fa off 480and ending at 481.Fa off+len 482will be put in a continuous memory region. 483If memory must be allocated, then it will fail if the 484.Fa len 485argument is greater than MAXMCLBYTES. 486The pointer returned points to an mbuf in the chain and the new offset 487for data in this mbuf is 488.Fa *offp . 489If this function fails, 490.Fa m 491is freed. 492.It Fn m_pullup "struct mbuf *n" "int len" 493Ensure that the data in the mbuf chain starting at the beginning of 494the chain and ending at 495.Fa len 496will be put in continuous memory region. 497If memory must be allocated, then it will fail if the 498.Fa len 499argument is greater than MAXMCLBYTES. 500If this function fails, 501.Fa n 502is freed. 503.It Fn m_split "struct mbuf *m0" "int len0" "int wait" 504Split an mbuf chain in two pieces, returning a pointer to 505the tail (which is made of the previous mbuf chain except the first 506.Fa len0 507bytes). 508.It Fn m_inject "struct mbuf *m0" "int len0" "int siz" "int wait" 509Inject a new mbuf chain of length 510.Fa siz 511into the mbuf chain pointed to by 512.Fa m0 513at position 514.Fa len0 . 515If there is enough space for an object of size 516.Fa siz 517in the appropriate location, no memory will be allocated. 518On failure, the function returns NULL (the mbuf is left untouched) and 519on success, a pointer to the first injected mbuf is returned. 520.It Fn m_getptr "struct mbuf *m" "int loc" "int *off" 521Returns a pointer to the mbuf containing the data located at 522.Fa loc 523bytes of the beginning. 524The offset in the new mbuf is pointed to by 525.Fa off . 526.It Fn m_adj "struct mbuf *mp" "int req_len" 527Trims 528.Fa req_len 529bytes of data from the mbuf chain pointed to by 530.Fa mp . 531If 532.Fa req_len 533is positive, the data will be trimmed from the head of the mbuf chain 534and if it is negative, it will be trimmed from the tail of the mbuf 535chain. 536.It Fn m_copyback "struct mbuf *m0" "int off" "int len" "caddr_t cp" "int wait" 537Copy data from a buffer pointed to by 538.Fa cp 539back into the mbuf chain pointed to by 540.Fa m0 541starting at 542.Fa off 543bytes from the beginning, extending the mbuf chain if 544necessary, sleeping for mbufs if 545.Fa wait 546is 547.Fa M_WAIT . 548If 549.Fa M_NOWAIT 550is set and no mbufs are available, 551.Fn m_copyback 552returns 553.Er ENOBUFS . 554The mbuf chain must be initialized properly, including setting 555.Fa m_len . 556.It Fn m_defrag "struct mbuf *m" "int wait" 557Defragment the data mbufs referenced by 558.Fa m 559by replacing the chain with a copy of their contents made into a 560single mbuf or cluster. 561.Fa wait 562specifies whether it can wait or not for the replacement storage. 563.Fn m_defrag 564returns 0 on success or 565.Er ENOBUFS 566on failure. 567The mbuf pointer 568.Fa m 569remains in existence and unchanged on failure. 570.It Fn m_freem "struct mbuf *m" 571Free the mbuf chain pointed to by 572.Fa m . 573.It Fn m_reclaim "void" 574Ask protocols to free unused memory space. 575.It Fn m_copydata "struct mbuf *m" "int off" "int len" "caddr_t cp" 576Copy data from the mbuf chain pointed to by 577.Fa m 578starting at 579.Fa off 580bytes from the beginning and continuing for 581.Fa len 582bytes into the buffer pointed to by 583.Fa cp . 584.It Fn m_cat "struct mbuf *m" "struct mbuf *n" 585Concatenate the mbuf chain pointed to by 586.Fa n 587to the mbuf chain pointed to by 588.Fa m . 589The mbuf chains must be of the same type. 590.It Fn m_devget "char *buf" "int totlen" "int off" "struct ifnet *ifp" 591Copy 592.Fa totlen 593bytes of data from device local memory pointed to by 594.Fa buf . 595The data is copied into an mbuf chain at offset 596.Fa off 597and a pointer to the head of the chain is returned. 598Returns NULL on failure. 599.It Fn m_apply "struct mbuf *m" "int off" "int len" \ 600"int (*func)(caddr_t, caddr_t, unsigned int)" "caddr_t fstate" 601Apply the function 602.Fa func 603to the data in the mbuf chain pointed to by 604.Fa m 605starting at 606.Fa off 607bytes from the beginning and continuing for 608.Fa len 609bytes. 610.It Fn mtod "struct mbuf *m" "datatype" 611Return a pointer to the data contained in the specified mbuf 612.Fa m 613cast to 614.Fa datatype . 615.It Fn MCLGET "struct mbuf *m" "int how" 616Allocate and add an mbuf cluster to the mbuf pointed to by 617.Fa m . 618On success, the flag M_EXT is set in the mbuf. 619See 620.Fn m_get 621for a description of 622.Fa how . 623.It Fn MCLGETI "struct mbuf *m" "int how" "struct ifnet *ifp" "int len" 624If 625.Fa m 626is NULL, allocate it. 627Then allocate and add an mbuf cluster of length 628.Fa len 629to the mbuf pointed to by 630.Fa m . 631Returns either the mbuf 632.Fa m 633that was passed in, or the newly allocated one which was allocated; in 634either case the flag M_EXT is set in the mbuf. 635See 636.Fn m_get 637for a description of 638.Fa how . 639.It Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \ 640"void (*free)(caddr_t, u_int, void *)" "void *arg" 641Add pre-allocated storage to the mbuf pointed to by 642.Fa m . 643On success, the flag M_EXT is set in the mbuf, and M_EXTWR is specified in 644.Fa flags . 645.It Fn M_ALIGN "struct mbuf *m" "int len" 646Set the 647.Fa m_data 648pointer of the newly allocated mbuf with 649.Fn m_get 650or 651.Fn MGET 652pointed to by 653.Fa m 654to an object of the specified size 655.Fa len 656at the end of the mbuf, longword aligned. 657.It Fn MH_ALIGN "m" "len" 658Same as 659.Fn M_ALIGN 660except it is for an mbuf allocated with 661.Fn m_gethdr 662or 663.Fn MGETHDR . 664.It Fn M_READONLY "struct mbuf *m" 665Check if the data of the mbuf pointed to by 666.Fa m 667is read-only. 668This is true for non-cluster external storage and for clusters that 669are being referenced by more than one mbuf. 670.It Fn M_LEADINGSPACE "struct mbuf *m" 671Compute the amount of space available before the current start of data 672in the mbuf pointed to by 673.Fa m . 674.It Fn M_TRAILINGSPACE "struct mbuf *m" 675Compute the amount of space available after the end of data in the 676mbuf pointed to by 677.Fa m . 678.It Fn m_dup_pkthdr "struct mbuf *to" "struct mbuf *from" "int how" 679Copy mbuf packet header, including mbuf tags, from 680.Fa from 681to 682.Fa to . 683See 684.Fn m_get 685for a description of 686.Fa how . 687.El 688.Sh CODE REFERENCES 689The mbuf management functions are implemented in the files 690.Pa sys/kern/uipc_mbuf.c 691and 692.Pa sys/kern/uipc_mbuf2.c . 693The function prototypes and the macros are located in 694.Pa sys/sys/mbuf.h . 695.Sh SEE ALSO 696.Xr netstat 1 , 697.Xr mbuf_tags 9 698.Rs 699.%A Jun-Ichiro Hagino 700.%T "Mbuf issues in 4.4BSD IPv6/IPsec support (experiences from KAME IPv6/IPsec implementation)" 701.%B "Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference" 702.%D June 2000 703.Re 704