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