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