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