mbuf.h revision 75686
131565Ssef/*
231897Ssef * Copyright (c) 1982, 1986, 1988, 1993
331897Ssef *	The Regents of the University of California.  All rights reserved.
431897Ssef *
531897Ssef * Redistribution and use in source and binary forms, with or without
631897Ssef * modification, are permitted provided that the following conditions
731897Ssef * are met:
831897Ssef * 1. Redistributions of source code must retain the above copyright
931897Ssef *    notice, this list of conditions and the following disclaimer.
1031897Ssef * 2. Redistributions in binary form must reproduce the above copyright
1131897Ssef *    notice, this list of conditions and the following disclaimer in the
1231897Ssef *    documentation and/or other materials provided with the distribution.
1331897Ssef * 3. All advertising materials mentioning features or use of this software
1431897Ssef *    must display the following acknowledgement:
1531897Ssef *	This product includes software developed by the University of
1631897Ssef *	California, Berkeley and its contributors.
1731897Ssef * 4. Neither the name of the University nor the names of its contributors
1831897Ssef *    may be used to endorse or promote products derived from this software
1931897Ssef *    without specific prior written permission.
2031897Ssef *
2131897Ssef * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2231897Ssef * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2331897Ssef * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2431897Ssef * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2531897Ssef * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2631897Ssef * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2731897Ssef * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2831897Ssef * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2931897Ssef * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3031897Ssef * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3131897Ssef * SUCH DAMAGE.
3231897Ssef *
3331897Ssef *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
3431565Ssef * $FreeBSD: head/sys/sys/mbuf.h 75686 2001-04-18 23:54:13Z bmilekic $
3531565Ssef */
3631565Ssef
3731565Ssef#ifndef _SYS_MBUF_H_
3831565Ssef#define	_SYS_MBUF_H_
3931565Ssef
4031565Ssef#ifdef _KERNEL
4131565Ssef#include <sys/condvar.h>	/* XXX */
4231897Ssef#include <sys/lock.h>		/* XXX */
4331565Ssef#include <sys/mutex.h>		/* XXX */
4431565Ssef#endif /* _KERNEL */
4531565Ssef
4631565Ssef/*
4731565Ssef * Mbufs are of a single size, MSIZE (machine/param.h), which
4831565Ssef * includes overhead.  An mbuf may add a single "mbuf cluster" of size
4931565Ssef * MCLBYTES (also in machine/param.h), which has no additional overhead
5031565Ssef * and is used instead of the internal data area; this is done when
5131565Ssef * at least MINCLSIZE of data must be stored.
5231565Ssef */
5331565Ssef
5431565Ssef#define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
5531565Ssef#define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
5631565Ssef
5731565Ssef#define	MINCLSIZE	(MHLEN + 1)	/* smallest amount to put in cluster */
5831565Ssef#define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */
5931565Ssef
6031565Ssef/*
6131565Ssef * Maximum number of allocatable counters for external buffers. This
6231565Ssef * ensures enough VM address space for the allocation of counters
6331565Ssef * in the extreme case where all possible external buffers are allocated.
6431565Ssef *
6531565Ssef * Note: When new types of external storage are allocated, EXT_COUNTERS
6631565Ssef * 	 must be tuned accordingly. Practically, this isn't a big deal
6731565Ssef *	 as each counter is only a word long, so we can fit
6831565Ssef *	 (PAGE_SIZE / length of word) counters in a single page.
6931565Ssef *
7031565Ssef * XXX: Must increase this if using any of if_ti, if_wb, if_sk drivers,
7131565Ssef *	or any other drivers which may manage their own buffers and
7231565Ssef *	eventually attach them to mbufs.
7331565Ssef */
7431691Ssef#define EXT_COUNTERS (nmbclusters + nsfbufs)
7531565Ssef
7631565Ssef#ifdef _KERNEL
7731565Ssef/*
7831691Ssef * Macros for type conversion
7931565Ssef * mtod(m, t)	- convert mbuf pointer to data pointer of correct type
8031565Ssef * dtom(x)	- convert data pointer within mbuf to mbuf pointer (XXX)
8131565Ssef */
8231565Ssef#define	mtod(m, t)	((t)((m)->m_data))
8331565Ssef#define	dtom(x)		((struct mbuf *)((intptr_t)(x) & ~(MSIZE-1)))
8431565Ssef#endif /* _KERNEL */
8531565Ssef
86/* header at beginning of each mbuf: */
87struct m_hdr {
88	struct	mbuf *mh_next;		/* next buffer in chain */
89	struct	mbuf *mh_nextpkt;	/* next chain in queue/record */
90	caddr_t	mh_data;		/* location of data */
91	int	mh_len;			/* amount of data in this mbuf */
92	short	mh_type;		/* type of data in this mbuf */
93	short	mh_flags;		/* flags; see below */
94};
95
96/* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
97struct pkthdr {
98	struct	ifnet *rcvif;		/* rcv interface */
99	int	len;			/* total packet length */
100	/* variables for ip and tcp reassembly */
101	void	*header;		/* pointer to packet header */
102	/* variables for hardware checksum */
103	int	csum_flags;		/* flags regarding checksum */
104	int	csum_data;		/* data field used by csum routines */
105	struct	mbuf *aux;		/* extra data buffer; ipsec/others */
106};
107
108/* description of external storage mapped into mbuf, valid if M_EXT set */
109struct m_ext {
110	caddr_t	ext_buf;		/* start of buffer */
111	void	(*ext_free)		/* free routine if not the usual */
112		    (caddr_t, void *);
113	void	*ext_args;		/* optional argument pointer */
114	u_int	ext_size;		/* size of buffer, for ext_free */
115	union	mext_refcnt *ref_cnt;	/* pointer to ref count info */
116	int	ext_type;		/* type of external storage */
117};
118
119struct mbuf {
120	struct	m_hdr m_hdr;
121	union {
122		struct {
123			struct	pkthdr MH_pkthdr;	/* M_PKTHDR set */
124			union {
125				struct	m_ext MH_ext;	/* M_EXT set */
126				char	MH_databuf[MHLEN];
127			} MH_dat;
128		} MH;
129		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
130	} M_dat;
131};
132#define	m_next		m_hdr.mh_next
133#define	m_len		m_hdr.mh_len
134#define	m_data		m_hdr.mh_data
135#define	m_type		m_hdr.mh_type
136#define	m_flags		m_hdr.mh_flags
137#define	m_nextpkt	m_hdr.mh_nextpkt
138#define	m_act		m_nextpkt
139#define	m_pkthdr	M_dat.MH.MH_pkthdr
140#define	m_ext		M_dat.MH.MH_dat.MH_ext
141#define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
142#define	m_dat		M_dat.M_databuf
143
144/* mbuf flags */
145#define	M_EXT		0x0001	/* has associated external storage */
146#define	M_PKTHDR	0x0002	/* start of record */
147#define	M_EOR		0x0004	/* end of record */
148#define M_RDONLY	0x0008	/* associated data is marked read-only */
149#define	M_PROTO1	0x0010	/* protocol-specific */
150#define	M_PROTO2	0x0020	/* protocol-specific */
151#define	M_PROTO3	0x0040	/* protocol-specific */
152#define	M_PROTO4	0x0080	/* protocol-specific */
153#define	M_PROTO5	0x0100	/* protocol-specific */
154
155/* mbuf pkthdr flags, also in m_flags */
156#define	M_BCAST		0x0200	/* send/received as link-level broadcast */
157#define	M_MCAST		0x0400	/* send/received as link-level multicast */
158#define	M_FRAG		0x0800	/* packet is a fragment of a larger packet */
159#define	M_FIRSTFRAG	0x1000	/* packet is first fragment */
160#define	M_LASTFRAG	0x2000	/* packet is last fragment */
161
162/* external buffer types: identify ext_buf type */
163#define	EXT_CLUSTER	1	/* mbuf cluster */
164#define	EXT_SFBUF	2	/* sendfile(2)'s sf_bufs */
165#define	EXT_NET_DRV	100	/* custom ext_buf provided by net driver(s) */
166#define	EXT_MOD_TYPE	200	/* custom module's ext_buf type */
167
168/* flags copied when copying m_pkthdr */
169#define	M_COPYFLAGS	(M_PKTHDR|M_EOR|M_PROTO1|M_PROTO1|M_PROTO2|M_PROTO3 | \
170			    M_PROTO4|M_PROTO5|M_BCAST|M_MCAST|M_FRAG|M_RDONLY)
171
172/* flags indicating hw checksum support and sw checksum requirements */
173#define CSUM_IP			0x0001		/* will csum IP */
174#define CSUM_TCP		0x0002		/* will csum TCP */
175#define CSUM_UDP		0x0004		/* will csum UDP */
176#define CSUM_IP_FRAGS		0x0008		/* will csum IP fragments */
177#define CSUM_FRAGMENT		0x0010		/* will do IP fragmentation */
178
179#define CSUM_IP_CHECKED		0x0100		/* did csum IP */
180#define CSUM_IP_VALID		0x0200		/*   ... the csum is valid */
181#define CSUM_DATA_VALID		0x0400		/* csum_data field is valid */
182#define CSUM_PSEUDO_HDR		0x0800		/* csum_data has pseudo hdr */
183
184#define CSUM_DELAY_DATA		(CSUM_TCP | CSUM_UDP)
185#define CSUM_DELAY_IP		(CSUM_IP)	/* XXX add ipv6 here too? */
186
187/* mbuf types */
188#define	MT_FREE		0	/* should be on free list */
189#define	MT_DATA		1	/* dynamic (data) allocation */
190#define	MT_HEADER	2	/* packet header */
191#if 0
192#define	MT_SOCKET	3	/* socket structure */
193#define	MT_PCB		4	/* protocol control block */
194#define	MT_RTABLE	5	/* routing tables */
195#define	MT_HTABLE	6	/* IMP host tables */
196#define	MT_ATABLE	7	/* address resolution tables */
197#endif
198#define	MT_SONAME	8	/* socket name */
199#if 0
200#define	MT_SOOPTS	10	/* socket options */
201#endif
202#define	MT_FTABLE	11	/* fragment reassembly header */
203#if 0
204#define	MT_RIGHTS	12	/* access rights */
205#define	MT_IFADDR	13	/* interface address */
206#endif
207#define	MT_CONTROL	14	/* extra-data protocol message */
208#define	MT_OOBDATA	15	/* expedited data  */
209#define	MT_NTYPES	16	/* number of mbuf types for mbtypes[] */
210
211/*
212 * mbuf statistics
213 */
214struct mbstat {
215	u_long	m_mbufs;	/* # mbufs obtained from page pool */
216	u_long	m_clusters;	/* # clusters obtained from page pool */
217	u_long	m_clfree;	/* # clusters on freelist (cache) */
218	u_long	m_refcnt;	/* # ref counters obtained from page pool */
219	u_long	m_refree;	/* # ref counters on freelist (cache) */
220	u_long	m_spare;	/* spare field */
221	u_long	m_drops;	/* times failed to find space */
222	u_long	m_wait;		/* times waited for space */
223	u_long	m_drain;	/* times drained protocols for space */
224	u_long	m_mcfail;	/* times m_copym failed */
225	u_long	m_mpfail;	/* times m_pullup failed */
226	u_long	m_msize;	/* length of an mbuf */
227	u_long	m_mclbytes;	/* length of an mbuf cluster */
228	u_long	m_minclsize;	/* min length of data to allocate a cluster */
229	u_long	m_mlen;		/* length of data in an mbuf */
230	u_long	m_mhlen;	/* length of data in a header mbuf */
231};
232
233/* flags to m_get/MGET */
234#define	M_DONTWAIT	1
235#define	M_TRYWAIT	0
236#define	M_WAIT		M_TRYWAIT	/* XXX: Deprecated. */
237
238/*
239 * Normal mbuf clusters are normally treated as character arrays
240 * after allocation, but use the first word of the buffer as a free list
241 * pointer while on the free list.
242 */
243union mcluster {
244	union	mcluster *mcl_next;
245	char	mcl_buf[MCLBYTES];
246};
247
248/*
249 * The m_ext object reference counter structure.
250 */
251union mext_refcnt {
252	union	mext_refcnt *next_ref;
253	u_int	refcnt;
254};
255
256#ifdef _KERNEL
257/*
258 * The freelists for mbufs and mbuf clusters include condition variables
259 * that are used in cases of depletion/starvation.
260 * The counter freelist does not require a condition variable as we never
261 * expect to consume more than the reserved address space for counters.
262 * All are presently protected by the mbuf_mtx lock.
263 */
264struct mbffree_lst {
265	struct	mbuf *m_head;
266	struct	cv m_starved;
267};
268
269struct mclfree_lst {
270	union	mcluster *m_head;
271	struct	cv m_starved;
272};
273
274struct mcntfree_lst {
275	union	mext_refcnt *m_head;
276};
277
278/*
279 * Signal a single instance (if any) blocked on a m_starved cv (i.e. an
280 * instance waiting for an {mbuf, cluster} to be freed to the global
281 * cache lists).
282 *
283 * Must be called with mbuf_mtx held.
284 */
285#define	MBWAKEUP(m_wid, m_cv) do {					\
286	if ((m_wid) > 0)						\
287		cv_signal((m_cv));					\
288} while (0)
289
290/*
291 * mbuf external reference count management macros:
292 *
293 * MEXT_IS_REF(m): true if (m) is not the only mbuf referencing
294 *     the external buffer ext_buf
295 * MEXT_REM_REF(m): remove reference to m_ext object
296 * MEXT_ADD_REF(m): add reference to m_ext object already
297 *     referred to by (m)
298 * MEXT_INIT_REF(m): allocate and initialize an external
299 *     object reference counter for (m)
300 */
301#define MEXT_IS_REF(m) ((m)->m_ext.ref_cnt->refcnt > 1)
302
303#define MEXT_REM_REF(m) do {						\
304	KASSERT((m)->m_ext.ref_cnt->refcnt > 0, ("m_ext refcnt < 0"));	\
305	atomic_subtract_int(&((m)->m_ext.ref_cnt->refcnt), 1);		\
306} while(0)
307
308#define MEXT_ADD_REF(m) atomic_add_int(&((m)->m_ext.ref_cnt->refcnt), 1)
309
310#define _MEXT_ALLOC_CNT(m_cnt, how) do {				\
311	union mext_refcnt *__mcnt;					\
312									\
313	mtx_lock(&mbuf_mtx);						\
314	if (mcntfree.m_head == NULL)					\
315		m_alloc_ref(1, (how));					\
316	__mcnt = mcntfree.m_head;					\
317	if (__mcnt != NULL) {						\
318		mcntfree.m_head = __mcnt->next_ref;			\
319		mbstat.m_refree--;					\
320		__mcnt->refcnt = 0;					\
321	}								\
322	mtx_unlock(&mbuf_mtx);						\
323	(m_cnt) = __mcnt;						\
324} while (0)
325
326#define _MEXT_DEALLOC_CNT(m_cnt) do {					\
327	union mext_refcnt *__mcnt = (m_cnt);				\
328									\
329	mtx_lock(&mbuf_mtx);						\
330	__mcnt->next_ref = mcntfree.m_head;				\
331	mcntfree.m_head = __mcnt;					\
332	mbstat.m_refree++;						\
333	mtx_unlock(&mbuf_mtx);						\
334} while (0)
335
336#define MEXT_INIT_REF(m, how) do {					\
337	struct mbuf *__mmm = (m);					\
338									\
339	_MEXT_ALLOC_CNT(__mmm->m_ext.ref_cnt, (how));			\
340	if (__mmm->m_ext.ref_cnt != NULL)				\
341		MEXT_ADD_REF(__mmm);					\
342} while (0)
343
344/*
345 * mbuf allocation/deallocation macros:
346 *
347 *	MGET(struct mbuf *m, int how, int type)
348 * allocates an mbuf and initializes it to contain internal data.
349 *
350 *	MGETHDR(struct mbuf *m, int how, int type)
351 * allocates an mbuf and initializes it to contain a packet header
352 * and internal data.
353 */
354/*
355 * Lower-level macros for MGET(HDR)... Not to be used outside the
356 * subsystem ("non-exportable" macro names are prepended with "_").
357 */
358#define _MGET_SETUP(m_set, m_set_type) do {				\
359	(m_set)->m_type = (m_set_type);					\
360	(m_set)->m_next = NULL;						\
361	(m_set)->m_nextpkt = NULL;					\
362	(m_set)->m_data = (m_set)->m_dat;				\
363	(m_set)->m_flags = 0;						\
364} while (0)
365
366#define	_MGET(m_mget, m_get_how) do {					\
367	if (mmbfree.m_head == NULL)					\
368		m_mballoc(1, (m_get_how));				\
369	(m_mget) = mmbfree.m_head;					\
370	if ((m_mget) != NULL) {						\
371		mmbfree.m_head = (m_mget)->m_next;			\
372		mbtypes[MT_FREE]--;					\
373	} else {							\
374		if ((m_get_how) == M_TRYWAIT)				\
375			(m_mget) = m_mballoc_wait();			\
376	}								\
377} while (0)
378
379#define MGET(m, how, type) do {						\
380	struct mbuf *_mm;						\
381	int _mhow = (how);						\
382	int _mtype = (type);						\
383									\
384	mtx_lock(&mbuf_mtx);						\
385	_MGET(_mm, _mhow);						\
386	if (_mm != NULL) {						\
387		mbtypes[_mtype]++;					\
388		mtx_unlock(&mbuf_mtx);					\
389		_MGET_SETUP(_mm, _mtype);				\
390	} else {							\
391		mbstat.m_drops++;					\
392		mtx_unlock(&mbuf_mtx);					\
393	}								\
394	(m) = _mm;							\
395} while (0)
396
397#define _MGETHDR_SETUP(m_set, m_set_type) do {				\
398	(m_set)->m_type = (m_set_type);					\
399	(m_set)->m_next = NULL;						\
400	(m_set)->m_nextpkt = NULL;					\
401	(m_set)->m_data = (m_set)->m_pktdat;				\
402	(m_set)->m_flags = M_PKTHDR;					\
403	(m_set)->m_pkthdr.rcvif = NULL;					\
404	(m_set)->m_pkthdr.csum_flags = 0;				\
405	(m_set)->m_pkthdr.aux = NULL;					\
406} while (0)
407
408#define MGETHDR(m, how, type) do {					\
409	struct mbuf *_mm;						\
410	int _mhow = (how);						\
411	int _mtype = (type);						\
412									\
413	mtx_lock(&mbuf_mtx);						\
414	_MGET(_mm, _mhow);						\
415	if (_mm != NULL) {						\
416		mbtypes[_mtype]++;					\
417		mtx_unlock(&mbuf_mtx);					\
418		_MGETHDR_SETUP(_mm, _mtype);				\
419	} else {							\
420		mbstat.m_drops++;					\
421		mtx_unlock(&mbuf_mtx);					\
422	}								\
423	(m) = _mm;							\
424} while (0)
425
426/*
427 * mbuf external storage macros:
428 *
429 *   MCLGET allocates and refers an mcluster to an mbuf
430 *   MEXTADD sets up pre-allocated external storage and refers to mbuf
431 *   MEXTFREE removes reference to external object and frees it if
432 *       necessary
433 */
434#define	_MCLALLOC(p, how) do {						\
435	caddr_t _mp;							\
436	int _mhow = (how);						\
437									\
438	if (mclfree.m_head == NULL)					\
439		m_clalloc(1, _mhow);					\
440	_mp = (caddr_t)mclfree.m_head;					\
441	if (_mp != NULL) {						\
442		mbstat.m_clfree--;					\
443		mclfree.m_head = ((union mcluster *)_mp)->mcl_next;	\
444	} else {							\
445		if (_mhow == M_TRYWAIT)					\
446			_mp = m_clalloc_wait();				\
447	}								\
448	(p) = _mp;							\
449} while (0)
450
451#define	MCLGET(m, how) do {						\
452	struct mbuf *_mm = (m);						\
453									\
454	mtx_lock(&mbuf_mtx);						\
455	_MCLALLOC(_mm->m_ext.ext_buf, (how));				\
456	if (_mm->m_ext.ext_buf != NULL) {				\
457		mtx_unlock(&mbuf_mtx);					\
458		MEXT_INIT_REF(_mm, (how));				\
459		if (_mm->m_ext.ref_cnt == NULL) {			\
460			_MCLFREE(_mm->m_ext.ext_buf);			\
461			_mm->m_ext.ext_buf = NULL;			\
462		} else {						\
463			_mm->m_data = _mm->m_ext.ext_buf;		\
464			_mm->m_flags |= M_EXT;				\
465			_mm->m_ext.ext_free = NULL;			\
466			_mm->m_ext.ext_args = NULL;			\
467			_mm->m_ext.ext_size = MCLBYTES;			\
468			_mm->m_ext.ext_type = EXT_CLUSTER;		\
469		}							\
470	} else {							\
471		mbstat.m_drops++;					\
472		mtx_unlock(&mbuf_mtx);					\
473	}								\
474} while (0)
475
476#define MEXTADD(m, buf, size, free, args, flags, type) do {		\
477	struct mbuf *_mm = (m);						\
478									\
479	MEXT_INIT_REF(_mm, M_TRYWAIT);					\
480	if (_mm->m_ext.ref_cnt != NULL) {				\
481		_mm->m_flags |= (M_EXT | (flags));			\
482		_mm->m_ext.ext_buf = (caddr_t)(buf);			\
483		_mm->m_data = _mm->m_ext.ext_buf;			\
484		_mm->m_ext.ext_size = (size);				\
485		_mm->m_ext.ext_free = (free);				\
486		_mm->m_ext.ext_args = (args);				\
487		_mm->m_ext.ext_type = (type);				\
488	}								\
489} while (0)
490
491#define	_MCLFREE(p) do {						\
492	union mcluster *_mp = (union mcluster *)(p);			\
493									\
494	mtx_lock(&mbuf_mtx);						\
495	_mp->mcl_next = mclfree.m_head;					\
496	mclfree.m_head = _mp;						\
497	mbstat.m_clfree++;						\
498	MBWAKEUP(m_clalloc_wid, &mclfree.m_starved);			\
499	mtx_unlock(&mbuf_mtx); 						\
500} while (0)
501
502/* MEXTFREE:
503 * If the atomic_cmpset_int() returns 0, then we effectively do nothing
504 * in terms of "cleaning up" (freeing the ext buf and ref. counter) as
505 * this means that either there are still references, or another thread
506 * is taking care of the clean-up.
507 */
508#define	MEXTFREE(m) do {						\
509	struct mbuf *_mmm = (m);					\
510									\
511	MEXT_REM_REF(_mmm);						\
512	if (atomic_cmpset_int(&_mmm->m_ext.ref_cnt->refcnt, 0, 1)) {	\
513		if (_mmm->m_ext.ext_type != EXT_CLUSTER) {		\
514			(*(_mmm->m_ext.ext_free))(_mmm->m_ext.ext_buf,	\
515			    _mmm->m_ext.ext_args);			\
516		} else							\
517			_MCLFREE(_mmm->m_ext.ext_buf);			\
518		_MEXT_DEALLOC_CNT(_mmm->m_ext.ref_cnt);			\
519	}								\
520	_mmm->m_flags &= ~M_EXT;					\
521} while (0)
522
523/*
524 * MFREE(struct mbuf *m, struct mbuf *n)
525 * Free a single mbuf and associated external storage.
526 * Place the successor, if any, in n.
527 */
528#define	MFREE(m, n) do {						\
529	struct mbuf *_mm = (m);						\
530									\
531	KASSERT(_mm->m_type != MT_FREE, ("freeing free mbuf"));		\
532	if (_mm->m_flags & M_EXT)					\
533		MEXTFREE(_mm);						\
534	mtx_lock(&mbuf_mtx);						\
535	mbtypes[_mm->m_type]--;						\
536	_mm->m_type = MT_FREE;						\
537	mbtypes[MT_FREE]++;						\
538	(n) = _mm->m_next;						\
539	_mm->m_next = mmbfree.m_head;					\
540	mmbfree.m_head = _mm;						\
541	MBWAKEUP(m_mballoc_wid, &mmbfree.m_starved);			\
542	mtx_unlock(&mbuf_mtx); 						\
543} while (0)
544
545/*
546 * M_WRITABLE(m)
547 * Evaluate TRUE if it's safe to write to the mbuf m's data region (this
548 * can be both the local data payload, or an external buffer area,
549 * depending on whether M_EXT is set).
550 */
551#define M_WRITABLE(m)	(!((m)->m_flags & M_RDONLY) && (!((m)->m_flags  \
552			    & M_EXT) || !MEXT_IS_REF(m)))
553
554/*
555 * Copy mbuf pkthdr from "from" to "to".
556 * from must have M_PKTHDR set, and to must be empty.
557 * aux pointer will be moved to `to'.
558 */
559#define	M_COPY_PKTHDR(to, from) do {					\
560	struct mbuf *_mfrom = (from);					\
561	struct mbuf *_mto = (to);					\
562									\
563	_mto->m_data = _mto->m_pktdat;					\
564	_mto->m_flags = _mfrom->m_flags & M_COPYFLAGS;			\
565	_mto->m_pkthdr = _mfrom->m_pkthdr;				\
566	_mfrom->m_pkthdr.aux = NULL;					\
567} while (0)
568
569/*
570 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
571 * an object of the specified size at the end of the mbuf, longword aligned.
572 */
573#define	M_ALIGN(m, len) do {						\
574	(m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1);		\
575} while (0)
576
577/*
578 * As above, for mbufs allocated with m_gethdr/MGETHDR
579 * or initialized by M_COPY_PKTHDR.
580 */
581#define	MH_ALIGN(m, len) do {						\
582	(m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1);		\
583} while (0)
584
585/*
586 * Compute the amount of space available
587 * before the current start of data in an mbuf.
588 */
589#define	M_LEADINGSPACE(m)						\
590	((m)->m_flags & M_EXT ?						\
591	    /* (m)->m_data - (m)->m_ext.ext_buf */ 0 :			\
592	    (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat :	\
593	    (m)->m_data - (m)->m_dat)
594
595/*
596 * Compute the amount of space available
597 * after the end of data in an mbuf.
598 */
599#define	M_TRAILINGSPACE(m)						\
600	((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf +			\
601	    (m)->m_ext.ext_size - ((m)->m_data + (m)->m_len) :		\
602	    &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
603
604/*
605 * Arrange to prepend space of size plen to mbuf m.
606 * If a new mbuf must be allocated, how specifies whether to wait.
607 * If the allocation fails, the original mbuf chain is freed and m is
608 * set to NULL.
609 */
610#define	M_PREPEND(m, plen, how) do {					\
611	struct mbuf **_mmp = &(m);					\
612	struct mbuf *_mm = *_mmp;					\
613	int _mplen = (plen);						\
614	int __mhow = (how);						\
615									\
616	if (M_LEADINGSPACE(_mm) >= _mplen) {				\
617		_mm->m_data -= _mplen;					\
618		_mm->m_len += _mplen;					\
619	} else								\
620		_mm = m_prepend(_mm, _mplen, __mhow);			\
621	if (_mm != NULL && _mm->m_flags & M_PKTHDR)			\
622		_mm->m_pkthdr.len += _mplen;				\
623	*_mmp = _mm;							\
624} while (0)
625
626/*
627 * change mbuf to new type
628 */
629#define	MCHTYPE(m, t) do {						\
630	struct mbuf *_mm = (m);						\
631	int _mt = (t);							\
632									\
633	mtx_lock(&mbuf_mtx);						\
634	mbtypes[_mm->m_type]--;						\
635	mbtypes[_mt]++;							\
636	mtx_unlock(&mbuf_mtx);						\
637	_mm->m_type = (_mt);						\
638} while (0)
639
640/* length to m_copy to copy all */
641#define	M_COPYALL	1000000000
642
643/* compatibility with 4.3 */
644#define	m_copy(m, o, l)	m_copym((m), (o), (l), M_DONTWAIT)
645
646/*
647 * pkthdr.aux type tags.
648 */
649struct mauxtag {
650	int	af;
651	int	type;
652};
653
654extern	u_long		 m_clalloc_wid;	/* mbuf cluster wait count */
655extern	u_long		 m_mballoc_wid;	/* mbuf wait count */
656extern	int		 max_datalen;	/* MHLEN - max_hdr */
657extern	int		 max_hdr;	/* largest link+protocol header */
658extern	int		 max_linkhdr;	/* largest link-level header */
659extern	int		 max_protohdr;	/* largest protocol header */
660extern	struct mbstat	 mbstat;
661extern	u_long		 mbtypes[MT_NTYPES]; /* per-type mbuf allocations */
662extern	int		 mbuf_wait;	/* mbuf sleep time */
663extern	struct mtx	 mbuf_mtx;
664extern	struct mbuf	*mbutl;		/* virtual address of mclusters */
665extern	struct mclfree_lst	mclfree;
666extern	struct mcntfree_lst	mcntfree;
667extern	struct mbffree_lst	mmbfree;
668extern	int		 nmbclusters;
669extern	int		 nmbcnt;
670extern	int		 nmbufs;
671extern	int		 nsfbufs;
672
673void	m_adj(struct mbuf *, int);
674int	m_alloc_ref(u_int, int);
675struct	mbuf *m_aux_add(struct mbuf *, int, int);
676void	m_aux_delete(struct mbuf *, struct mbuf *);
677struct	mbuf *m_aux_find(struct mbuf *, int, int);
678void	m_cat(struct mbuf *, struct mbuf *);
679int	m_clalloc(int, int);
680caddr_t	m_clalloc_wait(void);
681void	m_copyback(struct mbuf *, int, int, caddr_t);
682void	m_copydata(struct mbuf *, int, int, caddr_t);
683struct	mbuf *m_copym(struct mbuf *, int, int, int);
684struct	mbuf *m_copypacket(struct mbuf *, int);
685struct	mbuf *m_devget(char *, int, int, struct ifnet *,
686    void (*copy)(char *, caddr_t, u_int));
687struct	mbuf *m_dup(struct mbuf *, int);
688struct	mbuf *m_free(struct mbuf *);
689void	m_freem(struct mbuf *);
690struct	mbuf *m_get(int, int);
691struct	mbuf *m_getclr(int, int);
692struct	mbuf *m_gethdr(int, int);
693struct	mbuf *m_getm(struct mbuf *, int, int, int);
694int	m_mballoc(int, int);
695struct	mbuf *m_mballoc_wait(void);
696struct	mbuf *m_prepend(struct mbuf *, int, int);
697void	m_print(const struct mbuf *m);
698struct	mbuf *m_pulldown(struct mbuf *, int, int, int *);
699struct	mbuf *m_pullup(struct mbuf *, int);
700struct	mbuf *m_split(struct mbuf *, int, int);
701#endif /* _KERNEL */
702
703#endif /* !_SYS_MBUF_H_ */
704