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