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