xref: /openbsd-src/share/man/man9/mbuf.9 (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1.\"     $OpenBSD: mbuf.9,v 1.120 2020/12/12 11:48:52 jan 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: December 12 2020 $
29.Dt MGET 9
30.Os
31.Sh NAME
32.Nm m_copym ,
33.Nm m_free ,
34.Nm m_get ,
35.Nm MGET ,
36.Nm m_getclr ,
37.Nm m_gethdr ,
38.Nm m_removehdr ,
39.Nm m_resethdr ,
40.Nm m_calchdrlen ,
41.Nm MGETHDR ,
42.Nm m_prepend ,
43.Nm M_PREPEND ,
44.Nm m_pulldown ,
45.Nm m_pullup ,
46.Nm m_split ,
47.Nm m_makespace ,
48.Nm m_getptr ,
49.Nm m_adj ,
50.Nm m_copyback ,
51.Nm m_defrag ,
52.Nm m_freem ,
53.Nm m_freemp ,
54.Nm m_purge ,
55.Nm m_reclaim ,
56.Nm m_copydata ,
57.Nm m_cat ,
58.Nm m_devget ,
59.Nm m_apply ,
60.Nm MCLGET ,
61.Nm MCLGETL ,
62.Nm MEXTADD ,
63.Nm m_align ,
64.Nm M_READONLY ,
65.Nm m_leadingspace ,
66.Nm m_trailingspace ,
67.Nm mtod ,
68.Nm m_dup_pkt ,
69.Nm m_dup_pkthdr
70.Nd kernel memory management for networking protocols
71.Sh SYNOPSIS
72.In sys/mbuf.h
73.Ft struct mbuf *
74.Fn m_copym "struct mbuf *m" "int off" "int len" "int wait"
75.Ft struct mbuf *
76.Fn m_free "struct mbuf *m"
77.Ft struct mbuf *
78.Fn m_get "int how" "int type"
79.Fn MGET "struct mbuf *m" "int how" "int type"
80.Ft struct mbuf *
81.Fn m_getclr "int how" "int type"
82.Ft void
83.Fn m_removehdr "struct mbuf *m"
84.Ft void
85.Fn m_resethdr "struct mbuf *m"
86.Ft void
87.Fn m_calchdrlen "struct mbuf *m"
88.Ft struct mbuf *
89.Fn m_gethdr "int how" "int type"
90.Fn MGETHDR "struct mbuf *m" "int how" "int type"
91.Ft struct mbuf *
92.Fn m_prepend "struct mbuf *m" "int len" "int how"
93.Fn M_PREPEND "struct mbuf *m" "int plen" "int how"
94.Ft struct mbuf *
95.Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp"
96.Ft struct mbuf *
97.Fn m_pullup "struct mbuf *n" "int len"
98.Ft struct mbuf *
99.Fn m_split "struct mbuf *m0" "int len0" "int wait"
100.Ft struct mbuf *
101.Fn m_makespace "struct mbuf *m0" "int skip" "int hlen" "int *off"
102.Ft struct mbuf *
103.Fn m_getptr "struct mbuf *m" "int loc" "int *off"
104.Ft void
105.Fn m_adj "struct mbuf *mp" "int req_len"
106.Ft int
107.Fn m_copyback "struct mbuf *m0" "int off" "int len" "const void *cp" "int wait"
108.Ft int
109.Fn m_defrag "struct mbuf *m" "int wait"
110.Ft struct mbuf *
111.Fn m_freem "struct mbuf *m"
112.Ft struct mbuf *
113.Fn m_freemp "struct mbuf **mp"
114.Ft void
115.Fn m_purge "struct mbuf *m"
116.Ft void
117.Fn m_reclaim "void"
118.Ft void
119.Fn m_copydata "struct mbuf *m" "int off" "int len" "caddr_t cp"
120.Ft void
121.Fn m_cat "struct mbuf *m" "struct mbuf *n"
122.Ft struct mbuf *
123.Fn m_devget "char *buf" "int totlen" "int off"
124.Ft int
125.Fn m_apply "struct mbuf *m" "int off" "int len" \
126"int (*func)(caddr_t, caddr_t, unsigned int)" "caddr_t fstate"
127.Fn MCLGET "struct mbuf *m" "int how"
128.Ft struct mbuf *
129.Fn MCLGETL "struct mbuf *m" "int how" "int len"
130.Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \
131"void (*free)(caddr_t, u_int, void *)" "void *arg"
132.Ft void
133.Fn m_align "struct mbuf *m" "int len"
134.Fn M_READONLY "struct mbuf *m"
135.Ft int
136.Fn m_leadingspace "struct mbuf *m"
137.Ft int
138.Fn m_trailingspace "struct mbuf *m"
139.Ft struct mbuf *
140.Fn m_dup_pkt "struct mbuf *m" "u_int adj" "int how"
141.Ft int
142.Fn m_dup_pkthdr "struct mbuf *to" "struct mbuf *from" "int how"
143.Bd -literal
144#define MSIZE           256
145
146#define MLEN            (MSIZE - sizeof(struct m_hdr))
147#define MHLEN           (MLEN - sizeof(struct pkthdr))
148
149#define MAXMCLBYTES     (64 * 1024)
150#define MINCLSIZE       (MHLEN + MLEN + 1)
151#define M_MAXCOMPRESS   (MHLEN / 2)
152
153#define MCLSHIFT        11
154
155#define MCLBYTES        (1 << MCLSHIFT)
156#define MCLOFSET        (MCLBYTES - 1)
157
158#define mtod(m,t)       ((t)((m)->m_data))
159
160struct m_hdr {
161        struct  mbuf *mh_next;
162        struct  mbuf *mh_nextpkt;
163        caddr_t mh_data;
164        u_int   mh_len;
165        short   mh_type;
166        u_short mh_flags;
167#ifndef __LP64__
168        u_int   mh_pad;
169#endif
170};
171
172struct pkthdr {
173	void			*ph_cookie;
174	SLIST_HEAD(, m_tag)	 ph_tags;
175	int64_t			 ph_timestamp;
176	int			 len;
177	u_int16_t		 ph_tagsset;
178	u_int16_t		 ph_flowid;
179	u_int16_t		 csum_flags;
180	u_int16_t		 ether_vtag;
181	u_int			 ph_rtableid;
182	u_int			 ph_ifidx;
183	u_int8_t		 ph_loopcnt;
184	struct pkthdr_pf	 pf;
185};
186
187struct pkthdr_pf {
188	struct pf_state_key *statekey;
189	struct inpcb *inp;
190	u_int32_t qid;
191	u_int16_t tag;
192	u_int8_t  flags;
193	u_int8_t  routed;
194	u_int8_t  prio;
195	u_int8_t  pad[3];
196};
197
198struct mbuf_ext {
199	caddr_t ext_buf;
200	void	*ext_arg;
201	u_int	ext_free_fn;
202	u_int   ext_size;
203	struct mbuf *ext_nextref;
204	struct mbuf *ext_prevref;
205};
206
207struct mbuf {
208        struct  m_hdr m_hdr;
209        union {
210                struct {
211                        struct  pkthdr MH_pkthdr;
212                        union {
213                                struct  mbuf_ext MH_ext;
214                                char    MH_databuf[MHLEN];
215                        } MH_dat;
216                } MH;
217                char    M_databuf[MLEN];
218        } M_dat;
219};
220
221#define m_next          m_hdr.mh_next
222#define m_len           m_hdr.mh_len
223#define m_data          m_hdr.mh_data
224#define m_type          m_hdr.mh_type
225#define m_flags         m_hdr.mh_flags
226#define m_nextpkt       m_hdr.mh_nextpkt
227#define m_pkthdr        M_dat.MH.MH_pkthdr
228#define m_ext           M_dat.MH.MH_dat.MH_ext
229#define m_pktdat        M_dat.MH.MH_dat.MH_databuf
230#define m_dat           M_dat.M_databuf
231.Ed
232.Sh DESCRIPTION
233The
234.Nm mbuf
235functions provide a way to manage the memory buffers used by the kernel's
236networking subsystem.
237Several functions and macros are used to allocate and deallocate mbufs,
238but also to get, inject, remove, copy, modify, prepend or append data
239inside these mbufs.
240The size of an
241.Nm mbuf
242is defined by MSIZE.
243.Pp
244An
245.Nm mbuf
246structure is defined as an
247.Fa m_hdr
248structure followed by a
249union.
250The header contains the following elements:
251.Bl -tag -width foobarmoocow
252.It Fa mh_next
253A pointer to the next mbuf in the mbuf chain.
254.It Fa mh_nextpkt
255A pointer to the next mbuf chain (i.e., packet) in the queue.
256.It Fa mh_data
257Indicates the address of the beginning of data in the mbuf.
258.It Fa mh_len
259Indicates the amount of data in the mbuf.
260.It Fa mh_type
261Indicates the type of data contained in the mbuf (see below).
262.It Fa mh_flags
263Flags (see below).
264.El
265.Pp
266The
267.Fa mh_type
268variable can take the following values:
269.Pp
270.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX
271.It Dv MT_FREE
272the mbuf should be on the free list.
273.It Dv MT_DATA
274the data in the mbuf was dynamically allocated.
275.It Dv MT_HEADER
276the data contains a packet header.
277.It Dv MT_SONAME
278the data is a socket name.
279.It Dv MT_SOOPTS
280the data are socket options.
281.It Dv MT_FTABLE
282the data is a fragment reassembly header.
283.It Dv MT_CONTROL
284the mbuf contains extra-data protocol message.
285.It Dv MT_OOBDATA
286the data consists of out-of-band data.
287.El
288.Pp
289The
290.Fa mh_flags
291variable can take the following values:
292.Pp
293.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX
294.It Dv M_EXT
295mbuf has associated external storage.
296.It Dv M_PKTHDR
297the mbuf is the first that forms a packet.
298.It Dv M_EOR
299end of record.
300.It Dv M_EXTWR
301external storage is writable.
302.It Dv M_PROTO1
303protocol-specific.
304.It Dv M_VLANTAG
305.Fa m_pkthdr.ether_vtag
306variable is valid.
307.It Dv M_LOOP
308packet has been sent from local machine.
309.It Dv M_BCAST
310packet sent/received as link-level broadcast.
311.It Dv M_MCAST
312packet sent/received as link-level multicast.
313.It Dv M_CONF
314packet was encrypted (ESP-transport).
315.It Dv M_AUTH
316packet was authenticated (AH or ESP).
317.It Dv M_TUNNEL
318header was IP-in-IP encapsulated by tunnel mode IPsec.
319.It Dv M_ZEROIZE
320Zero the data part of the mbufs in the mbuf chain pointed to by
321.Nm m_free .
322.It Dv M_COMP
323header was decompressed.
324.It Dv M_LINK0
325link layer specific flag.
326.El
327.Pp
328An external cluster is used when the data to hold in the mbuf is
329large.
330The size of an external cluster is between MCLBYTES and MAXMCLBYTES.
331A cluster should be used when the size of the data reach MINCLSIZE
332(the minimum size to be held by an external cluster).
333.Pp
334The combination of the M_EXT and M_PKTHDR flags give four types of
335mbuf.
336When none of these constants are in use, the mbuf is a "normal"
337one, where the data part of the mbuf has the following elements:
338.Bl -tag -width foobarmoocow
339.It Fa m_dat
340buffer holding the data (size MLEN).
341.El
342.Pp
343When only M_PKTHDR is set, the data contained in the mbuf is a packet header.
344The data itself is contained in the mbuf (just like the previous case),
345but part of the mbuf is used to store a packet header.
346The data part has then the following elements:
347.Bl -tag -width foobarmoocow
348.It Fa m_pkthdr
349packet header, containing the length of the data, a pointer to the
350interface on which the data was received, checksum information
351and list of
352.Xr mbuf_tags 9 .
353.It Fa m_pktdat
354buffer holding the data (size MHLEN).
355.El
356.Pp
357The
358.Fa m_pkthdr.csum_flags
359variable can take the following values:
360.Pp
361.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX
362.It Dv M_IPV4_CSUM_OUT
363IPv4 checksum needed.
364.It Dv M_TCP_CSUM_OUT
365TCP checksum needed.
366.It Dv M_UDP_CSUM_OUT
367UDP checksum needed.
368.It Dv M_ICMP_CSUM_OUT
369ICMP/ICMPv6 checksum needed.
370.It Dv M_IPV4_CSUM_IN_OK
371IPv4 checksum verified.
372.It Dv M_IPV4_CSUM_IN_BAD
373IPv4 checksum bad.
374.It Dv M_TCP_CSUM_IN_OK
375TCP checksum verified.
376.It Dv M_TCP_CSUM_IN_BAD
377TCP checksum bad.
378.It Dv M_UDP_CSUM_IN_OK
379UDP checksum verified.
380.It Dv M_UDP_CSUM_IN_BAD
381UDP checksum bad.
382.It Dv M_ICMP_CSUM_IN_OK
383ICMP/ICMPv6 checksum verified.
384.It Dv M_ICMP_CSUM_IN_BAD
385ICMP/ICMPv6 checksum bad.
386.It Dv M_IPV6_DF_OUT
387Do not fragment IPv6 on output.
388.El
389.Pp
390The
391.Fa m_pkthdr.flowid
392variable can contain a low resolution (15-bit) classification of a
393flow or connection that the current mbuf is part of.
394If the flowid is valid, it may be used as an alternative to hashing
395the packets content to pick between different paths for the traffic.
396The following masks can be ORed with the flowid:
397.Pp
398.Bl -tag -compact -offset indent -width XXXXXXXXXXXXXXXXXX
399.It Dv M_FLOWID_VALID
400The flow ID has been set.
401.It Dv M_FLOWID_MASK
402The flow ID.
403.El
404.Pp
405When only M_EXT flag is set, an external storage buffer is being used to
406hold the data, which is no longer stored in the mbuf.
407The data part of the mbuf has now the following elements:
408.Bl -tag -width foobarmoocow
409.It Fa m_pkthdr
410a packet header, just like the previous case, but it is empty.
411No information is stored here.
412.It Fa m_ext
413a structure containing information about the external storage
414buffer.
415The information consists of the address of the external buffer,
416a pointer to the function used to free the buffer, a pointer to the
417arguments of the function, the size of the buffer, the type of the
418buffer, and pointers to the previous and next mbufs using this
419cluster.
420.El
421.Pp
422When both the M_EXT and M_PKTHDR flags are set, an external storage buffer
423is being used to store the data and this data contains a packet header.
424The structure used is the same as the previous one except that the
425.Fa m_pkthdr
426element is not empty, it contains the same information as when
427M_PKTHDR is used alone.
428.Bl -tag -width Ds
429.It Fn m_copym "struct mbuf *m" "int off" "int len" "int wait"
430Copy an mbuf chain starting at
431.Fa off
432bytes from the beginning
433and continuing for
434.Fa len
435bytes.
436If
437.Fa off
438is zero and
439.Fa m
440has the M_PKTHDR flag set,
441the header is copied.
442If
443.Fa len
444is M_COPYALL
445the whole mbuf is copied.
446The
447.Fa wait
448parameter can be M_WAIT or
449M_DONTWAIT.
450It does not copy clusters, it just increases their reference count.
451.It Fn m_free "struct mbuf *m"
452Free the mbuf pointed to by
453.Fa m .
454A pointer to the successor of the mbuf,
455if it exists, is returned by the function.
456If
457.Fa m
458is a
459.Dv NULL
460pointer, no action occurs and
461.Dv NULL
462is returned.
463.It Fn m_get "int how" "int type"
464Return a pointer to an mbuf of the type specified.
465If the
466.Fa how
467argument is
468.Fa M_WAITOK ,
469the function may call
470.Xr tsleep 9
471to await resources.
472If
473.Fa how
474is
475.Fa M_DONTWAIT
476and resources are not available,
477.Fn m_get
478returns NULL.
479.It Fn MGET "struct mbuf *m" "int how" "int type"
480Return a pointer to an mbuf in
481.Fa m
482of the type specified.
483See
484.Fn m_get
485for a description of
486.Fa how .
487.It Fn m_getclr "int how" "int type"
488Return a pointer to an mbuf of the type specified, and clear the data
489area of the mbuf.
490See
491.Fn m_get
492for a description of
493.Fa how .
494.It Fn m_removehdr "struct mbuf *m"
495Convert an mbuf with packet header to one without.
496Delete all
497.Xr pf 4
498data and all tags attached to an
499.Fa mbuf .
500Keep the data and mbuf chain, clear the packet header.
501.It Fn m_resethdr "struct mbuf *m"
502Delete all
503.Xr pf 4
504data and all tags attached to an
505.Fa mbuf .
506Keep the data and mbuf chain, initialize the packet header.
507.It Fn m_calchdrlen "struct mbuf *m"
508Set the packet header length to the sum of all length values in the
509mbuf chain.
510.It Fn m_gethdr "int how" "int type"
511Return a pointer to an mbuf of the type specified after initializing
512it to contain a packet header.
513See
514.Fn m_get
515for a description of
516.Fa how .
517.It Fn MGETHDR "struct mbuf *m" "int how" "int type"
518Return a pointer to an mbuf of the type specified after initializing
519it to contain a packet header.
520See
521.Fn m_get
522for a description of
523.Fa how .
524.It Fn m_prepend "struct mbuf *m" "int len" "int how"
525Prepend space of size
526.Fa plen
527to the mbuf pointed to by
528.Fa m .
529If necessary allocate a new mbuf and prepend it to the mbuf chain pointed to by
530.Fa m .
531If
532.Fa m
533points to an mbuf with a packet header, it is moved to the new
534mbuf that has been prepended.
535The return value is a pointer on the new mbuf chain.
536If this function fails to allocate a new mbuf,
537.Fa m
538is freed.
539See
540.Fn m_get
541for a description of
542.Fa how .
543.It Fn M_PREPEND "struct mbuf *m" "int plen" "int how"
544Prepend space of size
545.Fa plen
546to the mbuf pointed to by
547.Fa m .
548If a new mbuf must be allocated,
549.Fa how
550specifies whether to wait or not.
551If this function fails to allocate a new mbuf,
552.Fa m
553is freed.
554.It Fn m_pulldown "struct mbuf *m" "int off" "int len" "int *offp"
555Ensure that the data in the mbuf chain starting at
556.Fa off
557and ending at
558.Fa off+len
559will be put in a continuous memory region.
560If memory must be allocated, then it will fail if the
561.Fa len
562argument is greater than MAXMCLBYTES.
563The pointer returned points to an mbuf in the chain and the new offset
564for data in this mbuf is
565.Fa *offp .
566If this function fails,
567.Fa m
568is freed.
569.It Fn m_pullup "struct mbuf *n" "int len"
570Ensure that the data in the mbuf chain starting at the beginning of
571the chain and ending at
572.Fa len
573will be put in continuous memory region.
574If memory must be allocated, then it will fail if the
575.Fa len
576argument is greater than MAXMCLBYTES.
577If this function fails,
578.Fa n
579is freed.
580.It Fn m_split "struct mbuf *m0" "int len0" "int wait"
581Split an mbuf chain in two pieces, returning a pointer to
582the tail (which is made of the previous mbuf chain except the first
583.Fa len0
584bytes).
585.It Fn m_makespace "struct mbuf *m0" "int skip" "int hlen" "int *off"
586Make space for a continuous memory region of length
587.Fa hlen
588at
589.Fa skip
590bytes into the mbuf chain.
591On success, the mbuf of the continuous memory is returned
592together with an offset
593.Fa off
594into the mbuf.
595On failure, NULL is returned and the mbuf chain may have been modified.
596The caller is assumed to always free the chain.
597.It Fn m_getptr "struct mbuf *m" "int loc" "int *off"
598Returns a pointer to the mbuf containing the data located at
599.Fa loc
600bytes of the beginning.
601The offset in the new mbuf is pointed to by
602.Fa off .
603.It Fn m_adj "struct mbuf *mp" "int req_len"
604Trims
605.Fa req_len
606bytes of data from the mbuf chain pointed to by
607.Fa mp .
608If
609.Fa req_len
610is positive, the data will be trimmed from the head of the mbuf chain
611and if it is negative, it will be trimmed from the tail of the mbuf
612chain.
613.It Fn m_copyback "struct mbuf *m0" "int off" "int len" "caddr_t cp" "int wait"
614Copy data from a buffer pointed to by
615.Fa cp
616back into the mbuf chain pointed to by
617.Fa m0
618starting at
619.Fa off
620bytes from the beginning, extending the mbuf chain if
621necessary, sleeping for mbufs if
622.Fa wait
623is
624.Fa M_WAIT .
625If
626.Fa M_NOWAIT
627is set and no mbufs are available,
628.Fn m_copyback
629returns
630.Er ENOBUFS .
631The mbuf chain must be initialized properly, including setting
632.Fa m_len .
633.It Fn m_defrag "struct mbuf *m" "int wait"
634Defragment the data mbufs referenced by
635.Fa m
636by replacing the chain with a copy of their contents made into a
637single mbuf or cluster.
638.Fa wait
639specifies whether it can wait or not for the replacement storage.
640.Fn m_defrag
641returns 0 on success or
642.Er ENOBUFS
643on failure.
644The mbuf pointer
645.Fa m
646remains in existence and unchanged on failure.
647.It Fn m_freem "struct mbuf *m"
648Free the mbuf chain pointed to by
649.Fa m .
650A pointer to the next mbuf in the list linked by m_nextpkt,
651if it exists, is returned by the function.
652If
653.Fa m
654is a
655.Dv NULL
656pointer, no action occurs and
657.Dv NULL
658is returned.
659.It Fn m_freemp "struct mbuf **mp"
660Set the input mbuf pointer to
661.Dv NULL
662and call
663.Fn m_freem .
664.It Fn m_purge "struct mbuf *m"
665Free the list of mbufs linked by m_nextpkt that is pointed to by
666.Fa m .
667Each mbuf is freed by a call to
668.Fn m_freem .
669If
670.Fa m
671is a
672.Dv NULL
673pointer, no action occurs.
674.It Fn m_reclaim "void"
675Ask protocols to free unused memory space.
676.It Fn m_copydata "struct mbuf *m" "int off" "int len" "caddr_t cp"
677Copy data from the mbuf chain pointed to by
678.Fa m
679starting at
680.Fa off
681bytes from the beginning and continuing for
682.Fa len
683bytes into the buffer pointed to by
684.Fa cp .
685.It Fn m_cat "struct mbuf *m" "struct mbuf *n"
686Concatenate the mbuf chain pointed to by
687.Fa n
688to the mbuf chain pointed to by
689.Fa m .
690The mbuf chains must be of the same type.
691.It Fn m_devget "char *buf" "int totlen" "int off"
692Copy
693.Fa totlen
694bytes of data from device local memory pointed to by
695.Fa buf .
696The data is copied into an mbuf chain at offset
697.Fa off
698and a pointer to the head of the chain is returned.
699Returns NULL on failure.
700.It Fn m_apply "struct mbuf *m" "int off" "int len" \
701"int (*func)(caddr_t, caddr_t, unsigned int)" "caddr_t fstate"
702Apply the function
703.Fa func
704to the data in the mbuf chain pointed to by
705.Fa m
706starting at
707.Fa off
708bytes from the beginning and continuing for
709.Fa len
710bytes.
711.It Fn mtod "struct mbuf *m" "datatype"
712Return a pointer to the data contained in the specified mbuf
713.Fa m
714cast to
715.Fa datatype .
716.It Fn MCLGET "struct mbuf *m" "int how"
717Allocate and add an mbuf cluster to the mbuf pointed to by
718.Fa m .
719On success, the flag M_EXT is set in the mbuf.
720See
721.Fn m_get
722for a description of
723.Fa how .
724.It Fn MCLGETL "struct mbuf *m" "int how" "int len"
725If
726.Fa m
727is NULL, allocate it.
728Then allocate and add an mbuf cluster of length
729.Fa len
730to the mbuf pointed to by
731.Fa m .
732Returns either the mbuf
733.Fa m
734that was passed in, or the newly allocated one which was allocated; in
735either case the flag M_EXT is set in the mbuf.
736See
737.Fn m_get
738for a description of
739.Fa how .
740.It Fn MEXTADD "struct mbuf *m" "caddr_t buf" "u_int size" "int flags" \
741"void (*free)(caddr_t, u_int, void *)" "void *arg"
742Add pre-allocated storage to the mbuf pointed to by
743.Fa m .
744On success, the flag M_EXT is set in the mbuf, and M_EXTWR is specified in
745.Fa flags .
746.It Fn m_align "struct mbuf *m" "int len"
747Set the
748.Fa m_data
749pointer of the newly allocated mbuf
750.Fa m
751to an object of the specified size
752.Fa len
753at the end of this mbuf data area, longword aligned.
754.It Fn M_READONLY "struct mbuf *m"
755Check if the data of the mbuf pointed to by
756.Fa m
757is read-only.
758This is true for non-cluster external storage and for clusters that
759are being referenced by more than one mbuf.
760.It Fn m_leadingspace "struct mbuf *m"
761Compute the amount of space available before the current start of data
762in the mbuf pointed to by
763.Fa m .
764If the data of the mbuf pointed to by
765.Fa m
766is read-only then 0 is returned.
767.It Fn m_trailingspace "struct mbuf *m"
768Compute the amount of space available after the end of data in the
769mbuf pointed to by
770.Fa m .
771If the data of the mbuf pointed to by
772.Fa m
773is read-only then 0 is returned.
774.It Fn m_dup_pkt "struct mbuf *m" "u_int adj" "int how"
775Allocate a new mbuf and storage and copy the packet data and header,
776including mbuf tags, from
777.Fa m .
778The data in the new mbuf will be offset from the start of the storage by
779.Fa adj
780bytes.
781See
782.Fn m_get
783for a description of
784.Fa how .
785.It Fn m_dup_pkthdr "struct mbuf *to" "struct mbuf *from" "int how"
786Copy mbuf packet header, including mbuf tags, from
787.Fa from
788to
789.Fa to .
790See
791.Fn m_get
792for a description of
793.Fa how .
794.El
795.Sh CODE REFERENCES
796The mbuf management functions are implemented in the files
797.Pa sys/kern/uipc_mbuf.c
798and
799.Pa sys/kern/uipc_mbuf2.c .
800The function prototypes and the macros are located in
801.Pa sys/sys/mbuf.h .
802.Sh SEE ALSO
803.Xr netstat 1 ,
804.Xr mbuf_tags 9 ,
805.Xr mutex 9 ,
806.Xr spl 9
807.Rs
808.%A Jun-Ichiro Hagino
809.%T "Mbuf issues in 4.4BSD IPv6/IPsec support (experiences from KAME IPv6/IPsec implementation)"
810.%B "Proceedings of the Freenix Track: 2000 USENIX Annual Technical Conference"
811.%D June 2000
812.Re
813