1.\" $NetBSD: mbuf.9,v 1.45 2007/07/30 22:48:47 alc Exp $ 2.\" 3.\" Copyright (c) 1997 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This documentation is derived from text contributed to The NetBSD Foundation 7.\" by S.P.Zeidler (aka stargazer). 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 3. All advertising materials mentioning features or use of this software 18.\" must display the following acknowledgement: 19.\" This product includes software developed by the NetBSD 20.\" Foundation, Inc. and its contributors. 21.\" 4. Neither the name of The NetBSD Foundation nor the names of its 22.\" contributors may be used to endorse or promote products derived 23.\" from this software without specific prior written permission. 24.\" 25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35.\" POSSIBILITY OF SUCH DAMAGE. 36.\" 37.Dd July 28, 2006 38.Dt MBUF 9 39.Os 40.Sh NAME 41.Nm mbuf , 42.Nm m_get , 43.Nm m_getclr , 44.Nm m_gethdr , 45.Nm m_devget , 46.Nm m_copym , 47.Nm m_copypacket , 48.Nm m_copydata , 49.Nm m_copyback , 50.Nm m_copyback_cow , 51.Nm m_cat , 52.Nm m_dup , 53.Nm m_makewritable , 54.Nm m_prepend , 55.Nm m_pulldown , 56.Nm m_pullup , 57.Nm m_split , 58.Nm m_adj , 59.Nm m_apply , 60.Nm m_free , 61.Nm m_freem , 62.Nm mtod , 63.Nm MGET , 64.Nm MGETHDR , 65.Nm MEXTMALLOC , 66.Nm MEXTADD , 67.Nm MCLGET , 68.Nm M_COPY_PKTHDR , 69.Nm M_MOVE_PKTHDR , 70.Nm M_ALIGN , 71.Nm MH_ALIGN , 72.Nm M_LEADINGSPACE , 73.Nm M_TRAILINGSPACE , 74.Nm M_PREPEND , 75.Nm MCHTYPE , 76.Nm MEXTREMOVE , 77.Nm MFREE , 78.Nd "functions and macros for managing memory used by networking code" 79.Sh SYNOPSIS 80.In sys/mbuf.h 81.Ft struct mbuf * 82.Fn m_get "int nowait" "int type" 83.Ft struct mbuf * 84.Fn m_getclr "int nowait" "int type" 85.Ft struct mbuf * 86.Fn m_gethdr "int nowait" "int type" 87.Ft struct mbuf * 88.Fn m_devget "char *buf" "int totlen" "int off0" "struct ifnet *ifp" "void (*copy)(const void *, void *, size_t)" 89.Ft struct mbuf * 90.Fn m_copym "struct mbuf *m" "int off0" "int len" "int wait" 91.Ft struct mbuf * 92.Fn m_copypacket "struct mbuf *m" "int how" 93.Ft void 94.Fn m_copydata "struct mbuf *m" "int off" "int len" "void *cp" 95.Ft void 96.Fn m_copyback "struct mbuf *m0" "int off" "int len" "void *cp" 97.Ft struct mbuf * 98.Fn m_copyback_cow "struct mbuf *m0" "int off" "int len" "void *cp" "int how" 99.Ft int 100.Fn m_makewritable "struct mbuf **mp" "int off" "int len" "int how" 101.Ft void 102.Fn m_cat "struct mbuf *m" "struct mbuf *n" 103.Ft struct mbuf * 104.Fn m_dup "struct mbuf *m" "int off0" "int len" "int wait" 105.Ft struct mbuf * 106.Fn m_prepend "struct mbuf *m" "int len" "int how" 107.Ft struct mbuf * 108.Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp" 109.Ft struct mbuf * 110.Fn m_pullup "struct mbuf *n" "int len" 111.Ft struct mbuf * 112.Fn m_split "struct mbuf *m0" "int len0" "int wait" 113.Ft void 114.Fn m_adj "struct mbuf *mp" "int req_len" 115.Ft int 116.Fn m_apply "struct mbuf *m" "int off" "int len" "int *f(void *, void *, unsigned int)" "void *arg" 117.Ft struct mbuf * 118.Fn m_free "struct mbuf *m" 119.Ft void 120.Fn m_freem "struct mbuf *m" 121.Ft datatype 122.Fn mtod "struct mbuf *m" "datatype" 123.Ft void 124.Fn MGET "struct mbuf *m" "int how" "int type" 125.Ft void 126.Fn MGETHDR "struct mbuf *m" "int how" "int type" 127.Ft void 128.Fn MEXTMALLOC "struct mbuf *m" "int len" "int how" 129.Ft void 130.Fn MEXTADD "struct mbuf *m" "void *buf" "int size" "int type" "void (*free)(struct mbuf *, void *, size_t, void *)" "void *arg" 131.Ft void 132.Fn MCLGET "struct mbuf *m" "int how" 133.Ft void 134.Fn M_COPY_PKTHDR "struct mbuf *to" "struct mbuf *from" 135.Ft void 136.Fn M_MOVE_PKTHDR "struct mbuf *to" "struct mbuf *from" 137.Ft void 138.Fn M_ALIGN "struct mbuf *m" "int len" 139.Ft void 140.Fn MH_ALIGN "struct mbuf *m" "int len" 141.Ft int 142.Fn M_LEADINGSPACE "struct mbuf *m" 143.Ft int 144.Fn M_TRAILINGSPACE "struct mbuf *m" 145.Ft void 146.Fn M_PREPEND "struct mbuf *m" "int plen" "int how" 147.Ft void 148.Fn MCHTYPE "struct mbuf *m" "int type" 149.Ft void 150.Fn MEXTREMOVE "struct mbuf *m" 151.Ft void 152.Fn MFREE "struct mbuf *m" "struct mbuf *n" 153.Sh DESCRIPTION 154The 155.Nm 156functions and macros provide an easy and consistent way to handle 157a networking stack's memory management needs. 158An 159.Nm 160consists of a header and a data area. 161It is of a fixed size, 162.Dv MSIZE 163.Pq defined in Aq Pa machine/param.h , 164which includes overhead. 165The header contains a pointer to the next 166.Nm 167in the 168.Sq "mbuf chain" , 169a pointer to the next 170.Sq "mbuf chain" , 171a pointer to the data area, the amount of data in this mbuf, its type 172and a 173.Dv flags 174field. 175.Pp 176The 177.Dv type 178variable can signify: 179.Bl -tag -compact -offset indent -width "XXXXXXXXXXX" 180.It Dv MT_FREE 181the mbuf should be on the ``free'' list 182.It Dv MT_DATA 183data was dynamically allocated 184.It Dv MT_HEADER 185data is a packet header 186.It Dv MT_SONAME 187data is a socket name 188.It Dv MT_SOOPTS 189data is socket options 190.It Dv MT_FTABLE 191data is the fragment reassembly header 192.It Dv MT_CONTROL 193mbuf contains ancillary \&(protocol control\&) data 194.It Dv MT_OOBDATA 195mbuf contains out-of-band data. 196.El 197.Pp 198The 199.Dv flags 200variable contains information describing the 201.Nm , 202notably: 203.Bl -tag -compact -offset indent -width "XXXXXXXXXXX" 204.It Dv M_EXT 205has external storage 206.It Dv M_PKTHDR 207is start of record 208.It Dv M_EOR 209is end of record 210.It Dv M_CLUSTER 211external storage is a cluster. 212.El 213.Pp 214If an 215.Nm 216designates the start of a record 217.Pq Dv M_PKTHDR , 218its 219.Dv flags 220field may contain additional information describing the content of 221the record: 222.Bl -tag -compact -offset indent -width "XXXXXXXXXXX" 223.It Dv M_BCAST 224sent/received as link-level broadcast 225.It Dv M_MCAST 226sent/received as link-level multicast 227.It Dv M_LINK0 , 228.It Dv M_LINK1 , 229.It Dv M_LINK2 230three link-level specific flags. 231.El 232.Pp 233An 234.Nm 235may add a single 236.Sq "mbuf cluster" 237of 238.Dv MCLBYTES 239bytes 240.Pq also defined in Aq Pa machine/param.h , 241which has no additional overhead 242and is used instead of the internal data area; this is done when at least 243.Dv MINCLSIZE 244bytes of data must be stored. 245.Pp 246When the 247.Dv M_EXT 248flag is raised for an mbuf, 249the external storage area could be shared among multiple mbufs. 250Be careful when you attempt to overwrite the data content of the mbuf. 251.Bl -tag -width compact 252.It Fn m_get "int nowait" "int type" 253Allocates an mbuf and initializes it to contain internal data. 254The 255.Fa nowait 256parameter is a choice of 257.Dv M_WAIT / M_DONTWAIT 258from caller. 259.Dv M_WAIT 260means the call cannot fail, but may take forever. 261The 262.Fa type 263parameter is an mbuf type. 264.It Fn m_getclr "int nowait" "int type" 265Allocates an mbuf and initializes it to contain internal data, then 266zeros the data area. 267The 268.Fa nowait 269parameter is a choice of 270.Dv M_WAIT / M_DONTWAIT 271from caller. 272The 273.Fa type 274parameter is an mbuf type. 275.It Fn m_gethdr "int nowait" "int type" 276Allocates an mbuf and initializes it to contain a packet header and internal 277data. 278The 279.Fa nowait 280parameter is a choice of 281.Dv M_WAIT / M_DONTWAIT 282from caller. 283The 284.Fa type 285parameter is an mbuf type. 286.It Fn m_devget "char *buf" "int totlen" "int off0" "struct ifnet *ifp" "void (*copy)(const void *, void *, size_t)" 287Copies 288.Fa len 289bytes from device local memory into mbufs using copy routine 290.Fa copy . 291If parameter 292.Fa off 293is non-zero, the packet is supposed to be trailer-encapsulated and 294.Fa off 295bytes plus the type and length fields will be skipped before copying. 296Returns the top of the mbuf chain it created. 297.It Fn m_copym "struct mbuf *m" "int off0" "int len" "int wait" 298Creates a copy of an mbuf chain starting 299.Fa off0 300bytes from the beginning, continuing for 301.Fa len 302bytes. 303If the 304.Fa len 305requested is 306.Dv M_COPYALL , 307the complete mbuf chain will be copied. 308The 309.Fa wait 310parameter is a choice of 311.Dv M_WAIT / M_DONTWAIT 312from caller. 313.It Fn m_copypacket "struct mbuf *m" "int how" 314Copies an entire packet, including header (which must be present). 315This function is an optimization of the common case 316.Li m_copym(m, 0, Dv M_COPYALL, Fa how ) . 317.It Fn m_copydata "struct mbuf *m" "int off" "int len" "void *cp" 318Copies 319.Fa len 320bytes data from mbuf chain 321.Fa m 322into the buffer 323.Fa cp , 324starting 325.Fa off 326bytes from the beginning. 327.It Fn m_copyback "struct mbuf *m0" "int off" "int len" "void *cp" 328Copies 329.Fa len 330bytes data from buffer 331.Fa cp 332back into the mbuf chain 333.Fa m0 , 334starting 335.Fa off 336bytes from the beginning of the chain, extending the mbuf chain if necessary. 337.Fn m_copyback 338can only fail when extending the chain. 339The caller should check for this kind of failure 340by checking the resulting length of the chain in that case. 341It is an error to use 342.Fn m_copyback 343on read-only mbufs. 344.It Fn m_copyback_cow "struct mbuf *m0" "int off" "int len" "void *cp" \ 345"int how" 346Copies 347.Fa len 348bytes data from buffer 349.Fa cp 350back into the mbuf chain 351.Fa m0 352as 353.Fn m_copyback 354does. 355Unlike 356.Fn m_copyback , 357it is safe to use 358.Fn m_copyback_cow 359on read-only mbufs. 360If needed, 361.Fn m_copyback_cow 362automatically allocates new mbufs and adjusts the chain. 363On success, it returns a pointer to the resulting mbuf chain, 364and frees the original mbuf 365.Fa m0 . 366Otherwise, it returns 367.Dv NULL . 368The 369.Fa how 370parameter is a choice of 371.Dv M_WAIT / M_DONTWAIT 372from the caller. 373Unlike 374.Fn m_copyback , 375extending the mbuf chain isn't supported. 376It is an error to attempt to extend the mbuf chain using 377.Fn m_copyback_cow . 378.It Fn m_makewritable "struct mbuf **mp" "int off" "int len" "int how" 379Rearranges an mbuf chain so that 380.Fa len 381bytes from offset 382.Fa off 383are writable. 384When it meets read-only mbufs, it allocates new mbufs, adjusts the chain as 385.Fn m_copyback_cow 386does, and copies the original content into them. 387.Fn m_makewritable 388does 389.Em not 390guarantee that all 391.Fa len 392bytes at 393.Fa off 394are consecutive. 395The 396.Fa how 397parameter is a choice of 398.Dv M_WAIT / M_DONTWAIT 399from the caller. 400.Fn m_makewritable 401preserves the contents of the mbuf chain even in the case of failure. 402It updates a pointer to the mbuf chain pointed to by 403.Fa mp . 404It returns 0 on success. 405Otherwise, it returns an error code, typically 406.Er ENOBUFS . 407.It Fn m_cat "struct mbuf *m" "struct mbuf *n" 408Concatenates mbuf chain 409.Fa n 410to 411.Fa m . 412Both chains must be of the same type; packet headers will 413.Em not 414be updated if present. 415.It Fn m_dup "struct mbuf *m" "int off0" "int len" "int wait" 416Similarly to 417.Fn m_copym , 418the function creates a copy of an mbuf chain starting 419.Fa off0 420bytes from the beginning, continuing for 421.Fa len 422bytes. 423While 424.Fn m_copym 425tries to share external storage for mbufs with 426.Dv M_EXT 427flag, 428.Fn m_dup 429will deep-copy the whole data content into new mbuf chain 430and avoids shared external storage. 431.It Fn m_prepend "struct mbuf *m" "int len" "int how" 432Lesser-used path for 433.Fn M_PREPEND : 434allocates new mbuf 435.Fa m 436of size 437.Fa len 438to prepend to the chain, copying junk along. 439The 440.Fa how 441parameter is a choice of 442.Dv M_WAIT / M_DONTWAIT 443from caller. 444.It Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp" 445Rearranges an mbuf chain so that 446.Fa len 447bytes from offset 448.Fa off 449are contiguous and in the data area of an mbuf. 450The return value points to an mbuf in the middle of the mbuf chain 451.Fa m . 452If we call the return value 453.Fa n , 454the contiguous data region is available at 455.Li "mtod(n, void *) + *offp" , 456or 457.Li "mtod(n, void *)" 458if 459.Fa offp 460is 461.Dv NULL . 462The top of the mbuf chain 463.Fa m , 464and mbufs up to 465.Fa off , 466will not be modified. 467On successful return, it is guaranteed that the mbuf pointed to by 468.Fa n 469does not have a shared external storage, 470therefore it is safe to update the contiguous region. 471Returns 472.Dv NULL 473and frees the mbuf chain on failure. 474.Fa len 475must be smaller or equal than 476.Dv MCLBYTES . 477.It Fn m_pullup "struct mbuf *m" "int len" 478Rearranges an mbuf chain so that 479.Fa len 480bytes are contiguous 481and in the data area of an mbuf (so that 482.Fn mtod 483will work for a structure of size 484.Fa len ) . 485Returns the resulting 486mbuf chain on success, frees it and returns 487.Dv NULL 488on failure. 489If there is room, it will add up to 490.Dv max_protohdr 491- 492.Fa len 493extra bytes to the 494contiguous region to possibly avoid being called again. 495.Fa len 496must be smaller or equal than 497.Dv MHLEN . 498.It Fn m_split "struct mbuf *m0" "int len0" "int wait" 499Partitions an mbuf chain in two pieces, returning the tail, 500which is all but the first 501.Fa len0 502bytes. 503In case of failure, it returns 504.Dv NULL 505and attempts to 506restore the chain to its original state. 507.It Fn m_adj "struct mbuf *mp" "int req_len" 508Shaves off 509.Fa req_len 510bytes from head or tail of the (valid) data area. 511If 512.Fa req_len 513is greater than zero, front bytes are being shaved off, if it's smaller, 514from the back (and if it is zero, the mbuf will stay bearded). 515This function does not move data in any way, but is used to manipulate the 516data area pointer and data length variable of the mbuf in a non-clobbering 517way. 518.It Fn m_apply "struct mbuf *m" "int off" "int len" "int (*f)(void *, void *, unsigned int)" "void *arg" 519Apply function 520.Fa f 521to the data in an mbuf chain starting 522.Fa off 523bytes from the beginning, continuing for 524.Fa len 525bytes. 526Neither 527.Fa off 528nor 529.Fa len 530may be negative. 531.Fa arg 532will be supplied as first argument for 533.Fa f , 534the second argument will be the pointer to the data buffer of a 535packet (starting after 536.Fa off 537bytes in the stream), and the third argument is the amount 538of data in bytes in this call. 539If 540.Fa f 541returns something not equal to zero 542.Fn m_apply 543will bail out, returning the return code of 544.Fa f . 545Upon successful completion it will return zero. 546.It Fn m_free "struct mbuf *m" 547Frees mbuf 548.Fa m . 549.It Fn m_freem "struct mbuf *m" 550Frees the mbuf chain beginning with 551.Fa m . 552This function contains the elementary sanity check for a 553.Dv NULL 554pointer. 555.It Fn mtod "struct mbuf *m" "datatype" 556Returns a pointer to the data contained in the specified mbuf 557.Fa m , 558type-casted to the specified data type 559.Fa datatype . 560Implemented as a macro. 561.It Fn MGET "struct mbuf *m" "int how" "int type" 562Allocates mbuf 563.Fa m 564and initializes it to contain internal data. 565See 566.Fn m_get . 567Implemented as a macro. 568.It Fn MGETHDR "struct mbuf *m" "int how" "int type" 569Allocates mbuf 570.Fa m 571and initializes it to contain a packet header. 572See 573.Fn m_gethdr . 574Implemented as a macro. 575.It Fn MEXTMALLOC "struct mbuf *m" "int len" "int how" 576Allocates external storage of size 577.Fa len 578for mbuf 579.Fa m . 580The 581.Fa how 582parameter is a choice of 583.Dv M_WAIT / M_DONTWAIT 584from caller. 585The flag 586.Dv M_EXT 587is set upon success. 588Implemented as a macro. 589.It Fn MEXTADD "struct mbuf *m" "void *buf" "int size" "int type" "void (*free)(struct mbuf *, void *, size_t, void *)" "void *arg" 590Adds pre-allocated external storage 591.Fa buf 592to a normal mbuf 593.Fa m ; 594the parameters 595.Fa size , 596.Fa type , 597.Fa free 598and 599.Fa arg 600describe the external storage. 601.Fa size 602is the size of the storage, 603.Fa type 604describes its 605.Xr malloc 9 606type, 607.Fa free 608is a free routine (if not the usual one), and 609.Fa arg 610is a possible argument to the free routine. 611The flag 612.Dv M_EXT 613is set upon success. 614Implemented as a macro. 615If a free routine is specified, it will be called when the mbuf is freed or 616when MEXTREMOVE is called for the mbuf. 617In the case of former, the first argument for a free routine is the mbuf 618.Fa m 619and the routine is expected to free it in addition to the external storage 620pointed by second argument. 621In the case of latter, the first argument for the routine is NULL. 622.It Fn MCLGET "struct mbuf *m" "int how" 623Allocates and adds an mbuf cluster to a normal mbuf 624.Fa m . 625The 626.Fa how 627parameter is a choice of 628.Dv M_WAIT / M_DONTWAIT 629from caller. 630The flag 631.Dv M_EXT 632is set upon success. 633Implemented as a macro. 634.It Fn M_COPY_PKTHDR "struct mbuf *to" "struct mbuf *from" 635Copies the mbuf pkthdr from mbuf 636.Fa from 637to mbuf 638.Fa to . 639.Fa from 640must have the type flag 641.Dv M_PKTHDR 642set, and 643.Fa to 644must be empty. 645Implemented as a macro. 646.It Fn M_MOVE_PKTHDR "struct mbuf *to" "struct mbuf *from" 647Moves the mbuf pkthdr from mbuf 648.Fa from 649to mbuf 650.Fa to . 651.Fa from 652must have the type flag 653.Dv M_PKTHDR 654set, and 655.Fa to 656must be empty. 657The flag 658.Dv M_PKTHDR 659in mbuf 660.Fa from 661will be cleared. 662.It Fn M_ALIGN "struct mbuf *m" "int len" 663Sets the data pointer of a newly allocated mbuf 664.Fa m 665to 666.Fa len 667bytes from the end of the mbuf data area, so that 668.Fa len 669bytes of data written to the mbuf 670.Fa m , 671starting at the data pointer, will be aligned to the end of the data area. 672Implemented as a macro. 673.It Fn MH_ALIGN "struct mbuf *m" "int len" 674Sets the data pointer of a newly allocated packetheader mbuf 675.Fa m 676to 677.Fa len 678bytes from the end of the mbuf data area, so that 679.Fa len 680bytes of data written to the mbuf 681.Fa m , 682starting at the data pointer, will be aligned to the end of the data area. 683Implemented as a macro. 684.It Fn M_LEADINGSPACE "struct mbuf *m" 685Returns the amount of space available before the current start of valid 686data in mbuf 687.Fa m . 688Returns 0 if the mbuf data part is shared across multiple mbufs 689.Pq i.e. not writable . 690Implemented as a macro. 691.It Fn M_TRAILINGSPACE "struct mbuf *m" 692Returns the amount of space available after the current end of valid 693data in mbuf 694.Fa m . 695Returns 0 if the mbuf data part is shared across multiple mbufs 696.Pq i.e. not writable . 697Implemented as a macro. 698.It Fn M_PREPEND "struct mbuf *m" "int plen" "int how" 699Prepends space of size 700.Fa plen 701to mbuf 702.Fa m . 703If a new mbuf must be allocated, 704.Fa how 705specifies whether to wait. 706If 707.Fa how 708is 709.Dv M_DONTWAIT 710and allocation fails, the original mbuf chain is freed and 711.Fa m 712is set to 713.Dv NULL . 714Implemented as a macro. 715.It Fn MCHTYPE "struct mbuf *m" "int type" 716Change mbuf 717.Fa m 718to new type 719.Fa type . 720Implemented as a macro. 721.It Fn MEXTREMOVE "struct mbuf *m" 722Removes external storage from mbuf 723.Fa m . 724The flag 725.Dv M_EXT 726is removed. 727Implemented as a macro. 728.It Fn MFREE "struct mbuf *m" "struct mbuf *n" 729Frees a single mbuf 730.Fa m 731and places the successor, if any, in mbuf 732.Fa n . 733Implemented as a macro. 734.El 735.Sh FILES 736The 737.Nm 738management functions are implemented within the file 739.Pa sys/kern/uipc_mbuf.c . 740Function prototypes, and the functions implemented as macros 741are located in 742.Pa sys/sys/mbuf.h . 743Both pathnames are relative to the root of the 744.Nx 745source tree, 746.Pa /usr/src . 747.Sh SEE ALSO 748.Pa /usr/share/doc/smm/18.net , 749.Xr netstat 1 , 750.Xr m_tag 9 , 751.Xr malloc 9 752.Rs 753.%A Jun-ichiro Hagino 754.%T "Mbuf issues in 4.4BSD IPv6/IPsec support (experiences from KAME IPv6/IPsec implementation)" 755.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" 756.%D June 2000 757.Re 758.Sh AUTHORS 759.An -nosplit 760The original mbuf data structures were designed by Rob Gurwitz 761when he did the initial TCP/IP implementation at BBN. 762.br 763Further extensions and enhancements were made by Bill Joy, Sam Leffler, 764and Mike Karels at CSRG. 765.br 766Current implementation of external storage by 767.An Matt Thomas 768.Aq matt@3am-software.com 769and 770.An Jason R. Thorpe 771.Aq thorpej@NetBSD.org . 772