NAME
mbuf
, m_get
,
m_gethdr
, m_devget
,
m_copym
, m_copypacket
,
m_copydata
, m_copyback
,
m_copyback_cow
, m_cat
,
m_dup
, m_makewritable
,
m_pulldown
, m_pullup
,
m_copyup
, m_split
,
m_adj
, m_apply
,
m_free
, m_freem
,
mtod
, MGET
,
MGETHDR
, MEXTMALLOC
,
MEXTADD
, MCLGET
,
m_copy_pkthdr
,
m_move_pkthdr
,
m_remove_pkthdr
, m_align
,
M_LEADINGSPACE
,
M_TRAILINGSPACE
, M_PREPEND
,
MCHTYPE
—
functions and macros for managing
memory used by networking code
SYNOPSIS
#include
<sys/mbuf.h>
struct mbuf *
m_get
(int
how, int type);
struct mbuf *
m_gethdr
(int
how, int type);
struct mbuf *
m_devget
(char
*buf, int totlen,
int off,
struct ifnet *ifp);
struct mbuf *
m_copym
(struct
mbuf *m, int off,
int len,
int wait);
struct mbuf *
m_copypacket
(struct
mbuf *m, int
how);
void
m_copydata
(struct
mbuf *m, int off,
int len,
void *cp);
void
m_copyback
(struct
mbuf *m0, int off,
int len,
void *cp);
struct mbuf *
m_copyback_cow
(struct
mbuf *m0, int off,
int len,
void *cp,
int how);
int
m_makewritable
(struct
mbuf **mp, int off,
int len,
int how);
void
m_cat
(struct
mbuf *m, struct mbuf
*n);
struct mbuf *
m_dup
(struct
mbuf *m, int off,
int len,
int wait);
struct mbuf *
m_pulldown
(struct
mbuf *m, int off,
int len,
int *offp);
struct mbuf *
m_pullup
(struct
mbuf *n, int
len);
struct mbuf *
m_copyup
(struct
mbuf *m, int len,
int dstoff);
struct mbuf *
m_split
(struct
mbuf *m0, int len,
int wait);
void
m_adj
(struct
mbuf *mp, int
req_len);
int
m_apply
(struct
mbuf *m, int off,
int len,
int *f(void *, void *, unsigned
int), void
*arg);
struct mbuf *
m_free
(struct
mbuf *m);
void
m_freem
(struct
mbuf *m);
datatype
mtod
(struct
mbuf *m,
datatype);
void
MGET
(struct
mbuf *m, int how,
int type);
void
MGETHDR
(struct
mbuf *m, int how,
int type);
void
MEXTMALLOC
(struct
mbuf *m, int len,
int how);
void
MEXTADD
(struct
mbuf *m, void *buf,
int size,
int type,
void (*free)(struct mbuf *,
void *, size_t, void *),
void *arg);
void
MCLGET
(struct
mbuf *m, int
how);
void
m_copy_pkthdr
(struct
mbuf *to, struct mbuf
*from);
void
m_move_pkthdr
(struct
mbuf *to, struct mbuf
*from);
void
m_remove_pkthdr
(struct
mbuf *m);
void
m_align
(struct
mbuf *m, int
len);
int
M_LEADINGSPACE
(struct
mbuf *m);
int
M_TRAILINGSPACE
(struct
mbuf *m);
void
M_PREPEND
(struct
mbuf *m, int plen,
int how);
void
MCHTYPE
(struct
mbuf *m, int
type);
DESCRIPTION
Thembuf
functions and macros provide an easy and
consistent way to handle a networking stack's memory management needs. An
mbuf
consists of a header and a data area. It is of a
fixed size, MSIZE
(defined in
⟨machine/param.h⟩), which includes the
size of the header. The header contains a pointer to the next
mbuf
in the ‘mbuf chain’, a pointer to
the next ‘mbuf chain’, a pointer to the data area, the amount of
data in this mbuf, its type and a flags
field.
The type
variable can signify:
MT_FREE
- the mbuf should be on the ``free'' list
MT_DATA
- data was dynamically allocated
MT_HEADER
- data is a packet header
MT_SONAME
- data is a socket name
MT_SOOPTS
- data is socket options
MT_FTABLE
- data is the fragment reassembly header
MT_CONTROL
- mbuf contains ancillary (protocol control) data
MT_OOBDATA
- mbuf contains out-of-band data.
The flags
variable contains information
describing the mbuf
, notably:
If an mbuf
designates the start of a
record (M_PKTHDR
), its flags
field may contain additional information describing the content of the
record:
An mbuf
may add a single ‘mbuf
cluster’ of MCLBYTES
bytes (defined in
⟨machine/param.h⟩), which has no
additional overhead and is used instead of the internal data area; this is
done when at least MINCLSIZE
bytes of data must be
stored.
When the M_EXT
flag is set on an mbuf, the
external storage area could be shared among multiple mbufs. Therefore, care
must be taken when overwriting the data content of an mbuf, because its
external storage could be considered as read-only.
m_get
(int how, int type)- Allocates an mbuf and initializes it to contain internal data. The
how parameter is a choice of
M_WAIT / M_DONTWAIT
from caller.M_WAIT
means the call cannot fail, but may take forever. The type parameter is an mbuf type. m_gethdr
(int how, int type)- Allocates an mbuf and initializes it to contain a packet header and
internal data. The how parameter is a choice of
M_WAIT / M_DONTWAIT
from caller. The type parameter is an mbuf type. m_devget
(char *buf, int totlen, int off, struct ifnet *ifp)- Copies len bytes from device local memory into mbufs. If parameter off is non-zero, the packet is supposed to be trailer-encapsulated and off bytes plus the type and length fields will be skipped before copying. Returns the top of the mbuf chain it created.
m_copym
(struct mbuf *m, int off, int len, int wait)- Creates a copy of an mbuf chain starting off bytes
from the beginning, continuing for len bytes. If the
len requested is
M_COPYALL
, the complete mbuf chain will be copied. The wait parameter is a choice ofM_WAIT / M_DONTWAIT
from caller. m_copypacket
(struct mbuf *m, int how)- Copies an entire packet, including header. This function is an
optimization of the common case
m_copym
(m
,0
,M_COPYALL
, how). However, contrary tom_copym
(), a header must be present. It is incorrect to usem_copypacket
() with an mbuf that does not have a header. m_copydata
(struct mbuf *m, int off, int len, void *cp)- Copies len bytes data from mbuf chain m into the buffer cp, starting off bytes from the beginning.
m_copyback
(struct mbuf *m0, int off, int len, void *cp)- Copies len bytes data from buffer
cp back into the mbuf chain
m0, starting off bytes from
the beginning of the chain, extending the mbuf chain if necessary.
m_copyback
() can only fail when extending the chain. The caller should check for this kind of failure by checking the resulting length of the chain in that case. It is an error to usem_copyback
() on read-only mbufs. m_copyback_cow
(struct mbuf *m0, int off, int len, void *cp, int how)- Copies len bytes data from buffer
cp back into the mbuf chain m0
as
m_copyback
() does. Unlikem_copyback
(), it is safe to usem_copyback_cow
() on read-only mbufs. If needed,m_copyback_cow
() automatically allocates new mbufs and adjusts the chain. On success, it returns a pointer to the resulting mbuf chain, and frees the original mbuf m0. Otherwise, it returnsNULL
. The how parameter is a choice ofM_WAIT / M_DONTWAIT
from the caller. Unlikem_copyback
(), extending the mbuf chain isn't supported. It is an error to attempt to extend the mbuf chain usingm_copyback_cow
(). m_makewritable
(struct mbuf **mp, int off, int len, int how)- Rearranges an mbuf chain so that len bytes from
offset off are writable. When it meets read-only
mbufs, it allocates new mbufs, adjusts the chain as
m_copyback_cow
() does, and copies the original content into them.m_makewritable
() does not guarantee that all len bytes at off are consecutive. The how parameter is a choice ofM_WAIT / M_DONTWAIT
from the caller.m_makewritable
() preserves the contents of the mbuf chain even in the case of failure. It updates a pointer to the mbuf chain pointed to by mp. It returns 0 on success. Otherwise, it returns an error code, typicallyENOBUFS
. m_cat
(struct mbuf *m, struct mbuf *n)- Concatenates mbuf chain n to m. Both chains must be of the same type; packet headers will not be updated if present.
m_dup
(struct mbuf *m, int off, int len, int wait)- Similarly to
m_copym
(), the function creates a copy of an mbuf chain starting off bytes from the beginning, continuing for len bytes. Whilem_copym
() tries to share external storage for mbufs withM_EXT
flag,m_dup
() will deep-copy the whole data content into new mbuf chain and avoids shared external storage. m_pulldown
(struct mbuf *m, int off, int len, int *offp)- Rearranges an mbuf chain so that len bytes from
offset off are contiguous and in the data area of an
mbuf. The return value points to an mbuf in the middle of the mbuf chain
m. If we call the return value
n, the contiguous data region is available at
mtod(n, void *) + *offp
, ormtod(n, void *)
if offp isNULL
. The top of the mbuf chain m, and mbufs up to off, will not be modified. On successful return, it is guaranteed that the mbuf pointed to by n does not have a shared external storage, therefore it is safe to update the contiguous region. ReturnsNULL
and frees the mbuf chain on failure. len must be smaller than or equal toMCLBYTES
. m_pullup
(struct mbuf *m, int len)- Rearranges an mbuf chain so that len bytes are
contiguous and in the data area of an mbuf (so that
mtod
() will work for a structure of size len). Returns the resulting mbuf chain on success, frees it and returnsNULL
on failure. If there is room, it will add up tomax_protohdr
- len extra bytes to the contiguous region to possibly avoid being called again. len must be smaller or equal thanMHLEN
. m_copyup
(struct mbuf *m, int len, int dstoff)- Similar to
m_pullup
() but copies len bytes of data into a new mbuf at dstoff bytes into the mbuf. The dstoff argument aligns the data and leaves room for a link layer header. Returns the new mbuf chain on success, and frees the mbuf chain and returnsNULL
on failure. Note that the function does not allocate mbuf clusters, so len + dstoff must be less thanMHLEN
. m_split
(struct mbuf *m0, int len, int wait)- Partitions an mbuf chain in two pieces, returning the tail, which is all
but the first len bytes. In case of failure, it
returns
NULL
and restores the chain to its original state. m_adj
(struct mbuf *mp, int req_len)- Shaves off req_len bytes from head or tail of the (valid) data area. If req_len is greater than zero, front bytes are being shaved off, if it's smaller, from the back (and if it is zero, the mbuf will stay bearded). This function does not move data in any way, but is used to manipulate the data area pointer and data length variable of the mbuf in a non-clobbering way.
m_apply
(struct mbuf *m, int off, int len, int (*f)(void *, void *, unsigned int), void *arg)- Apply function f to the data in an mbuf chain
starting off bytes from the beginning, continuing
for len bytes. Neither off nor
len may be negative. arg will
be supplied as first argument for f, the second
argument will be the pointer to the data buffer of a packet (starting
after off bytes in the stream), and the third
argument is the amount of data in bytes in this call. If
f returns something not equal to zero
m_apply
() will bail out, returning the return code of f. Upon successful completion it will return zero. m_free
(struct mbuf *m)- Frees mbuf m.
m_freem
(struct mbuf *m)- Frees the mbuf chain beginning with m. This function
contains the elementary sanity check for a
NULL
pointer. mtod
(struct mbuf *m, datatype)- Returns a pointer to the data contained in the specified mbuf m, type-casted to the specified data type datatype.
MGET
(struct mbuf *m, int how, int type)- Allocates mbuf m and initializes it to contain
internal data. See
m_get
(). MGETHDR
(struct mbuf *m, int how, int type)- Allocates mbuf m and initializes it to contain a
packet header. See
m_gethdr
(). MEXTMALLOC
(struct mbuf *m, int len, int how)- Allocates external storage of size len for mbuf
m. The how parameter is a
choice of
M_WAIT / M_DONTWAIT
from caller. The flagM_EXT
is set upon success. MEXTADD
(struct mbuf *m, void *buf, int size, int type, void (*free)(struct mbuf *, void *, size_t, void *), void *arg)- Adds pre-allocated external storage buf to a normal
mbuf m; the parameters size,
type, free and
arg describe the external storage.
size is the size of the storage,
type describes its
malloc(9) type, free is a free routine (if
not the usual one), and arg is a possible argument
to the free routine. The flag
M_EXT
is set upon success. If a free routine is specified, it will be called when the mbuf is freed. In the case of former, the first argument for a free routine is the mbuf m and the routine is expected to free it in addition to the external storage pointed by second argument. In the case of latter, the first argument for the routine is NULL. MCLGET
(struct mbuf *m, int how)- Allocates and adds an mbuf cluster to a normal mbuf
m. The how parameter is a
choice of
M_WAIT / M_DONTWAIT
from caller. The flagM_EXT
is set upon success. m_copy_pkthdr
(struct mbuf *to, struct mbuf *from)- Copies the mbuf pkthdr from mbuf from to mbuf
to. from must have the type
flag
M_PKTHDR
set, and to must be empty. m_move_pkthdr
(struct mbuf *to, struct mbuf *from)- Moves the mbuf pkthdr from mbuf from to mbuf
to. from must have the type
flag
M_PKTHDR
set, and to must be empty. The flagM_PKTHDR
in mbuf from will be cleared. m_remove_pkthdr
(struct mbuf *m)- Removes the mbuf pkthdr from mbuf m.
m must have the flag
M_PKTHDR
set. This flag will be cleared. m_align
(struct mbuf *m, int len)- Sets the data pointer of a newly allocated mbuf m to len bytes from the end of the mbuf data area, so that len bytes of data written to the mbuf m, starting at the data pointer, will be aligned to the end of the data area.
M_LEADINGSPACE
(struct mbuf *m)- Returns the amount of space available before the current start of valid data in mbuf m. Returns 0 if the mbuf data part is shared across multiple mbufs (i.e. not writable).
M_TRAILINGSPACE
(struct mbuf *m)- Returns the amount of space available after the current end of valid data in mbuf m. Returns 0 if the mbuf data part is shared across multiple mbufs (i.e. not writable).
M_PREPEND
(struct mbuf *m, int plen, int how)- Prepends space of size plen to mbuf
m. If a new mbuf must be allocated,
how specifies whether to wait. If
how is
M_DONTWAIT
and allocation fails, the original mbuf chain is freed and m is set toNULL
. It is illegal for the plen parameter to be greater thanMHLEN
. MCHTYPE
(struct mbuf *m, int type)- Change mbuf m to new type type.
CODE REFERENCES
The mbuf
management functions are
implemented within the file sys/kern/uipc_mbuf.c.
Function prototypes, and the functions implemented as macros are located in
sys/sys/mbuf.h.
SEE ALSO
/usr/share/doc/smm/18.net, netstat(1), m_tag(9), malloc(9)
Jun-ichiro Hagino, Mbuf issues in 4.4BSD IPv6/IPsec support (experiences from KAME IPv6/IPsec implementation), Proceedings of the freenix track: 2000 USENIX annual technical conference, June 2000.
AUTHORS
The original mbuf data structures were designed by Rob Gurwitz when he did the initial TCP/IP implementation at BBN.
Further extensions and enhancements were made by Bill Joy, Sam Leffler, and Mike Karels at CSRG.
Current implementation of external storage by Matt Thomas ⟨matt@3am-software.com⟩ and Jason R. Thorpe ⟨thorpej@NetBSD.org⟩.