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