mbuf.h revision e6ca555ca95db3d710e106b8f0920ea99be7c4a5
/*-
* Copyright (c) 1982, 1986, 1988, 1993
* The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mbuf.h 8.5 (Berkeley) 2/19/95
*/
#ifndef _SYS_MBUF_H_
#define _SYS_MBUF_H_
#ifndef VBOX
/* XXX: These includes suck. Sorry! */
#ifdef _KERNEL
#ifdef WITNESS
#endif
#endif
#else /* VBOX */
# include "misc.h"
# include "ext.h"
typedef const char *c_caddr_t;
{
}
/* for non-gnu compilers */
# ifndef __inline
# define __inline
# endif
/*
* Constants related to network buffer management.
* MCLBYTES must be no larger than PAGE_SIZE.
*/
# ifndef MSIZE
# endif /* MSIZE */
# ifndef MCLSHIFT
# endif /* MCLSHIFT */
# ifndef MCLBYTES
# endif /*MCLBYTES*/
#endif /* VBOX */
/*
* An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
* internal data area; this is done when at least MINCLSIZE of data must be
* stored. Additionally, it is possible to allocate a separate buffer
* externally and attach it to the mbuf in a way similar to that of mbuf
* clusters.
*/
/*-
* Macros for type conversion:
* mtod(m, t) -- Convert mbuf pointer to data pointer of correct type.
* dtom(x) -- Convert data pointer within mbuf to mbuf pointer (XXX).
*/
/*
* Argument structure passed to UMA routines during mbuf and packet
* allocations.
*/
struct mb_args {
int flags; /* Flags for mbuf being allocated */
short type; /* Type of mbuf being allocated */
};
#endif /* _KERNEL */
#if defined(__LP64__)
#define M_HDR_PAD 6
#else
#define M_HDR_PAD 2
#endif
/*
* Header present at the beginning of every mbuf.
*/
struct m_hdr {
int mh_len; /* amount of data in this mbuf */
int mh_flags; /* flags; see below */
short mh_type; /* type of data in this mbuf */
#ifdef VBOX
#endif
};
/*
* Packet tag structure (see below for details).
*/
struct m_tag {
void (*m_tag_free)(struct m_tag *);
};
/*
*/
struct pkthdr {
/* variables for ip and tcp reassembly */
void *header; /* pointer to packet header */
int len; /* total packet length */
/* variables for hardware checksum */
int csum_flags; /* flags regarding checksum */
int csum_data; /* data field used by csum routines */
};
/*
* Description of external storage mapped into mbuf; valid only if M_EXT is
* set.
*/
struct m_ext {
void (*ext_free) /* free routine if not the usual */
(void *, void *);
void *ext_args; /* optional argument pointer */
#ifdef VBOX
#else
#endif
int ext_type; /* type of external storage */
};
/*
* The core of the mbuf object along with some shortcut defines for practical
* purposes.
*/
struct mbuf {
union {
struct {
union {
char MH_databuf[MHLEN];
} MH_dat;
} MH;
} M_dat;
};
#ifdef VBOX
#endif
/*
* mbuf flags.
*/
/*
* For RELENG_{6,7} steal these flags for limited multiple routing table
* support. In RELENG_8 and beyond, use just one flag and a tag.
*/
/*
* Flags to purge when crossing layers.
*/
#define M_PROTOFLAGS \
/*
* Flags preserved when copying m_pkthdr.
*/
#define M_COPYFLAGS \
/*
* External buffer types: identify ext_buf type.
*/
/*
* Flags indicating hw checksum support and sw checksum requirements. This
* field can be directly tested against if_data.ifi_hwassist.
*/
/*
* mbuf types.
*/
#define MT_NOTMBUF 0 /* USED INTERNALLY ONLY! Object is not mbuf */
a non-initialized mbuf */
/*
* General mbuf allocator statistics structure.
*
* Many of these statistics are no longer used; we instead track many
* allocator statistics through UMA's built in statistics mechanism.
*/
struct mbstat {
/* Number of mbtypes (gives # elems in mbtypes[] array) */
short m_numtypes;
/* XXX: Sendfile stats should eventually move to their own struct */
};
/*
* Flags specifying how an allocation should be made.
*
* The flag to use is as follows:
* - M_DONTWAIT or M_NOWAIT from an interrupt handler to not block allocation.
* - M_WAIT or M_WAITOK or M_TRYWAIT from wherever it is safe to block.
*
* M_DONTWAIT/M_NOWAIT means that we will not block the thread explicitly and
* if we cannot allocate immediately we may return NULL, whereas
* will block until they are available, and thus never return NULL.
*
*/
#ifndef VBOX
#define M_DONTWAIT M_NOWAIT
#else
/* @todo (r=vvl) not sure we can do it in NAT */
# define M_WAITOK 0
# define M_NOWAIT 0
# define M_DONTWAIT 0
# define M_TRYWAI 0
# define M_WAIT 0
#endif
/*
* String names of mbuf-related UMA(9) and malloc(9) types. Exposed to
* !_KERNEL so that monitoring tools can look up the zones with
* libmemstat(3).
*/
#define MBUF_MEM_NAME "mbuf"
#define MBUF_CLUSTER_MEM_NAME "mbuf_cluster"
#define MBUF_PACKET_MEM_NAME "mbuf_packet"
#define MBUF_JUMBOP_MEM_NAME "mbuf_jumbo_pagesize"
#define MBUF_JUMBO9_MEM_NAME "mbuf_jumbo_9k"
#define MBUF_JUMBO16_MEM_NAME "mbuf_jumbo_16k"
#define MBUF_TAG_MEM_NAME "mbuf_tag"
#define MBUF_EXTREFCNT_MEM_NAME "mbuf_ext_refcnt"
#ifdef WITNESS
#define MBUF_CHECKSLEEP(how) do { \
"Sleeping in \"%s\"", __func__); \
} while (0)
#else
#define MBUF_CHECKSLEEP(how)
#endif
/*
* Network buffer allocation API
*
* The rest of it is defined in kern/kern_mbuf.c
*/
#ifndef VBOX
extern uma_zone_t zone_mbuf;
extern uma_zone_t zone_clust;
extern uma_zone_t zone_pack;
extern uma_zone_t zone_jumbop;
extern uma_zone_t zone_jumbo9;
extern uma_zone_t zone_jumbo16;
extern uma_zone_t zone_ext_refcnt;
#endif
#ifndef VBOX
int size);
void mb_free_ext(struct mbuf *);
#else
#endif
static __inline int
{
int type;
switch (size) {
case MSIZE:
break;
case MCLBYTES:
type = EXT_CLUSTER;
break;
#if MJUMPAGESIZE != MCLBYTES
case MJUMPAGESIZE:
type = EXT_JUMBOP;
break;
#endif
case MJUM9BYTES:
type = EXT_JUMBO9;
break;
case MJUM16BYTES:
type = EXT_JUMBO16;
break;
default:
}
return (type);
}
static __inline uma_zone_t
#ifndef VBOX
#else
#endif
{
switch (size) {
case MSIZE:
break;
case MCLBYTES:
zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
case MJUMPAGESIZE:
zone = zone_jumbop;
break;
#endif
case MJUM9BYTES:
zone = zone_jumbo9;
break;
case MJUM16BYTES:
zone = zone_jumbo16;
break;
default:
}
return (zone);
}
#ifndef VBOX
#else
#endif
{
}
/*
* XXX This should be deprecated, very little use.
*/
#ifndef VBOX
#else
#endif
{
struct mbuf *m;
if (m != NULL)
return (m);
}
#ifndef VBOX
#else
#endif
{
}
#ifndef VBOX
#else
#endif
{
}
/*
* m_getjcl() returns an mbuf with a cluster of the specified size attached.
* For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
*
* XXX: This is rather large, should be real function maybe.
*/
#ifndef VBOX
#else
#endif
{
struct mbuf *m, *n;
if (m == NULL)
return (NULL);
#ifndef VBOX
#else
#endif
if (n == NULL) {
return (NULL);
}
return (m);
}
#ifndef VBOX
static __inline void
m_free_fast(struct mbuf *m)
{
}
#else
static __inline void
{
}
#endif
#ifndef VBOX
#else
#endif
{
#ifndef VBOX
mb_free_ext(m);
#else
mb_free_ext(pData, m);
#endif
return (n);
}
static __inline void
#ifndef VBOX
#else
#endif
{
/*
* On a cluster allocation failure, drain the packet zone and retry,
* we might be able to loosen a few clusters up on the drain.
*/
}
}
/*
* m_cljget() is different from m_clget() as it can allocate clusters without
* attaching them to an mbuf. In that case the return value is the pointer
* to the cluster of the requested size. If an mbuf was specified, it gets
* the cluster attached to it and the return value can be safely ignored.
* For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
*/
static __inline void *
#ifndef VBOX
#else
#endif
{
if (m != NULL)
#ifndef VBOX
#else
#endif
}
static __inline void
#ifndef VBOX
#else
#endif
{
int size;
switch (type) {
case EXT_CLUSTER:
zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
case EXT_JUMBOP:
size = MJUMPAGESIZE;
zone = zone_jumbop;
break;
#endif
case EXT_JUMBO9:
size = MJUM9BYTES;
zone = zone_jumbo9;
break;
case EXT_JUMBO16:
size = MJUM16BYTES;
zone = zone_jumbo16;
break;
default:
panic("unknown cluster type");
break;
}
#ifdef VBOX
#else
#endif
}
static __inline void
{
}
{
while (m->m_next)
m = m->m_next;
return (m);
}
/*
* mbuf, cluster, and external object allocation macros (for compatibility
* purposes).
*/
#ifndef VBOX
#else /*!VBOX*/
#endif
/*
* Evaluate TRUE if it's safe to write to the mbuf m's data region (this can
* be both the local data payload, or an external buffer area, depending on
* whether M_EXT is set).
*/
/* Check if the supplied mbuf has a packet header, or else panic. */
#define M_ASSERTPKTHDR(m) \
("%s: no mbuf packet header!", __func__))
/*
* Ensure that the supplied mbuf is a valid, non-free mbuf.
*
* XXX: Broken at the moment. Need some UMA magic to make it work again.
*/
#define M_ASSERTVALID(m) \
("%s: attempted use of a free mbuf!", __func__))
/*
* object of the specified size at the end of the mbuf, longword aligned.
*/
("%s: M_ALIGN not normal mbuf", __func__)); \
("%s: M_ALIGN not a virgin mbuf", __func__)); \
} while (0)
/*
* M_DUP/MOVE_PKTHDR.
*/
("%s: MH_ALIGN not PKTHDR mbuf", __func__)); \
("%s: MH_ALIGN not a virgin mbuf", __func__)); \
} while (0)
/*
* Compute the amount of space available before the current start of data in
* an mbuf.
*
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
* of checking writability of the mbuf data area rests solely with the caller.
*/
#define M_LEADINGSPACE(m) \
/*
* Compute the amount of space available after the end of data in an mbuf.
*
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
* of checking writability of the mbuf data area rests solely with the caller.
*/
#define M_TRAILINGSPACE(m) \
/*
* Arrange to prepend space of size plen to mbuf m. If a new mbuf must be
* allocated, how specifies whether to wait. If the allocation fails, the
* original mbuf chain is freed and m is set to NULL.
*/
\
MBUF_CHECKSLEEP(how); \
} else \
} while (0)
/*
* Change mbuf to new type. This is a relatively expensive operation and
* should be avoided.
*/
/* Length to m_copy to copy all. */
#define M_COPYALL 1000000000
/* Compatibility with 4.3. */
extern int max_datalen; /* MHLEN - max_hdr */
extern int max_hdr; /* Largest link + protocol header */
extern int max_linkhdr; /* Largest link-level header */
extern int max_protohdr; /* Largest protocol header */
extern int nmbclusters; /* Maximum number of clusters */
struct uio;
int (*)(void *, void *, u_int), void *);
#ifndef VBOX
int, int, int, int);
void (*)(void *, void *), void *, int, int);
#else
int, int, int, int);
void (*)(void *, void *), void *, int, int);
#endif
#ifndef VBOX
#else
#endif
/*-
* Network packets may have annotations attached by affixing a list of
* "packet tags" to the pkthdr structure. Packet tags are dynamically
* allocated semi-opaque data structures that have a fixed header
* (struct m_tag) that specifies the size of the memory block and a
* <cookie,type> pair that identifies it. The cookie is a 32-bit unique
* unsigned value used to identify a module or ABI. By convention this value
* is chosen as the date+time that the module is created, expressed as the
* number of seconds since the epoch (e.g., using date -u +'%s'). The type
* value is an ABI/module-specific value that identifies a particular
* annotation and is private to the module. For compatibility with systems
* PACKET_ABI_COMPAT is used to implement m_tag_get and m_tag_find
* compatibility shim functions and several tag types are defined below.
* Users that do not require compatibility should use a private cookie value
* so that packet tag-related definitions can be maintained privately.
*
* Note that the packet tag returned by m_tag_alloc has the default memory
* alignment implemented by malloc. To reference private data one can use a
* construct like:
*
* struct m_tag *mtag = m_tag_alloc(...);
* struct foo *p = (struct foo *)(mtag+1);
*
* if the alignment of struct m_tag is sufficient for referencing members of
* struct foo. Otherwise it is necessary to embed struct m_tag within the
* private data structure to insure proper alignment; e.g.,
*
* struct foo {
* struct m_tag tag;
* ...
* };
* struct foo *p = (struct foo *) m_tag_alloc(...);
* struct m_tag *mtag = &p->tag;
*/
/*
* Persistent tags stay with an mbuf until the mbuf is reclaimed. Otherwise
* tags are expected to ``vanish'' when they pass through a network
* interface. For most interfaces this happens normally as the tags are
* reclaimed when the mbuf is free'd. However in some special cases
* reclaiming must be done manually. An example is packets that pass through
* the loopback interface. Also, one must be careful to do this when
* ``turning around'' packets (e.g., icmp_reflect).
*
* To mark a tag persistent bit-or this flag in when defining the tag id.
* The tag will then be treated as described above.
*/
#define MTAG_PERSISTENT 0x800
#define PACKET_TAG_NONE 0 /* Nadda */
/* Packet tags for use with PACKET_ABI_COMPAT. */
#ifdef VBOX
# define PACKET_TAG_ALIAS 0xab01
# define PACKET_TAG_ETHER 0xab02
# define PACKET_SERVICE 0xab03
#endif
/* Specific cookies and tags. */
/* Packet tag routines. */
void m_tag_free_default(struct m_tag *);
void m_tag_delete_nonpersistent(struct mbuf *);
/*
* Initialize the list of tags associated with an mbuf.
*/
static __inline void
m_tag_init(struct mbuf *m)
{
}
/*
* Set up the contents of a tag. Note that this does not fill in the free
* method; the caller is expected to do that.
*
* XXX probably should be called m_tag_init, but that was already taken.
*/
static __inline void
{
t->m_tag_cookie = cookie;
}
/*
* Reclaim resources associated with a tag.
*/
static __inline void
m_tag_free(struct m_tag *t)
{
(*t->m_tag_free)(t);
}
/*
* Return the first tag associated with an mbuf.
*/
m_tag_first(struct mbuf *m)
{
}
/*
* Return the next tag in the list of tags associated with an mbuf.
*/
{
NOREF(m);
return (SLIST_NEXT(t, m_tag_link));
}
/*
* Prepend a tag to the list of tags associated with an mbuf.
*/
static __inline void
{
}
/*
* Unlink a tag from the list of tags associated with an mbuf.
*/
static __inline void
{
}
/* These are for OpenBSD compatibility. */
#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
{
}
{
}
/* XXX temporary FIB methods probably eventually use tags.*/
#define M_FIBSHIFT 28
#define M_FIBMASK 0x0F
/* get the fib from an mbuf and if it is not set, return the default */
} while (0)
#endif /* _KERNEL */
#endif /* !_SYS_MBUF_H_ */