MGET(9) | Kernel Developer's Manual | MGET(9) |
m_copym
, m_free
,
m_get
, MGET
,
m_getclr
, m_gethdr
,
m_removehdr
, m_resethdr
,
m_calchdrlen
, MGETHDR
,
m_prepend
, M_PREPEND
,
m_pulldown
, m_pullup
,
m_split
, m_makespace
,
m_getptr
, m_adj
,
m_copyback
, m_defrag
,
m_freem
, m_freemp
,
m_purge
, m_reclaim
,
m_copydata
, m_cat
,
m_devget
, m_apply
,
MCLGET
, MCLGETI
,
MEXTADD
, m_align
,
M_READONLY
, m_leadingspace
,
m_trailingspace
, mtod
,
m_dup_pkt
, m_dup_pkthdr
— kernel memory management for networking
protocols
#include
<sys/mbuf.h>
struct mbuf *
m_copym
(struct
mbuf *m, int off,
int len,
int wait);
struct mbuf *
m_free
(struct
mbuf *m);
struct mbuf *
m_get
(int
how, int type);
MGET
(struct
mbuf *m, int how,
int type);
struct mbuf *
m_getclr
(int
how, int type);
void
m_removehdr
(struct
mbuf *m);
void
m_resethdr
(struct
mbuf *m);
void
m_calchdrlen
(struct
mbuf *m);
struct mbuf *
m_gethdr
(int
how, int type);
MGETHDR
(struct
mbuf *m, int how,
int type);
struct mbuf *
m_prepend
(struct
mbuf *m, int len,
int how);
M_PREPEND
(struct
mbuf *m, int plen,
int how);
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_split
(struct
mbuf *m0, int len0,
int wait);
struct mbuf *
m_makespace
(struct
mbuf *m0, int skip,
int hlen,
int *off);
struct mbuf *
m_getptr
(struct
mbuf *m, int loc,
int *off);
void
m_adj
(struct
mbuf *mp, int
req_len);
int
m_copyback
(struct
mbuf *m0, int off,
int len,
const void *cp,
int wait);
int
m_defrag
(struct
mbuf *m, int
wait);
struct mbuf *
m_freem
(struct
mbuf *m);
struct mbuf *
m_freemp
(struct
mbuf **mp);
void
m_purge
(struct
mbuf *m);
void
m_reclaim
(void);
void
m_copydata
(struct
mbuf *m, int off,
int len,
caddr_t cp);
void
m_cat
(struct
mbuf *m, struct mbuf
*n);
struct mbuf *
m_devget
(char
*buf, int totlen,
int off);
int
m_apply
(struct
mbuf *m, int off,
int len,
int (*func)(caddr_t, caddr_t,
unsigned int), caddr_t
fstate);
MCLGET
(struct
mbuf *m, int
how);
struct mbuf *
MCLGETI
(struct
mbuf *m, int how,
struct ifnet *ifp,
int len);
MEXTADD
(struct
mbuf *m, caddr_t
buf, u_int size,
int flags,
void (*free)(caddr_t, u_int,
void *), void
*arg);
void
m_align
(struct
mbuf *m, int
len);
M_READONLY
(struct
mbuf *m);
int
m_leadingspace
(struct
mbuf *m);
int
m_trailingspace
(struct
mbuf *m);
struct mbuf *
m_dup_pkt
(struct
mbuf *m, u_int adj,
int how);
int
m_dup_pkthdr
(struct
mbuf *to, struct mbuf
*from, int
how);
#define MSIZE 256 #define MLEN (MSIZE - sizeof(struct m_hdr)) #define MHLEN (MLEN - sizeof(struct pkthdr)) #define MAXMCLBYTES (64 * 1024) #define MINCLSIZE (MHLEN + MLEN + 1) #define M_MAXCOMPRESS (MHLEN / 2) #define MCLSHIFT 11 #define MCLBYTES (1 << MCLSHIFT) #define MCLOFSET (MCLBYTES - 1) #define mtod(m,t) ((t)((m)->m_data)) struct m_hdr { struct mbuf *mh_next; struct mbuf *mh_nextpkt; caddr_t mh_data; u_int mh_len; short mh_type; u_short mh_flags; #ifndef __LP64__ u_int mh_pad; #endif }; struct pkthdr { void *ph_cookie; SLIST_HEAD(, m_tag) ph_tags; int64_t ph_timestamp; int len; u_int16_t ph_tagsset; u_int16_t ph_flowid; u_int16_t csum_flags; u_int16_t ether_vtag; u_int ph_rtableid; u_int ph_ifidx; u_int8_t ph_loopcnt; struct pkthdr_pf pf; }; struct pkthdr_pf { struct pf_state_key *statekey; struct inpcb *inp; u_int32_t qid; u_int16_t tag; u_int8_t flags; u_int8_t routed; u_int8_t prio; u_int8_t pad[3]; }; struct mbuf_ext { caddr_t ext_buf; void *ext_arg; u_int ext_free_fn; u_int ext_size; struct mbuf *ext_nextref; struct mbuf *ext_prevref; }; struct mbuf { struct m_hdr m_hdr; union { struct { struct pkthdr MH_pkthdr; union { struct mbuf_ext MH_ext; char MH_databuf[MHLEN]; } MH_dat; } MH; char M_databuf[MLEN]; } M_dat; }; #define m_next m_hdr.mh_next #define m_len m_hdr.mh_len #define m_data m_hdr.mh_data #define m_type m_hdr.mh_type #define m_flags m_hdr.mh_flags #define m_nextpkt m_hdr.mh_nextpkt #define m_pkthdr M_dat.MH.MH_pkthdr #define m_ext M_dat.MH.MH_dat.MH_ext #define m_pktdat M_dat.MH.MH_dat.MH_databuf #define m_dat M_dat.M_databuf
The mbuf
functions provide a way to manage
the memory buffers used by the kernel's networking subsystem. Several
functions and macros are used to allocate and deallocate mbufs, but also to
get, inject, remove, copy, modify, prepend or append data inside these
mbufs. The size of an mbuf
is defined by MSIZE.
An mbuf
structure is defined as an
m_hdr structure followed by a union. The header
contains the following elements:
The mh_type variable can take the following values:
MT_FREE
MT_DATA
MT_HEADER
MT_SONAME
MT_SOOPTS
MT_FTABLE
MT_CONTROL
MT_OOBDATA
The mh_flags variable can take the following values:
M_EXT
M_PKTHDR
M_EOR
M_EXTWR
M_PROTO1
M_VLANTAG
M_LOOP
M_ACAST
M_BCAST
M_MCAST
M_CONF
M_AUTH
M_TUNNEL
M_ZEROIZE
m_free
.M_COMP
M_LINK0
An external cluster is used when the data to hold in the mbuf is large. The size of an external cluster is between MCLBYTES and MAXMCLBYTES. A cluster should be used when the size of the data reach MINCLSIZE (the minimum size to be held by an external cluster).
The combination of the M_EXT and M_PKTHDR flags give four types of mbuf. When none of these constants are in use, the mbuf is a "normal" one, where the data part of the mbuf has the following elements:
When only M_PKTHDR is set, the data contained in the mbuf is a packet header. The data itself is contained in the mbuf (just like the previous case), but part of the mbuf is used to store a packet header. The data part has then the following elements:
The m_pkthdr.csum_flags variable can take the following values:
M_IPV4_CSUM_OUT
M_TCP_CSUM_OUT
M_UDP_CSUM_OUT
M_ICMP_CSUM_OUT
M_IPV4_CSUM_IN_OK
M_IPV4_CSUM_IN_BAD
M_TCP_CSUM_IN_OK
M_TCP_CSUM_IN_BAD
M_UDP_CSUM_IN_OK
M_UDP_CSUM_IN_BAD
M_ICMP_CSUM_IN_OK
M_ICMP_CSUM_IN_BAD
M_IPV6_DF_OUT
The m_pkthdr.flowid variable can contain a low resolution (15-bit) classification of a flow or connection that the current mbuf is part of. If the flowid is valid, it may be used as an alternative to hashing the packets content to pick between different paths for the traffic. The following masks can be ORed with the flowid:
M_FLOWID_VALID
M_FLOWID_MASK
When only M_EXT flag is set, an external storage buffer is being used to hold the data, which is no longer stored in the mbuf. The data part of the mbuf has now the following elements:
When both the M_EXT and M_PKTHDR flags are set, an external storage buffer is being used to store the data and this data contains a packet header. The structure used is the same as the previous one except that the m_pkthdr element is not empty, it contains the same information as when M_PKTHDR is used alone.
m_copym
(struct
mbuf *m, int off, int len,
int wait)m_free
(struct
mbuf *m)NULL
pointer, no
action occurs and NULL
is returned.m_get
(int
how, int type)m_get
() returns NULL.MGET
(struct
mbuf *m, int how, int
type)m_get
() for a description of
how.m_getclr
(int
how, int type)m_get
() for a description of
how.m_removehdr
(struct
mbuf *m)m_resethdr
(struct
mbuf *m)m_calchdrlen
(struct
mbuf *m)m_gethdr
(int
how, int type)m_get
() for a
description of how.MGETHDR
(struct
mbuf *m, int how, int
type)m_get
() for a
description of how.m_prepend
(struct
mbuf *m, int len, int
how)m_get
() for a description of
how.M_PREPEND
(struct
mbuf *m, int plen, int
how)m_pulldown
(struct
mbuf *m, int off, int len,
int *offp)m_pullup
(struct
mbuf *n, int len)m_split
(struct
mbuf *m0, int len0, int
wait)m_makespace
(struct
mbuf *m0, int skip, int
hlen, int *off)m_getptr
(struct
mbuf *m, int loc, int
*off)m_adj
(struct
mbuf *mp, int req_len)m_copyback
(struct
mbuf *m0, int off, int
len, caddr_t cp, int
wait)m_copyback
() returns
ENOBUFS
. The mbuf chain must be initialized
properly, including setting m_len.m_defrag
(struct
mbuf *m, int wait)m_defrag
()
returns 0 on success or ENOBUFS
on failure. The
mbuf pointer m remains in existence and unchanged on
failure.m_freem
(struct
mbuf *m)NULL
pointer, no action occurs and
NULL
is returned.m_freemp
(struct
mbuf **mp)NULL
and call
m_freem
().m_purge
(struct
mbuf *m)m_freem
(). If m is a
NULL
pointer, no action occurs.m_reclaim
(void)m_copydata
(struct
mbuf *m, int off, int len,
caddr_t cp)m_cat
(struct
mbuf *m, struct mbuf *n)m_devget
(char
*buf, int totlen, int
off)m_apply
(struct
mbuf *m, int off, int len,
int (*func)(caddr_t, caddr_t, unsigned int),
caddr_t fstate)mtod
(struct
mbuf *m, datatype)MCLGET
(struct
mbuf *m, int how)m_get
() for a description of
how.MCLGETI
(struct
mbuf *m, int how, struct ifnet
*ifp, int len)m_get
() for a description of
how.MEXTADD
(struct
mbuf *m, caddr_t buf, u_int
size, int flags, void
(*free)(caddr_t, u_int, void *), void *arg)m_align
(struct
mbuf *m, int len)M_READONLY
(struct
mbuf *m)m_leadingspace
(struct
mbuf *m)m_trailingspace
(struct
mbuf *m)m_dup_pkt
(struct
mbuf *m, u_int adj, int
how)m_get
() for a
description of how.m_dup_pkthdr
(struct
mbuf *to, struct mbuf *from, int
how)m_get
() for a description of
how.The mbuf management functions are implemented in the files sys/kern/uipc_mbuf.c and sys/kern/uipc_mbuf2.c. The function prototypes and the macros are located in sys/sys/mbuf.h.
netstat(1), mbuf_tags(9), mutex(9), spl(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.
December 7, 2018 | OpenBSD-6.7 |