1829d1a776d2fc5124c1701da541079d0e17da6b3tuexen/*-
2829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Copyright (c) 1982, 1986, 1988, 1993
3829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *      The Regents of the University of California.
4829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * All rights reserved.
5829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *
6829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * Redistribution and use in source and binary forms, with or without
7829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * modification, are permitted provided that the following conditions
8829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * are met:
9829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * 1. Redistributions of source code must retain the above copyright
10829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *    notice, this list of conditions and the following disclaimer.
11829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * 2. Redistributions in binary form must reproduce the above copyright
12829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *    notice, this list of conditions and the following disclaimer in the
13829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *    documentation and/or other materials provided with the distribution.
14829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * 3. Neither the name of the University nor the names of its contributors
15829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *    may be used to endorse or promote products derived from this software
16829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *    without specific prior written permission.
17829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *
18829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28829d1a776d2fc5124c1701da541079d0e17da6b3tuexen * SUCH DAMAGE.
29829d1a776d2fc5124c1701da541079d0e17da6b3tuexen *
30829d1a776d2fc5124c1701da541079d0e17da6b3tuexen */
31829d1a776d2fc5124c1701da541079d0e17da6b3tuexen
32bca1dae6587a640359abee04337c0463b0a3893tuexen#ifndef _USER_MBUF_H_
33bca1dae6587a640359abee04337c0463b0a3893tuexen#define _USER_MBUF_H_
34bca1dae6587a640359abee04337c0463b0a3893tuexen
35bca1dae6587a640359abee04337c0463b0a3893tuexen/* __Userspace__ header file for mbufs */
36bca1dae6587a640359abee04337c0463b0a3893tuexen#include <stdio.h>
37bca1dae6587a640359abee04337c0463b0a3893tuexen#if !defined(SCTP_SIMPLE_ALLOCATOR)
38bca1dae6587a640359abee04337c0463b0a3893tuexen#include "umem.h"
39bca1dae6587a640359abee04337c0463b0a3893tuexen#endif
40bca1dae6587a640359abee04337c0463b0a3893tuexen#include "user_malloc.h"
41bca1dae6587a640359abee04337c0463b0a3893tuexen#include "netinet/sctp_os_userspace.h"
42bca1dae6587a640359abee04337c0463b0a3893tuexen
43bca1dae6587a640359abee04337c0463b0a3893tuexen#define USING_MBUF_CONSTRUCTOR 0
44bca1dae6587a640359abee04337c0463b0a3893tuexen
45bca1dae6587a640359abee04337c0463b0a3893tuexen/* For Linux */
46bca1dae6587a640359abee04337c0463b0a3893tuexen#ifndef MSIZE
47bca1dae6587a640359abee04337c0463b0a3893tuexen#define MSIZE 256
48bca1dae6587a640359abee04337c0463b0a3893tuexen/* #define MSIZE 1024 */
49bca1dae6587a640359abee04337c0463b0a3893tuexen#endif
50bca1dae6587a640359abee04337c0463b0a3893tuexen#ifndef MCLBYTES
51bca1dae6587a640359abee04337c0463b0a3893tuexen#define MCLBYTES 2048
52bca1dae6587a640359abee04337c0463b0a3893tuexen#endif
53bca1dae6587a640359abee04337c0463b0a3893tuexen
54bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf * m_gethdr(int how, short type);
55bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf * m_get(int how, short type);
56bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf * m_free(struct mbuf *m);
57bca1dae6587a640359abee04337c0463b0a3893tuexenvoid m_clget(struct mbuf *m, int how);
58bca1dae6587a640359abee04337c0463b0a3893tuexen
59bca1dae6587a640359abee04337c0463b0a3893tuexen
60bca1dae6587a640359abee04337c0463b0a3893tuexen/* mbuf initialization function */
61bca1dae6587a640359abee04337c0463b0a3893tuexenvoid mbuf_init(void *);
62bca1dae6587a640359abee04337c0463b0a3893tuexen
63bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_MOVE_PKTHDR(to, from)	m_move_pkthdr((to), (from))
64bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MGET(m, how, type)	((m) = m_get((how), (type)))
65bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MGETHDR(m, how, type)	((m) = m_gethdr((how), (type)))
66bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MCLGET(m, how)		m_clget((m), (how))
67bca1dae6587a640359abee04337c0463b0a3893tuexen
68bca1dae6587a640359abee04337c0463b0a3893tuexen
69bca1dae6587a640359abee04337c0463b0a3893tuexen#define M_HDR_PAD ((sizeof(intptr_t)==4) ? 2 : 6) /* modified for __Userspace__ */
70bca1dae6587a640359abee04337c0463b0a3893tuexen
71bca1dae6587a640359abee04337c0463b0a3893tuexen/* Length to m_copy to copy all. */
72bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_COPYALL	1000000000
73bca1dae6587a640359abee04337c0463b0a3893tuexen
74c7108437de5af4d0b9f9a24979710b39197ec6cetuexen/* umem_cache_t is defined in user_include/umem.h as
75bca1dae6587a640359abee04337c0463b0a3893tuexen * typedef struct umem_cache umem_cache_t;
76bca1dae6587a640359abee04337c0463b0a3893tuexen * Note:umem_zone_t is a pointer.
77bca1dae6587a640359abee04337c0463b0a3893tuexen */
78c7108437de5af4d0b9f9a24979710b39197ec6cetuexen#if defined(SCTP_SIMPLE_ALLOCATOR)
79bca1dae6587a640359abee04337c0463b0a3893tuexentypedef size_t sctp_zone_t;
80bca1dae6587a640359abee04337c0463b0a3893tuexen#else
81bca1dae6587a640359abee04337c0463b0a3893tuexentypedef umem_cache_t *sctp_zone_t;
82bca1dae6587a640359abee04337c0463b0a3893tuexen#endif
83bca1dae6587a640359abee04337c0463b0a3893tuexen
84bca1dae6587a640359abee04337c0463b0a3893tuexenextern sctp_zone_t zone_mbuf;
85bca1dae6587a640359abee04337c0463b0a3893tuexenextern sctp_zone_t zone_clust;
86bca1dae6587a640359abee04337c0463b0a3893tuexenextern sctp_zone_t zone_ext_refcnt;
87bca1dae6587a640359abee04337c0463b0a3893tuexen
88bca1dae6587a640359abee04337c0463b0a3893tuexen/*-
89bca1dae6587a640359abee04337c0463b0a3893tuexen * Macros for type conversion:
90bca1dae6587a640359abee04337c0463b0a3893tuexen * mtod(m, t)	-- Convert mbuf pointer to data pointer of correct type.
91bca1dae6587a640359abee04337c0463b0a3893tuexen * dtom(x)	-- Convert data pointer within mbuf to mbuf pointer (XXX).
92bca1dae6587a640359abee04337c0463b0a3893tuexen */
93bca1dae6587a640359abee04337c0463b0a3893tuexen#define	mtod(m, t)	((t)((m)->m_data))
94bca1dae6587a640359abee04337c0463b0a3893tuexen#define	dtom(x)		((struct mbuf *)((intptr_t)(x) & ~(MSIZE-1)))
95bca1dae6587a640359abee04337c0463b0a3893tuexen
96bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mb_args {
97bca1dae6587a640359abee04337c0463b0a3893tuexen	int	flags;	/* Flags for mbuf being allocated */
98bca1dae6587a640359abee04337c0463b0a3893tuexen	short	type;	/* Type of mbuf being allocated */
99bca1dae6587a640359abee04337c0463b0a3893tuexen};
100bca1dae6587a640359abee04337c0463b0a3893tuexen
101bca1dae6587a640359abee04337c0463b0a3893tuexenstruct clust_args {
1029b332c241dd6df73b563594af7c334e23f5e42b8t	struct mbuf * parent_mbuf;
103bca1dae6587a640359abee04337c0463b0a3893tuexen};
104bca1dae6587a640359abee04337c0463b0a3893tuexen
105bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf *    m_split(struct mbuf *, int, int);
106bca1dae6587a640359abee04337c0463b0a3893tuexenvoid             m_cat(struct mbuf *m, struct mbuf *n);
107bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_adj(struct mbuf *, int);
108bca1dae6587a640359abee04337c0463b0a3893tuexenvoid  mb_free_ext(struct mbuf *);
109bca1dae6587a640359abee04337c0463b0a3893tuexenvoid  m_freem(struct mbuf *);
110bca1dae6587a640359abee04337c0463b0a3893tuexenstruct m_tag	*m_tag_alloc(u_int32_t, int, int, int);
111bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf	*m_copym(struct mbuf *, int, int, int);
112a89a6767416760e852d85b2db374f6eebc4e93d7tuexenvoid		 m_copyback(struct mbuf *, int, int, caddr_t);
113bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf	*m_pullup(struct mbuf *, int);
114cd78deb883f0edfcdcde56ea7a2f972afc3bfbcdtuexenstruct mbuf	*m_pulldown(struct mbuf *, int off, int len, int *offp);
115bca1dae6587a640359abee04337c0463b0a3893tuexenint		 m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
116bca1dae6587a640359abee04337c0463b0a3893tuexenstruct m_tag	*m_tag_copy(struct m_tag *, int);
117bca1dae6587a640359abee04337c0463b0a3893tuexenint		 m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
118bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf	*m_prepend(struct mbuf *, int, int);
119bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_copydata(const struct mbuf *, int, int, caddr_t);
120bca1dae6587a640359abee04337c0463b0a3893tuexen
121bca1dae6587a640359abee04337c0463b0a3893tuexen#define MBUF_MEM_NAME "mbuf"
122bca1dae6587a640359abee04337c0463b0a3893tuexen#define MBUF_CLUSTER_MEM_NAME "mbuf_cluster"
123bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MBUF_EXTREFCNT_MEM_NAME	"mbuf_ext_refcnt"
124bca1dae6587a640359abee04337c0463b0a3893tuexen
125bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_NOINIT	255	/* Not a type but a flag to allocate
126bca1dae6587a640359abee04337c0463b0a3893tuexen				   a non-initialized mbuf */
127bca1dae6587a640359abee04337c0463b0a3893tuexen
128bca1dae6587a640359abee04337c0463b0a3893tuexen/*
129bca1dae6587a640359abee04337c0463b0a3893tuexen * General mbuf allocator statistics structure.
130bca1dae6587a640359abee04337c0463b0a3893tuexen * __Userspace__ mbstat may be useful for gathering statistics.
131bca1dae6587a640359abee04337c0463b0a3893tuexen * In the kernel many of these statistics are no longer used as
132bca1dae6587a640359abee04337c0463b0a3893tuexen * they track allocator statistics through kernel UMA's built in statistics mechanism.
133bca1dae6587a640359abee04337c0463b0a3893tuexen */
134bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbstat {
135bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mbufs;	/* XXX */
136bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mclusts;	/* XXX */
137bca1dae6587a640359abee04337c0463b0a3893tuexen
138bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_drain;	/* times drained protocols for space */
139bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mcfail;	/* XXX: times m_copym failed */
140bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mpfail;	/* XXX: times m_pullup failed */
141bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_msize;	/* length of an mbuf */
142bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mclbytes;	/* length of an mbuf cluster */
143bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_minclsize;	/* min length of data to allocate a cluster */
144bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mlen;		/* length of data in an mbuf */
145bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	m_mhlen;	/* length of data in a header mbuf */
146bca1dae6587a640359abee04337c0463b0a3893tuexen
147bca1dae6587a640359abee04337c0463b0a3893tuexen	/* Number of mbtypes (gives # elems in mbtypes[] array: */
148bca1dae6587a640359abee04337c0463b0a3893tuexen	short	m_numtypes;
149bca1dae6587a640359abee04337c0463b0a3893tuexen
150bca1dae6587a640359abee04337c0463b0a3893tuexen	/* XXX: Sendfile stats should eventually move to their own struct */
151bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	sf_iocnt;	/* times sendfile had to do disk I/O */
152bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	sf_allocfail;	/* times sfbuf allocation failed */
153bca1dae6587a640359abee04337c0463b0a3893tuexen	u_long	sf_allocwait;	/* times sfbuf allocation had to wait */
154bca1dae6587a640359abee04337c0463b0a3893tuexen};
155bca1dae6587a640359abee04337c0463b0a3893tuexen
156bca1dae6587a640359abee04337c0463b0a3893tuexen
157bca1dae6587a640359abee04337c0463b0a3893tuexen/*
158bca1dae6587a640359abee04337c0463b0a3893tuexen * Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead.
159bca1dae6587a640359abee04337c0463b0a3893tuexen * An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
160bca1dae6587a640359abee04337c0463b0a3893tuexen * sys/param.h), which has no additional overhead and is used instead of the
161bca1dae6587a640359abee04337c0463b0a3893tuexen * internal data area; this is done when at least MINCLSIZE of data must be
162bca1dae6587a640359abee04337c0463b0a3893tuexen * stored.  Additionally, it is possible to allocate a separate buffer
163bca1dae6587a640359abee04337c0463b0a3893tuexen * externally and attach it to the mbuf in a way similar to that of mbuf
164bca1dae6587a640359abee04337c0463b0a3893tuexen * clusters.
165bca1dae6587a640359abee04337c0463b0a3893tuexen */
166702e28636b3144fa8a5e0a464f6675108589b8e7t#define	MLEN		((int)(MSIZE - sizeof(struct m_hdr)))	/* normal data len */
167702e28636b3144fa8a5e0a464f6675108589b8e7t#define	MHLEN		((int)(MLEN - sizeof(struct pkthdr)))	/* data len w/pkthdr */
16895bfa38ce6f931b195b768ca9ba286c3c904d805t#define	MINCLSIZE	((int)(MHLEN + 1))	/* smallest amount to put in cluster */
169bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */
170bca1dae6587a640359abee04337c0463b0a3893tuexen
171bca1dae6587a640359abee04337c0463b0a3893tuexen
172bca1dae6587a640359abee04337c0463b0a3893tuexen/*
173bca1dae6587a640359abee04337c0463b0a3893tuexen * Header present at the beginning of every mbuf.
174bca1dae6587a640359abee04337c0463b0a3893tuexen */
175bca1dae6587a640359abee04337c0463b0a3893tuexenstruct m_hdr {
176bca1dae6587a640359abee04337c0463b0a3893tuexen	struct mbuf	*mh_next;	/* next buffer in chain */
177bca1dae6587a640359abee04337c0463b0a3893tuexen	struct mbuf	*mh_nextpkt;	/* next chain in queue/record */
178bca1dae6587a640359abee04337c0463b0a3893tuexen	caddr_t		 mh_data;	/* location of data */
179bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 mh_len;	/* amount of data in this mbuf */
180bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 mh_flags;	/* flags; see below */
181bca1dae6587a640359abee04337c0463b0a3893tuexen	short		 mh_type;	/* type of data in this mbuf */
182bca1dae6587a640359abee04337c0463b0a3893tuexen	uint8_t          pad[M_HDR_PAD];/* word align                  */
183bca1dae6587a640359abee04337c0463b0a3893tuexen};
184bca1dae6587a640359abee04337c0463b0a3893tuexen
185bca1dae6587a640359abee04337c0463b0a3893tuexen/*
186bca1dae6587a640359abee04337c0463b0a3893tuexen * Packet tag structure (see below for details).
187bca1dae6587a640359abee04337c0463b0a3893tuexen */
188bca1dae6587a640359abee04337c0463b0a3893tuexenstruct m_tag {
189bca1dae6587a640359abee04337c0463b0a3893tuexen	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */
190bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int16_t		m_tag_id;	/* Tag ID */
191bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int16_t		m_tag_len;	/* Length of data */
192bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int32_t		m_tag_cookie;	/* ABI/Module ID */
193bca1dae6587a640359abee04337c0463b0a3893tuexen	void			(*m_tag_free)(struct m_tag *);
194bca1dae6587a640359abee04337c0463b0a3893tuexen};
195bca1dae6587a640359abee04337c0463b0a3893tuexen
196bca1dae6587a640359abee04337c0463b0a3893tuexen/*
197bca1dae6587a640359abee04337c0463b0a3893tuexen * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
198bca1dae6587a640359abee04337c0463b0a3893tuexen */
199bca1dae6587a640359abee04337c0463b0a3893tuexenstruct pkthdr {
200bca1dae6587a640359abee04337c0463b0a3893tuexen	struct ifnet	*rcvif;		/* rcv interface */
201bca1dae6587a640359abee04337c0463b0a3893tuexen	/* variables for ip and tcp reassembly */
202bca1dae6587a640359abee04337c0463b0a3893tuexen	void		*header;	/* pointer to packet header */
203bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 len;		/* total packet length */
204bca1dae6587a640359abee04337c0463b0a3893tuexen	/* variables for hardware checksum */
205bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 csum_flags;	/* flags regarding checksum */
206bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 csum_data;	/* data field used by csum routines */
207bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int16_t	 tso_segsz;	/* TSO segment size */
208bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int16_t	 ether_vtag;	/* Ethernet 802.1p+q vlan tag */
209bca1dae6587a640359abee04337c0463b0a3893tuexen	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
210bca1dae6587a640359abee04337c0463b0a3893tuexen};
211bca1dae6587a640359abee04337c0463b0a3893tuexen
212bca1dae6587a640359abee04337c0463b0a3893tuexen/*
213bca1dae6587a640359abee04337c0463b0a3893tuexen * Description of external storage mapped into mbuf; valid only if M_EXT is
214bca1dae6587a640359abee04337c0463b0a3893tuexen * set.
215bca1dae6587a640359abee04337c0463b0a3893tuexen */
216bca1dae6587a640359abee04337c0463b0a3893tuexenstruct m_ext {
217bca1dae6587a640359abee04337c0463b0a3893tuexen	caddr_t		 ext_buf;	/* start of buffer */
218bca1dae6587a640359abee04337c0463b0a3893tuexen	void		(*ext_free)	/* free routine if not the usual */
219bca1dae6587a640359abee04337c0463b0a3893tuexen			    (void *, void *);
220bca1dae6587a640359abee04337c0463b0a3893tuexen	void		*ext_args;	/* optional argument pointer */
221bca1dae6587a640359abee04337c0463b0a3893tuexen	u_int		 ext_size;	/* size of buffer, for ext_free */
222bca1dae6587a640359abee04337c0463b0a3893tuexen	volatile u_int	*ref_cnt;	/* pointer to ref count info */
223bca1dae6587a640359abee04337c0463b0a3893tuexen	int		 ext_type;	/* type of external storage */
224bca1dae6587a640359abee04337c0463b0a3893tuexen};
225bca1dae6587a640359abee04337c0463b0a3893tuexen
226bca1dae6587a640359abee04337c0463b0a3893tuexen
227bca1dae6587a640359abee04337c0463b0a3893tuexen/*
228bca1dae6587a640359abee04337c0463b0a3893tuexen * The core of the mbuf object along with some shortcut defined for practical
229bca1dae6587a640359abee04337c0463b0a3893tuexen * purposes.
230bca1dae6587a640359abee04337c0463b0a3893tuexen */
231bca1dae6587a640359abee04337c0463b0a3893tuexenstruct mbuf {
232bca1dae6587a640359abee04337c0463b0a3893tuexen	struct m_hdr	m_hdr;
233bca1dae6587a640359abee04337c0463b0a3893tuexen	union {
234bca1dae6587a640359abee04337c0463b0a3893tuexen		struct {
235bca1dae6587a640359abee04337c0463b0a3893tuexen			struct pkthdr	MH_pkthdr;	/* M_PKTHDR set */
236bca1dae6587a640359abee04337c0463b0a3893tuexen			union {
237bca1dae6587a640359abee04337c0463b0a3893tuexen				struct m_ext	MH_ext;	/* M_EXT set */
238bca1dae6587a640359abee04337c0463b0a3893tuexen				char		MH_databuf[MHLEN];
239bca1dae6587a640359abee04337c0463b0a3893tuexen			} MH_dat;
240bca1dae6587a640359abee04337c0463b0a3893tuexen		} MH;
241bca1dae6587a640359abee04337c0463b0a3893tuexen		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
242bca1dae6587a640359abee04337c0463b0a3893tuexen	} M_dat;
243bca1dae6587a640359abee04337c0463b0a3893tuexen};
244bca1dae6587a640359abee04337c0463b0a3893tuexen
245bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_next		m_hdr.mh_next
246bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_len		m_hdr.mh_len
247bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_data		m_hdr.mh_data
248bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_type		m_hdr.mh_type
249bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_flags		m_hdr.mh_flags
250bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_nextpkt	m_hdr.mh_nextpkt
251bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_act		m_nextpkt
252bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_pkthdr	M_dat.MH.MH_pkthdr
253bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_ext		M_dat.MH.MH_dat.MH_ext
254bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
255bca1dae6587a640359abee04337c0463b0a3893tuexen#define	m_dat		M_dat.M_databuf
256bca1dae6587a640359abee04337c0463b0a3893tuexen
257bca1dae6587a640359abee04337c0463b0a3893tuexen
258bca1dae6587a640359abee04337c0463b0a3893tuexen/*
259bca1dae6587a640359abee04337c0463b0a3893tuexen * mbuf flags.
260bca1dae6587a640359abee04337c0463b0a3893tuexen */
261bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_EXT		0x0001	/* has associated external storage */
262bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PKTHDR	0x0002	/* start of record */
263bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_EOR		0x0004	/* end of record */
264bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_RDONLY	0x0008	/* associated data is marked read-only */
265bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROTO1	0x0010	/* protocol-specific */
266bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROTO2	0x0020	/* protocol-specific */
267bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROTO3	0x0040	/* protocol-specific */
268bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROTO4	0x0080	/* protocol-specific */
269bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROTO5	0x0100	/* protocol-specific */
270bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_SKIP_FIREWALL	0x4000	/* skip firewall processing */
271bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_FREELIST	0x8000	/* mbuf is on the free list */
272bca1dae6587a640359abee04337c0463b0a3893tuexen
273bca1dae6587a640359abee04337c0463b0a3893tuexen
274bca1dae6587a640359abee04337c0463b0a3893tuexen/*
275bca1dae6587a640359abee04337c0463b0a3893tuexen * Flags copied when copying m_pkthdr.
276bca1dae6587a640359abee04337c0463b0a3893tuexen */
277bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_COPYFLAGS	(M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\
278bca1dae6587a640359abee04337c0463b0a3893tuexen			    M_PROTO3|M_PROTO4|M_PROTO5|M_SKIP_FIREWALL|\
279bca1dae6587a640359abee04337c0463b0a3893tuexen			    M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG|\
280bca1dae6587a640359abee04337c0463b0a3893tuexen			    M_VLANTAG|M_PROMISC)
281bca1dae6587a640359abee04337c0463b0a3893tuexen
282bca1dae6587a640359abee04337c0463b0a3893tuexen
283bca1dae6587a640359abee04337c0463b0a3893tuexen/*
284bca1dae6587a640359abee04337c0463b0a3893tuexen * mbuf pkthdr flags (also stored in m_flags).
285bca1dae6587a640359abee04337c0463b0a3893tuexen */
286bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_BCAST		0x0200	/* send/received as link-level broadcast */
287bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_MCAST		0x0400	/* send/received as link-level multicast */
288bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
289bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
290bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_LASTFRAG	0x2000	/* packet is last fragment */
291bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_VLANTAG	0x10000	/* ether_vtag is valid */
292bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PROMISC	0x20000	/* packet was not for us */
293bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_NOFREE	0x40000	/* do not free mbuf - it is embedded in the cluster */
294bca1dae6587a640359abee04337c0463b0a3893tuexen
295bca1dae6587a640359abee04337c0463b0a3893tuexen
296bca1dae6587a640359abee04337c0463b0a3893tuexen/*
297bca1dae6587a640359abee04337c0463b0a3893tuexen * External buffer types: identify ext_buf type.
298bca1dae6587a640359abee04337c0463b0a3893tuexen */
299bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_CLUSTER	1	/* mbuf cluster */
300bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_SFBUF	2	/* sendfile(2)'s sf_bufs */
301bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_JUMBOP	3	/* jumbo cluster 4096 bytes */
302bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_JUMBO9	4	/* jumbo cluster 9216 bytes */
303bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_JUMBO16	5	/* jumbo cluster 16184 bytes */
304bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_PACKET	6	/* mbuf+cluster from packet zone */
305bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_MBUF	7	/* external mbuf reference (M_IOVEC) */
306bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_NET_DRV	100	/* custom ext_buf provided by net driver(s) */
307bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_MOD_TYPE	200	/* custom module's ext_buf type */
308bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_DISPOSABLE	300	/* can throw this buffer away w/page flipping */
309bca1dae6587a640359abee04337c0463b0a3893tuexen#define	EXT_EXTREF	400	/* has externally maintained ref_cnt ptr */
310bca1dae6587a640359abee04337c0463b0a3893tuexen
311bca1dae6587a640359abee04337c0463b0a3893tuexen
312bca1dae6587a640359abee04337c0463b0a3893tuexen/*
313bca1dae6587a640359abee04337c0463b0a3893tuexen * mbuf types.
314bca1dae6587a640359abee04337c0463b0a3893tuexen */
315bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_NOTMBUF	0	/* USED INTERNALLY ONLY! Object is not mbuf */
316bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_DATA		1	/* dynamic (data) allocation */
317bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_HEADER	MT_DATA	/* packet header, use M_PKTHDR instead */
318bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_SONAME	8	/* socket name */
319bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_CONTROL	14	/* extra-data protocol message */
320bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_OOBDATA	15	/* expedited data  */
321bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_NTYPES	16	/* number of mbuf types for mbtypes[] */
322bca1dae6587a640359abee04337c0463b0a3893tuexen
323bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MT_NOINIT	255	/* Not a type but a flag to allocate
324bca1dae6587a640359abee04337c0463b0a3893tuexen				   a non-initialized mbuf */
325bca1dae6587a640359abee04337c0463b0a3893tuexen
326bca1dae6587a640359abee04337c0463b0a3893tuexen/*
327bca1dae6587a640359abee04337c0463b0a3893tuexen * __Userspace__ flags like M_NOWAIT are defined in malloc.h
328bca1dae6587a640359abee04337c0463b0a3893tuexen * Flags like these are used in functions like uma_zalloc()
329bca1dae6587a640359abee04337c0463b0a3893tuexen * but don't have an equivalent in userland umem
330bca1dae6587a640359abee04337c0463b0a3893tuexen * Flags specifying how an allocation should be made.
331bca1dae6587a640359abee04337c0463b0a3893tuexen *
332bca1dae6587a640359abee04337c0463b0a3893tuexen * The flag to use is as follows:
333bca1dae6587a640359abee04337c0463b0a3893tuexen * - M_DONTWAIT or M_NOWAIT from an interrupt handler to not block allocation.
334bca1dae6587a640359abee04337c0463b0a3893tuexen * - M_WAIT or M_WAITOK or M_TRYWAIT from wherever it is safe to block.
335bca1dae6587a640359abee04337c0463b0a3893tuexen *
336bca1dae6587a640359abee04337c0463b0a3893tuexen * M_DONTWAIT/M_NOWAIT means that we will not block the thread explicitly and
337bca1dae6587a640359abee04337c0463b0a3893tuexen * if we cannot allocate immediately we may return NULL, whereas
338bca1dae6587a640359abee04337c0463b0a3893tuexen * M_WAIT/M_WAITOK/M_TRYWAIT means that if we cannot allocate resources we
339bca1dae6587a640359abee04337c0463b0a3893tuexen * will block until they are available, and thus never return NULL.
340bca1dae6587a640359abee04337c0463b0a3893tuexen *
341bca1dae6587a640359abee04337c0463b0a3893tuexen * XXX Eventually just phase this out to use M_WAITOK/M_NOWAIT.
342bca1dae6587a640359abee04337c0463b0a3893tuexen */
343bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MBTOM(how)	(how)
344bca1dae6587a640359abee04337c0463b0a3893tuexen
345bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_tag_delete(struct mbuf *, struct m_tag *);
346bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_tag_delete_chain(struct mbuf *, struct m_tag *);
347bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_move_pkthdr(struct mbuf *, struct mbuf *);
348bca1dae6587a640359abee04337c0463b0a3893tuexenvoid		 m_tag_free_default(struct m_tag *);
349bca1dae6587a640359abee04337c0463b0a3893tuexen
350bca1dae6587a640359abee04337c0463b0a3893tuexenextern int max_linkhdr;    /* Largest link-level header */
351bca1dae6587a640359abee04337c0463b0a3893tuexenextern int max_protohdr; /* Size of largest protocol layer header. See user_mbuf.c */
352bca1dae6587a640359abee04337c0463b0a3893tuexen
353bca1dae6587a640359abee04337c0463b0a3893tuexenextern struct mbstat	mbstat;		/* General mbuf stats/infos */
354bca1dae6587a640359abee04337c0463b0a3893tuexen
355bca1dae6587a640359abee04337c0463b0a3893tuexen
356bca1dae6587a640359abee04337c0463b0a3893tuexen/*
357bca1dae6587a640359abee04337c0463b0a3893tuexen * Evaluate TRUE if it's safe to write to the mbuf m's data region (this can
358bca1dae6587a640359abee04337c0463b0a3893tuexen * be both the local data payload, or an external buffer area, depending on
359bca1dae6587a640359abee04337c0463b0a3893tuexen * whether M_EXT is set).
360bca1dae6587a640359abee04337c0463b0a3893tuexen */
361bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_WRITABLE(m)	(!((m)->m_flags & M_RDONLY) &&			\
362bca1dae6587a640359abee04337c0463b0a3893tuexen			 (!(((m)->m_flags & M_EXT)) ||			\
363bca1dae6587a640359abee04337c0463b0a3893tuexen			 (*((m)->m_ext.ref_cnt) == 1)) )		\
364bca1dae6587a640359abee04337c0463b0a3893tuexen
365bca1dae6587a640359abee04337c0463b0a3893tuexen
366bca1dae6587a640359abee04337c0463b0a3893tuexen/*
367bca1dae6587a640359abee04337c0463b0a3893tuexen * Compute the amount of space available before the current start of data in
368bca1dae6587a640359abee04337c0463b0a3893tuexen * an mbuf.
369bca1dae6587a640359abee04337c0463b0a3893tuexen *
370bca1dae6587a640359abee04337c0463b0a3893tuexen * The M_WRITABLE() is a temporary, conservative safety measure: the burden
371bca1dae6587a640359abee04337c0463b0a3893tuexen * of checking writability of the mbuf data area rests solely with the caller.
372bca1dae6587a640359abee04337c0463b0a3893tuexen */
373bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_LEADINGSPACE(m)						\
374bca1dae6587a640359abee04337c0463b0a3893tuexen	((m)->m_flags & M_EXT ?						\
375bca1dae6587a640359abee04337c0463b0a3893tuexen	    (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0):	\
376bca1dae6587a640359abee04337c0463b0a3893tuexen	    (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat :	\
377bca1dae6587a640359abee04337c0463b0a3893tuexen	    (m)->m_data - (m)->m_dat)
378bca1dae6587a640359abee04337c0463b0a3893tuexen
379bca1dae6587a640359abee04337c0463b0a3893tuexen/*
380bca1dae6587a640359abee04337c0463b0a3893tuexen * Compute the amount of space available after the end of data in an mbuf.
381bca1dae6587a640359abee04337c0463b0a3893tuexen *
382bca1dae6587a640359abee04337c0463b0a3893tuexen * The M_WRITABLE() is a temporary, conservative safety measure: the burden
383bca1dae6587a640359abee04337c0463b0a3893tuexen * of checking writability of the mbuf data area rests solely with the caller.
384bca1dae6587a640359abee04337c0463b0a3893tuexen */
385bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_TRAILINGSPACE(m)						\
386bca1dae6587a640359abee04337c0463b0a3893tuexen	((m)->m_flags & M_EXT ?						\
387bca1dae6587a640359abee04337c0463b0a3893tuexen	    (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size	\
388bca1dae6587a640359abee04337c0463b0a3893tuexen		- ((m)->m_data + (m)->m_len) : 0) :			\
389bca1dae6587a640359abee04337c0463b0a3893tuexen	    &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
390bca1dae6587a640359abee04337c0463b0a3893tuexen
391bca1dae6587a640359abee04337c0463b0a3893tuexen
392bca1dae6587a640359abee04337c0463b0a3893tuexen
393bca1dae6587a640359abee04337c0463b0a3893tuexen/*
394bca1dae6587a640359abee04337c0463b0a3893tuexen * Arrange to prepend space of size plen to mbuf m.  If a new mbuf must be
395bca1dae6587a640359abee04337c0463b0a3893tuexen * allocated, how specifies whether to wait.  If the allocation fails, the
396bca1dae6587a640359abee04337c0463b0a3893tuexen * original mbuf chain is freed and m is set to NULL.
397bca1dae6587a640359abee04337c0463b0a3893tuexen */
398bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_PREPEND(m, plen, how) do {					\
399bca1dae6587a640359abee04337c0463b0a3893tuexen	struct mbuf **_mmp = &(m);					\
400bca1dae6587a640359abee04337c0463b0a3893tuexen	struct mbuf *_mm = *_mmp;					\
401bca1dae6587a640359abee04337c0463b0a3893tuexen	int _mplen = (plen);						\
402bca1dae6587a640359abee04337c0463b0a3893tuexen	int __mhow = (how);						\
403bca1dae6587a640359abee04337c0463b0a3893tuexen									\
404bca1dae6587a640359abee04337c0463b0a3893tuexen	if (M_LEADINGSPACE(_mm) >= _mplen) {				\
405bca1dae6587a640359abee04337c0463b0a3893tuexen		_mm->m_data -= _mplen;					\
406bca1dae6587a640359abee04337c0463b0a3893tuexen		_mm->m_len += _mplen;					\
407bca1dae6587a640359abee04337c0463b0a3893tuexen	} else								\
408bca1dae6587a640359abee04337c0463b0a3893tuexen		_mm = m_prepend(_mm, _mplen, __mhow);			\
409bca1dae6587a640359abee04337c0463b0a3893tuexen	if (_mm != NULL && _mm->m_flags & M_PKTHDR)			\
410bca1dae6587a640359abee04337c0463b0a3893tuexen		_mm->m_pkthdr.len += _mplen;				\
411bca1dae6587a640359abee04337c0463b0a3893tuexen	*_mmp = _mm;							\
412bca1dae6587a640359abee04337c0463b0a3893tuexen} while (0)
413bca1dae6587a640359abee04337c0463b0a3893tuexen
414bca1dae6587a640359abee04337c0463b0a3893tuexen/*
415bca1dae6587a640359abee04337c0463b0a3893tuexen * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place an
416bca1dae6587a640359abee04337c0463b0a3893tuexen * object of the specified size at the end of the mbuf, longword aligned.
417bca1dae6587a640359abee04337c0463b0a3893tuexen */
418bca1dae6587a640359abee04337c0463b0a3893tuexen#define	M_ALIGN(m, len) do {						\
419c7108437de5af4d0b9f9a24979710b39197ec6cetuexen        KASSERT(!((m)->m_flags & (M_PKTHDR|M_EXT)),                     \
420c7108437de5af4d0b9f9a24979710b39197ec6cetuexen                ("%s: M_ALIGN not normal mbuf", __func__));             \
421c7108437de5af4d0b9f9a24979710b39197ec6cetuexen        KASSERT((m)->m_data == (m)->m_dat,                              \
422c7108437de5af4d0b9f9a24979710b39197ec6cetuexen                ("%s: M_ALIGN not a virgin mbuf", __func__));           \
423bca1dae6587a640359abee04337c0463b0a3893tuexen	(m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1);		\
424bca1dae6587a640359abee04337c0463b0a3893tuexen} while (0)
425bca1dae6587a640359abee04337c0463b0a3893tuexen
426bca1dae6587a640359abee04337c0463b0a3893tuexen/*
427bca1dae6587a640359abee04337c0463b0a3893tuexen * As above, for mbufs allocated with m_gethdr/MGETHDR or initialized by
428bca1dae6587a640359abee04337c0463b0a3893tuexen * M_DUP/MOVE_PKTHDR.
429bca1dae6587a640359abee04337c0463b0a3893tuexen */
430bca1dae6587a640359abee04337c0463b0a3893tuexen#define	MH_ALIGN(m, len) do {						\
431c7108437de5af4d0b9f9a24979710b39197ec6cetuexen        KASSERT((m)->m_flags & M_PKTHDR && !((m)->m_flags & M_EXT),     \
432c7108437de5af4d0b9f9a24979710b39197ec6cetuexen                ("%s: MH_ALIGN not PKTHDR mbuf", __func__));            \
433c7108437de5af4d0b9f9a24979710b39197ec6cetuexen        KASSERT((m)->m_data == (m)->m_pktdat,                           \
434c7108437de5af4d0b9f9a24979710b39197ec6cetuexen                ("%s: MH_ALIGN not a virgin mbuf", __func__));          \
435bca1dae6587a640359abee04337c0463b0a3893tuexen	(m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1);		\
436bca1dae6587a640359abee04337c0463b0a3893tuexen} while (0)
437bca1dae6587a640359abee04337c0463b0a3893tuexen
438bca1dae6587a640359abee04337c0463b0a3893tuexen#endif
439