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