xref: /netbsd/sys/sys/mbuf.h (revision c4a72b64)
1 /*	$NetBSD: mbuf.h,v 1.68 2002/12/01 22:57:17 matt Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997, 1999, 2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1996 Matt Thomas.  All rights reserved.
42  * Copyright (c) 1982, 1986, 1988, 1993
43  *	The Regents of the University of California.  All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  * 1. Redistributions of source code must retain the above copyright
49  *    notice, this list of conditions and the following disclaimer.
50  * 2. Redistributions in binary form must reproduce the above copyright
51  *    notice, this list of conditions and the following disclaimer in the
52  *    documentation and/or other materials provided with the distribution.
53  * 3. All advertising materials mentioning features or use of this software
54  *    must display the following acknowledgement:
55  *	This product includes software developed by the University of
56  *	California, Berkeley and its contributors.
57  * 4. Neither the name of the University nor the names of its contributors
58  *    may be used to endorse or promote products derived from this software
59  *    without specific prior written permission.
60  *
61  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71  * SUCH DAMAGE.
72  *
73  *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
74  */
75 
76 #ifndef _SYS_MBUF_H_
77 #define _SYS_MBUF_H_
78 
79 #ifndef M_WAITOK
80 #include <sys/malloc.h>
81 #endif
82 #include <sys/pool.h>
83 
84 /*
85  * Mbufs are of a single size, MSIZE (machine/param.h), which
86  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
87  * MCLBYTES (also in machine/param.h), which has no additional overhead
88  * and is used instead of the internal data area; this is done when
89  * at least MINCLSIZE of data must be stored.
90  */
91 
92 #define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
93 #define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
94 
95 #define	MINCLSIZE	(MHLEN+MLEN+1)	/* smallest amount to put in cluster */
96 #define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */
97 
98 /*
99  * Macros for type conversion
100  * mtod(m,t) -	convert mbuf pointer to data pointer of correct type
101  */
102 #define	mtod(m,t)	((t)((m)->m_data))
103 
104 /* header at beginning of each mbuf: */
105 struct m_hdr {
106 	struct	mbuf *mh_next;		/* next buffer in chain */
107 	struct	mbuf *mh_nextpkt;	/* next chain in queue/record */
108 	caddr_t	mh_data;		/* location of data */
109 	int	mh_len;			/* amount of data in this mbuf */
110 	short	mh_type;		/* type of data in this mbuf */
111 	short	mh_flags;		/* flags; see below */
112 };
113 
114 /*
115  * record/packet header in first mbuf of chain; valid if M_PKTHDR set
116  *
117  * A note about csum_data: For the out-bound direction, this indicates the
118  * offset after the L4 header where the final L4 checksum value is to be
119  * stored.  For the in-bound direction, it is only valid if the M_CSUM_DATA
120  * flag is set.  In this case, an L4 checksum has been calculated by
121  * hardware, but it is up to software to perform final verification.
122  *
123  * Note for in-bound TCP/UDP checksums, we expect the csum_data to NOT
124  * be bit-wise inverted (the final step in the calculation of an IP
125  * checksum) -- this is so we can accumulate the checksum for fragmented
126  * packets during reassembly.
127  */
128 struct	pkthdr {
129 	struct	ifnet *rcvif;		/* rcv interface */
130 	int	len;			/* total packet length */
131 	int	csum_flags;		/* checksum flags */
132 	u_int32_t csum_data;		/* checksum data */
133 	struct mbuf *aux;		/* extra data buffer; ipsec/others */
134 };
135 
136 /*
137  * Note: These bits are carefully arrange so that the compiler can have
138  * a prayer of generating a jump table.
139  */
140 #define	M_CSUM_TCPv4		0x00000001	/* TCP header/payload */
141 #define	M_CSUM_UDPv4		0x00000002	/* UDP header/payload */
142 #define	M_CSUM_TCP_UDP_BAD	0x00000004	/* TCP/UDP checksum bad */
143 #define	M_CSUM_DATA		0x00000008	/* consult csum_data */
144 #define	M_CSUM_TCPv6		0x00000010	/* IPv6 TCP header/payload */
145 #define	M_CSUM_UDPv6		0x00000020	/* IPv6 UDP header/payload */
146 #define	M_CSUM_IPv4		0x00000040	/* IPv4 header */
147 #define	M_CSUM_IPv4_BAD		0x00000080	/* IPv4 header checksum bad */
148 
149 /* description of external storage mapped into mbuf, valid if M_EXT set */
150 struct m_ext {
151 	caddr_t	ext_buf;		/* start of buffer */
152 	void	(*ext_free)		/* free routine if not the usual */
153 		__P((struct mbuf *, caddr_t, u_int, void *));
154 	void	*ext_arg;		/* argument for ext_free */
155 	u_int	ext_size;		/* size of buffer, for ext_free */
156 	int	ext_type;		/* malloc type */
157 	struct mbuf *ext_nextref;
158 	struct mbuf *ext_prevref;
159 #ifdef DEBUG
160 	const char *ext_ofile;
161 	const char *ext_nfile;
162 	int ext_oline;
163 	int ext_nline;
164 #endif
165 };
166 
167 struct mbuf {
168 	struct	m_hdr m_hdr;
169 	union {
170 		struct {
171 			struct	pkthdr MH_pkthdr;	/* M_PKTHDR set */
172 			union {
173 				struct	m_ext MH_ext;	/* M_EXT set */
174 				char	MH_databuf[MHLEN];
175 			} MH_dat;
176 		} MH;
177 		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
178 	} M_dat;
179 };
180 #define	m_next		m_hdr.mh_next
181 #define	m_len		m_hdr.mh_len
182 #define	m_data		m_hdr.mh_data
183 #define	m_type		m_hdr.mh_type
184 #define	m_flags		m_hdr.mh_flags
185 #define	m_nextpkt	m_hdr.mh_nextpkt
186 #define	m_pkthdr	M_dat.MH.MH_pkthdr
187 #define	m_ext		M_dat.MH.MH_dat.MH_ext
188 #define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
189 #define	m_dat		M_dat.M_databuf
190 
191 /* mbuf flags */
192 #define	M_EXT		0x0001	/* has associated external storage */
193 #define	M_PKTHDR	0x0002	/* start of record */
194 #define	M_EOR		0x0004	/* end of record */
195 #define	M_CLUSTER	0x0008	/* external storage is a cluster */
196 
197 /* mbuf pkthdr flags, also in m_flags */
198 #define	M_BCAST		0x0100	/* send/received as link-level broadcast */
199 #define	M_MCAST		0x0200	/* send/received as link-level multicast */
200 #define	M_CANFASTFWD	0x0400	/* used by filters to indicate packet can
201 				   be fast-forwarded */
202 #define M_ANYCAST6	0x0800	/* received as IPv6 anycast */
203 #define	M_LINK0		0x1000	/* link layer specific flag */
204 #define	M_LINK1		0x2000	/* link layer specific flag */
205 #define	M_LINK2		0x4000	/* link layer specific flag */
206 #define M_AUTHIPHDR	0x0010	/* data origin authentication for IP header */
207 #define M_DECRYPTED	0x0020	/* confidentiality */
208 #define M_LOOP		0x0040	/* for Mbuf statistics */
209 #define M_AUTHIPDGM     0x0080  /* data origin authentication */
210 
211 /* flags copied when copying m_pkthdr */
212 #define	M_COPYFLAGS	(M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_ANYCAST6|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM)
213 
214 /* mbuf types */
215 #define	MT_FREE		0	/* should be on free list */
216 #define	MT_DATA		1	/* dynamic (data) allocation */
217 #define	MT_HEADER	2	/* packet header */
218 #define	MT_SONAME	3	/* socket name */
219 #define	MT_SOOPTS	4	/* socket options */
220 #define	MT_FTABLE	5	/* fragment reassembly header */
221 #define MT_CONTROL	6	/* extra-data protocol message */
222 #define MT_OOBDATA	7	/* expedited data  */
223 
224 /* flags to m_get/MGET */
225 #define	M_DONTWAIT	M_NOWAIT
226 #define	M_WAIT		M_WAITOK
227 
228 /*
229  * mbuf utility macros:
230  *
231  *	MBUFLOCK(code)
232  * prevents a section of code from from being interrupted by network
233  * drivers.
234  */
235 #define	MBUFLOCK(code)							\
236 do {									\
237 	int ms = splvm();						\
238 	{ code }							\
239 	splx(ms);							\
240 } while (/* CONSTCOND */ 0)
241 
242 /*
243  * mbuf allocation/deallocation macros:
244  *
245  *	MGET(struct mbuf *m, int how, int type)
246  * allocates an mbuf and initializes it to contain internal data.
247  *
248  *	MGETHDR(struct mbuf *m, int how, int type)
249  * allocates an mbuf and initializes it to contain a packet header
250  * and internal data.
251  *
252  * If 'how' is M_WAIT, these macros (and the corresponding functions)
253  * are guaranteed to return successfully.
254  */
255 #define	MGET(m, how, type)						\
256 do {									\
257 	MBUFLOCK((m) = pool_cache_get(&mbpool_cache,			\
258 	    (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0););		\
259 	if (m) {							\
260 		MBUFLOCK(mbstat.m_mtypes[type]++;);			\
261 		(m)->m_type = (type);					\
262 		(m)->m_next = (struct mbuf *)NULL;			\
263 		(m)->m_nextpkt = (struct mbuf *)NULL;			\
264 		(m)->m_data = (m)->m_dat;				\
265 		(m)->m_flags = 0;					\
266 	}								\
267 } while (/* CONSTCOND */ 0)
268 
269 #define	MGETHDR(m, how, type)						\
270 do {									\
271 	MBUFLOCK((m) = pool_cache_get(&mbpool_cache,			\
272 	    (how) == M_WAIT ? PR_WAITOK|PR_LIMITFAIL : 0););		\
273 	if (m) {							\
274 		MBUFLOCK(mbstat.m_mtypes[type]++;);			\
275 		(m)->m_type = (type);					\
276 		(m)->m_next = (struct mbuf *)NULL;			\
277 		(m)->m_nextpkt = (struct mbuf *)NULL;			\
278 		(m)->m_data = (m)->m_pktdat;				\
279 		(m)->m_flags = M_PKTHDR;				\
280 		(m)->m_pkthdr.csum_flags = 0;				\
281 		(m)->m_pkthdr.csum_data = 0;				\
282 		(m)->m_pkthdr.aux = (struct mbuf *)NULL;		\
283 	}								\
284 } while (/* CONSTCOND */ 0)
285 
286 /*
287  * Macros for tracking external storage associated with an mbuf.
288  *
289  * Note: add and delete reference must be called at splvm().
290  */
291 #ifdef DEBUG
292 #define MCLREFDEBUGN(m, file, line)					\
293 do {									\
294 	(m)->m_ext.ext_nfile = (file);					\
295 	(m)->m_ext.ext_nline = (line);					\
296 } while (/* CONSTCOND */ 0)
297 
298 #define MCLREFDEBUGO(m, file, line)					\
299 do {									\
300 	(m)->m_ext.ext_ofile = (file);					\
301 	(m)->m_ext.ext_oline = (line);					\
302 } while (/* CONSTCOND */ 0)
303 #else
304 #define MCLREFDEBUGN(m, file, line)
305 #define MCLREFDEBUGO(m, file, line)
306 #endif
307 
308 #define	MCLBUFREF(p)
309 #define	MCLISREFERENCED(m)	((m)->m_ext.ext_nextref != (m))
310 #define	_MCLDEREFERENCE(m)						\
311 do {									\
312 	(m)->m_ext.ext_nextref->m_ext.ext_prevref =			\
313 		(m)->m_ext.ext_prevref;					\
314 	(m)->m_ext.ext_prevref->m_ext.ext_nextref =			\
315 		(m)->m_ext.ext_nextref;					\
316 } while (/* CONSTCOND */ 0)
317 
318 #define	_MCLADDREFERENCE(o, n)						\
319 do {									\
320 	(n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER));		\
321 	(n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref;		\
322 	(n)->m_ext.ext_prevref = (o);					\
323 	(o)->m_ext.ext_nextref = (n);					\
324 	(n)->m_ext.ext_nextref->m_ext.ext_prevref = (n);		\
325 	MCLREFDEBUGN((n), __FILE__, __LINE__);				\
326 } while (/* CONSTCOND */ 0)
327 
328 #define	MCLINITREFERENCE(m)						\
329 do {									\
330 	(m)->m_ext.ext_prevref = (m);					\
331 	(m)->m_ext.ext_nextref = (m);					\
332 	MCLREFDEBUGO((m), __FILE__, __LINE__);				\
333 	MCLREFDEBUGN((m), NULL, 0);					\
334 } while (/* CONSTCOND */ 0)
335 
336 #define	MCLADDREFERENCE(o, n)	MBUFLOCK(_MCLADDREFERENCE((o), (n));)
337 
338 /*
339  * Macros for mbuf external storage.
340  *
341  * MCLGET allocates and adds an mbuf cluster to a normal mbuf;
342  * the flag M_EXT is set upon success.
343  *
344  * MEXTMALLOC allocates external storage and adds it to
345  * a normal mbuf; the flag M_EXT is set upon success.
346  *
347  * MEXTADD adds pre-allocated external storage to
348  * a normal mbuf; the flag M_EXT is set upon success.
349  */
350 #define	MCLGET(m, how)							\
351 do {									\
352 	MBUFLOCK(							\
353 		(m)->m_ext.ext_buf =					\
354 		    pool_cache_get(&mclpool_cache, (how) == M_WAIT ?	\
355 			(PR_WAITOK|PR_LIMITFAIL) : 0);			\
356 	);								\
357 	if ((m)->m_ext.ext_buf != NULL) {				\
358 		(m)->m_data = (m)->m_ext.ext_buf;			\
359 		(m)->m_flags |= M_EXT|M_CLUSTER;			\
360 		(m)->m_ext.ext_size = MCLBYTES;				\
361 		(m)->m_ext.ext_free = NULL;				\
362 		(m)->m_ext.ext_arg = NULL;				\
363 		MCLINITREFERENCE(m);					\
364 	}								\
365 } while (/* CONSTCOND */ 0)
366 
367 #define	MEXTMALLOC(m, size, how)					\
368 do {									\
369 	(m)->m_ext.ext_buf =						\
370 	    (caddr_t)malloc((size), mbtypes[(m)->m_type], (how));	\
371 	if ((m)->m_ext.ext_buf != NULL) {				\
372 		(m)->m_data = (m)->m_ext.ext_buf;			\
373 		(m)->m_flags |= M_EXT;					\
374 		(m)->m_flags &= ~M_CLUSTER;				\
375 		(m)->m_ext.ext_size = (size);				\
376 		(m)->m_ext.ext_free = NULL;				\
377 		(m)->m_ext.ext_arg = NULL;				\
378 		(m)->m_ext.ext_type = mbtypes[(m)->m_type];		\
379 		MCLINITREFERENCE(m);					\
380 	}								\
381 } while (/* CONSTCOND */ 0)
382 
383 #define	MEXTADD(m, buf, size, type, free, arg)				\
384 do {									\
385 	(m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf);		\
386 	(m)->m_flags |= M_EXT;						\
387 	(m)->m_flags &= ~M_CLUSTER;					\
388 	(m)->m_ext.ext_size = (size);					\
389 	(m)->m_ext.ext_free = (free);					\
390 	(m)->m_ext.ext_arg = (arg);					\
391 	(m)->m_ext.ext_type = (type);					\
392 	MCLINITREFERENCE(m);						\
393 } while (/* CONSTCOND */ 0)
394 
395 #define	MEXTREMOVE(m)							\
396 do {									\
397 	int _ms_ = splvm(); /* MBUFLOCK */				\
398 	if (MCLISREFERENCED(m)) {					\
399 		_MCLDEREFERENCE(m);					\
400 		splx(_ms_);						\
401 	} else if ((m)->m_flags & M_CLUSTER) {				\
402 		pool_cache_put(&mclpool_cache, (m)->m_ext.ext_buf);	\
403 		splx(_ms_);						\
404 	} else if ((m)->m_ext.ext_free) {				\
405 		/*							\
406 		 * NOTE: We assume that MEXTREMOVE() is called from	\
407 		 * code where it is safe to invoke the free routine	\
408 		 * without the mbuf to perform bookkeeping.		\
409 		 */							\
410 		splx(_ms_);						\
411 		(*((m)->m_ext.ext_free))(NULL, (m)->m_ext.ext_buf,	\
412 		    (m)->m_ext.ext_size, (m)->m_ext.ext_arg);		\
413 	} else {							\
414 		splx(_ms_);						\
415 		free((m)->m_ext.ext_buf, (m)->m_ext.ext_type);		\
416 	}								\
417 	(m)->m_flags &= ~(M_CLUSTER|M_EXT);				\
418 	(m)->m_ext.ext_size = 0;	/* why ??? */			\
419 } while (/* CONSTCOND */ 0)
420 
421 /*
422  * Reset the data pointer on an mbuf.
423  */
424 #define	MRESETDATA(m)							\
425 do {									\
426 	if ((m)->m_flags & M_EXT)					\
427 		(m)->m_data = (m)->m_ext.ext_buf;			\
428 	else if ((m)->m_flags & M_PKTHDR)				\
429 		(m)->m_data = (m)->m_pktdat;				\
430 	else								\
431 		(m)->m_data = (m)->m_dat;				\
432 } while (/* CONSTCOND */ 0)
433 
434 /*
435  * MFREE(struct mbuf *m, struct mbuf *n)
436  * Free a single mbuf and associated external storage.
437  * Place the successor, if any, in n.
438  *
439  * we do need to check non-first mbuf for m_aux, since some of existing
440  * code does not call M_PREPEND properly.
441  * (example: call to bpf_mtap from drivers)
442  */
443 #define	MFREE(m, n)							\
444 	MBUFLOCK(							\
445 		mbstat.m_mtypes[(m)->m_type]--;				\
446 		if (((m)->m_flags & M_PKTHDR) != 0 &&			\
447 		    (m)->m_pkthdr.aux != NULL) {			\
448 			m_freem((m)->m_pkthdr.aux);			\
449 			(m)->m_pkthdr.aux = NULL;			\
450 		}							\
451 		(n) = (m)->m_next;					\
452 		if ((m)->m_flags & M_EXT) {				\
453 			if (MCLISREFERENCED(m)) {			\
454 				_MCLDEREFERENCE(m);			\
455 				pool_cache_put(&mbpool_cache, (m));	\
456 			} else if ((m)->m_flags & M_CLUSTER) {		\
457 				pool_cache_put(&mclpool_cache,		\
458 				    (m)->m_ext.ext_buf);		\
459 				pool_cache_put(&mbpool_cache, (m));	\
460 			} else if ((m)->m_ext.ext_free) {		\
461 				/*					\
462 				 * (*ext_free)() is responsible for	\
463 				 * freeing the mbuf when it is safe.	\
464 				 */					\
465 				(*((m)->m_ext.ext_free))((m),		\
466 				    (m)->m_ext.ext_buf,			\
467 				    (m)->m_ext.ext_size,		\
468 				    (m)->m_ext.ext_arg);		\
469 			} else {					\
470 				free((m)->m_ext.ext_buf,		\
471 				    (m)->m_ext.ext_type);		\
472 				pool_cache_put(&mbpool_cache, (m));	\
473 			}						\
474 		} else							\
475 			pool_cache_put(&mbpool_cache, (m));		\
476 	)
477 
478 /*
479  * Copy mbuf pkthdr from `from' to `to'.
480  * `from' must have M_PKTHDR set, and `to' must be empty.
481  * aux pointer will be moved to `to'.
482  */
483 #define	M_COPY_PKTHDR(to, from)						\
484 do {									\
485 	(to)->m_pkthdr = (from)->m_pkthdr;				\
486 	(from)->m_pkthdr.aux = (struct mbuf *)NULL;			\
487 	(to)->m_flags = (from)->m_flags & M_COPYFLAGS;			\
488 	(to)->m_data = (to)->m_pktdat;					\
489 } while (/* CONSTCOND */ 0)
490 
491 /*
492  * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
493  * an object of the specified size at the end of the mbuf, longword aligned.
494  */
495 #define	M_ALIGN(m, len)							\
496 do {									\
497 	(m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1);		\
498 } while (/* CONSTCOND */ 0)
499 
500 /*
501  * As above, for mbufs allocated with m_gethdr/MGETHDR
502  * or initialized by M_COPY_PKTHDR.
503  */
504 #define	MH_ALIGN(m, len)						\
505 do {									\
506 	(m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1);		\
507 } while (/* CONSTCOND */ 0)
508 
509 /*
510  * Determine if an mbuf's data area is read-only.  This is true
511  * for non-cluster external storage and for clusters that are
512  * being referenced by more than one mbuf.
513  */
514 #define	M_READONLY(m)							\
515 	(((m)->m_flags & M_EXT) != 0 &&					\
516 	  (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m)))
517 
518 /*
519  * Compute the amount of space available
520  * before the current start of data in an mbuf.
521  */
522 #define	_M_LEADINGSPACE(m)						\
523 	((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf :	\
524 	 (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat :	\
525 	 (m)->m_data - (m)->m_dat)
526 
527 #define	M_LEADINGSPACE(m)						\
528 	(M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m)))
529 
530 /*
531  * Compute the amount of space available
532  * after the end of data in an mbuf.
533  */
534 #define	_M_TRAILINGSPACE(m)						\
535 	((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
536 	 ((m)->m_data + (m)->m_len) :					\
537 	 &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
538 
539 #define	M_TRAILINGSPACE(m)						\
540 	(M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m)))
541 
542 /*
543  * Arrange to prepend space of size plen to mbuf m.
544  * If a new mbuf must be allocated, how specifies whether to wait.
545  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
546  * is freed and m is set to NULL.
547  */
548 #define	M_PREPEND(m, plen, how)						\
549 do {									\
550 	if (M_LEADINGSPACE(m) >= (plen)) {				\
551 		(m)->m_data -= (plen);					\
552 		(m)->m_len += (plen);					\
553 	} else								\
554 		(m) = m_prepend((m), (plen), (how));			\
555 	if ((m) && (m)->m_flags & M_PKTHDR)				\
556 		(m)->m_pkthdr.len += (plen);				\
557 } while (/* CONSTCOND */ 0)
558 
559 /* change mbuf to new type */
560 #define MCHTYPE(m, t)							\
561 do {									\
562 	MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \
563 	(m)->m_type = t;						\
564 } while (/* CONSTCOND */ 0)
565 
566 /* length to m_copy to copy all */
567 #define	M_COPYALL	1000000000
568 
569 /* compatibility with 4.3 */
570 #define  m_copy(m, o, l)	m_copym((m), (o), (l), M_DONTWAIT)
571 
572 /*
573  * Allow drivers and/or protocols to use the rcvif member of
574  * PKTHDR mbufs to store private context information.
575  */
576 #define	M_GETCTX(m, t)		((t) (m)->m_pkthdr.rcvif + 0)
577 #define	M_SETCTX(m, c)		((void) ((m)->m_pkthdr.rcvif = (void *) (c)))
578 
579 /*
580  * pkthdr.aux type tags.
581  */
582 struct mauxtag {
583 	int af;
584 	int type;
585 };
586 
587 /*
588  * Mbuf statistics.
589  * For statistics related to mbuf and cluster allocations, see also the
590  * pool headers (mbpool and mclpool).
591  */
592 struct mbstat {
593 	u_long	_m_spare;	/* formerly m_mbufs */
594 	u_long	_m_spare1;	/* formerly m_clusters */
595 	u_long	_m_spare2;	/* spare field */
596 	u_long	_m_spare3;	/* formely m_clfree - free clusters */
597 	u_long	m_drops;	/* times failed to find space */
598 	u_long	m_wait;		/* times waited for space */
599 	u_long	m_drain;	/* times drained protocols for space */
600 	u_short	m_mtypes[256];	/* type specific mbuf allocations */
601 };
602 
603 /*
604  * Mbuf sysctl variables.
605  */
606 #define	MBUF_MSIZE		1	/* int: mbuf base size */
607 #define	MBUF_MCLBYTES		2	/* int: mbuf cluster size */
608 #define	MBUF_NMBCLUSTERS	3	/* int: limit on the # of clusters */
609 #define	MBUF_MBLOWAT		4	/* int: mbuf low water mark */
610 #define	MBUF_MCLLOWAT		5	/* int: mbuf cluster low water mark */
611 #define	MBUF_MAXID		6	/* number of valid MBUF ids */
612 
613 #define	CTL_MBUF_NAMES {						\
614 	{ 0, 0 },							\
615 	{ "msize", CTLTYPE_INT },					\
616 	{ "mclbytes", CTLTYPE_INT },					\
617 	{ "nmbclusters", CTLTYPE_INT },					\
618 	{ "mblowat", CTLTYPE_INT },					\
619 	{ "mcllowat", CTLTYPE_INT },					\
620 }
621 
622 #ifdef	_KERNEL
623 /* always use m_pulldown codepath for KAME IPv6/IPsec */
624 #define PULLDOWN_TEST
625 
626 extern struct mbstat mbstat;
627 extern int	nmbclusters;		/* limit on the # of clusters */
628 extern int	mblowat;		/* mbuf low water mark */
629 extern int	mcllowat;		/* mbuf cluster low water mark */
630 extern int	max_linkhdr;		/* largest link-level header */
631 extern int	max_protohdr;		/* largest protocol header */
632 extern int	max_hdr;		/* largest link+protocol header */
633 extern int	max_datalen;		/* MHLEN - max_hdr */
634 extern const int msize;			/* mbuf base size */
635 extern const int mclbytes;		/* mbuf cluster size */
636 extern const int mbtypes[];		/* XXX */
637 extern struct pool mbpool;
638 extern struct pool mclpool;
639 extern struct pool_cache mbpool_cache;
640 extern struct pool_cache mclpool_cache;
641 
642 struct	mbuf *m_copym __P((struct mbuf *, int, int, int));
643 struct	mbuf *m_copypacket __P((struct mbuf *, int));
644 struct	mbuf *m_devget __P((char *, int, int, struct ifnet *,
645 			    void (*copy)(const void *, void *, size_t)));
646 struct	mbuf *m_dup __P((struct mbuf *, int, int, int));
647 struct	mbuf *m_free __P((struct mbuf *));
648 struct	mbuf *m_get __P((int, int));
649 struct	mbuf *m_getclr __P((int, int));
650 struct	mbuf *m_gethdr __P((int, int));
651 struct	mbuf *m_prepend __P((struct mbuf *,int,int));
652 struct	mbuf *m_pulldown __P((struct mbuf *, int, int, int *));
653 struct	mbuf *m_pullup __P((struct mbuf *, int));
654 struct	mbuf *m_copyup __P((struct mbuf *, int, int));
655 struct	mbuf *m_split __P((struct mbuf *,int,int));
656 void	m_adj __P((struct mbuf *, int));
657 void	m_cat __P((struct mbuf *,struct mbuf *));
658 int	m_mballoc __P((int, int));
659 void	m_copyback __P((struct mbuf *, int, int, caddr_t));
660 void	m_copydata __P((struct mbuf *, int, int, caddr_t));
661 void	m_freem __P((struct mbuf *));
662 void	m_reclaim __P((void *, int));
663 void	mbinit __P((void));
664 
665 struct mbuf *m_aux_add __P((struct mbuf *, int, int));
666 struct mbuf *m_aux_find __P((struct mbuf *, int, int));
667 void m_aux_delete __P((struct mbuf *, struct mbuf *));
668 #endif /* _KERNEL */
669 #endif /* !_SYS_MBUF_H_ */
670 
671 #ifdef _KERNEL
672 #ifdef MBTYPES
673 const int mbtypes[] = {				/* XXX */
674 	M_FREE,		/* MT_FREE	0	should be on free list */
675 	M_MBUF,		/* MT_DATA	1	dynamic (data) allocation */
676 	M_MBUF,		/* MT_HEADER	2	packet header */
677 	M_MBUF,		/* MT_SONAME	3	socket name */
678 	M_SOOPTS,	/* MT_SOOPTS	4	socket options */
679 	M_FTABLE,	/* MT_FTABLE	5	fragment reassembly header */
680 	M_MBUF,		/* MT_CONTROL	6	extra-data protocol message */
681 	M_MBUF,		/* MT_OOBDATA	7	expedited data  */
682 };
683 #undef MBTYPES
684 #else
685 extern const int mbtypes[];
686 #endif /* MBTYPES */
687 #endif /* _KERNEL */
688