xref: /openbsd/sys/sys/mbuf.h (revision 181b71c4)
1 /*	$OpenBSD: mbuf.h,v 1.265 2024/11/05 13:15:13 jsg Exp $	*/
2 /*	$NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 1982, 1986, 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
33  */
34 
35 #ifndef _SYS_MBUF_H_
36 #define _SYS_MBUF_H_
37 
38 #include <sys/queue.h>
39 
40 /*
41  * Constants related to network buffer management.
42  * MCLBYTES must be no larger than PAGE_SIZE (the software page size) and,
43  * on machines that exchange pages of input or output buffers with mbuf
44  * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
45  * of the hardware page size.
46  */
47 #define	MSIZE		256		/* size of an mbuf */
48 
49 /*
50  * Mbufs are of a single size, MSIZE, which includes overhead.  An mbuf may
51  * add a single "mbuf cluster" of size MCLBYTES, which has no additional
52  * overhead and is used instead of the internal data area; this is done when
53  * at least MINCLSIZE of data must be stored.
54  */
55 
56 #define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
57 #define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
58 
59 #define	MAXMCLBYTES	(64 * 1024)		/* largest cluster from the stack */
60 #define	MINCLSIZE	(MHLEN + MLEN + 1)	/* smallest amount to put in cluster */
61 
62 #define	MCLSHIFT	11		/* convert bytes to m_buf clusters */
63 					/* 2K cluster can hold Ether frame */
64 #define	MCLBYTES	(1 << MCLSHIFT)	/* size of a m_buf cluster */
65 
66 /* Packet tags structure */
67 struct m_tag {
68 	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */
69 	u_int16_t		m_tag_id;	/* Tag ID */
70 	u_int16_t		m_tag_len;	/* Length of data */
71 };
72 
73 /*
74  * Macros for type conversion
75  * mtod(m,t) -	convert mbuf pointer to data pointer of correct type
76  */
77 #define	mtod(m,t)	((t)((m)->m_data))
78 
79 /* header at beginning of each mbuf: */
80 struct m_hdr {
81 	struct	mbuf *mh_next;		/* next buffer in chain */
82 	struct	mbuf *mh_nextpkt;	/* next chain in queue/record */
83 	caddr_t	mh_data;		/* location of data */
84 	u_int	mh_len;			/* amount of data in this mbuf */
85 	short	mh_type;		/* type of data in this mbuf */
86 	u_short	mh_flags;		/* flags; see below */
87 #ifndef __LP64__
88 	u_int	mh_pad;			/* pad to 8-byte boundary */
89 #endif
90 };
91 
92 /* pf stuff */
93 struct pf_state_key;
94 struct inpcb;
95 
96 struct pkthdr_pf {
97 	struct pf_state_key *statekey;	/* pf stackside statekey */
98 	struct inpcb	*inp;		/* connected pcb for outgoing packet */
99 	u_int32_t	 qid;		/* queue id */
100 	u_int16_t	 tag;		/* tag id */
101 	u_int16_t	 delay;		/* delay packet by X ms */
102 	u_int8_t	 flags;
103 	u_int8_t	 routed;
104 	u_int8_t	 prio;
105 	u_int8_t	 pad[1];
106 };
107 
108 /* pkthdr_pf.flags */
109 #define	PF_TAG_GENERATED		0x01
110 #define	PF_TAG_SYNCOOKIE_RECREATED	0x02
111 #define	PF_TAG_TRANSLATE_LOCALHOST	0x04
112 #define	PF_TAG_DIVERTED			0x08
113 #define	PF_TAG_DIVERTED_PACKET		0x10
114 #define	PF_TAG_REROUTE			0x20
115 #define	PF_TAG_REFRAGMENTED		0x40	/* refragmented ipv6 packet */
116 #define	PF_TAG_PROCESSED		0x80	/* packet was checked by pf */
117 
118 #ifdef _KERNEL
119 #define MPF_BITS \
120     ("\20\1GENERATED\2SYNCOOKIE_RECREATED\3TRANSLATE_LOCALHOST\4DIVERTED" \
121     "\5DIVERTED_PACKET\6REROUTE\7REFRAGMENTED\10PROCESSED")
122 #endif
123 
124 /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
125 struct	pkthdr {
126 	void			*ph_cookie;	/* additional data */
127 	SLIST_HEAD(, m_tag)	 ph_tags;	/* list of packet tags */
128 	int64_t			 ph_timestamp;	/* packet timestamp */
129 	int			 len;		/* total packet length */
130 	u_int			 ph_rtableid;	/* routing table id */
131 	u_int			 ph_ifidx;	/* rcv interface index */
132 	u_int16_t		 ph_tagsset;	/* mtags attached */
133 	u_int16_t		 ph_flowid;	/* pseudo unique flow id */
134 	u_int16_t		 csum_flags;	/* checksum flags */
135 	u_int16_t		 ether_vtag;	/* Ethernet 802.1p+Q vlan tag */
136 	u_int16_t		 ph_mss;	/* TCP max segment size */
137 	u_int8_t		 ph_loopcnt;	/* mbuf is looping in kernel */
138 	u_int8_t		 ph_family;	/* af, used when queueing */
139 	struct pkthdr_pf	 pf;
140 };
141 
142 /* description of external storage mapped into mbuf, valid if M_EXT set */
143 struct mbuf_ext {
144 	caddr_t	ext_buf;		/* start of buffer */
145 	void	*ext_arg;
146 	u_int	ext_free_fn;		/* index of free function */
147 	u_int	ext_size;		/* size of buffer, for ext_free_fn */
148 	struct mbuf *ext_nextref;
149 	struct mbuf *ext_prevref;
150 #ifdef DEBUG
151 	const char *ext_ofile;
152 	const char *ext_nfile;
153 	int ext_oline;
154 	int ext_nline;
155 #endif
156 };
157 
158 struct mbuf {
159 	struct	m_hdr m_hdr;
160 	union {
161 		struct {
162 			struct	pkthdr MH_pkthdr;	/* M_PKTHDR set */
163 			union {
164 				struct	mbuf_ext MH_ext; /* M_EXT set */
165 				char	MH_databuf[MHLEN];
166 			} MH_dat;
167 		} MH;
168 		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
169 	} M_dat;
170 };
171 #define	m_next		m_hdr.mh_next
172 #define	m_len		m_hdr.mh_len
173 #define	m_data		m_hdr.mh_data
174 #define	m_type		m_hdr.mh_type
175 #define	m_flags		m_hdr.mh_flags
176 #define	m_nextpkt	m_hdr.mh_nextpkt
177 #define	m_pkthdr	M_dat.MH.MH_pkthdr
178 #define	m_ext		M_dat.MH.MH_dat.MH_ext
179 #define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
180 #define	m_dat		M_dat.M_databuf
181 
182 /* mbuf flags */
183 #define	M_EXT		0x0001	/* has associated external storage */
184 #define	M_PKTHDR	0x0002	/* start of record */
185 #define	M_EOR		0x0004	/* end of record */
186 #define M_EXTWR		0x0008	/* external storage is writable */
187 #define	M_PROTO1	0x0010	/* protocol-specific */
188 
189 /* mbuf pkthdr flags, also in m_flags */
190 #define M_VLANTAG	0x0020	/* ether_vtag is valid */
191 #define M_LOOP		0x0040	/* packet has been sent from local machine */
192 #define M_BCAST		0x0100	/* sent/received as link-level broadcast */
193 #define M_MCAST		0x0200	/* sent/received as link-level multicast */
194 #define M_CONF		0x0400  /* payload was encrypted (ESP-transport) */
195 #define M_AUTH		0x0800  /* payload was authenticated (AH or ESP auth) */
196 #define M_TUNNEL	0x1000  /* IP-in-IP added by tunnel mode IPsec */
197 #define M_ZEROIZE	0x2000  /* Zeroize data part on free */
198 #define M_COMP		0x4000  /* header was decompressed */
199 #define M_LINK0		0x8000	/* link layer specific flag */
200 
201 #ifdef _KERNEL
202 #define M_BITS \
203     ("\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_EXTWR\5M_PROTO1\6M_VLANTAG\7M_LOOP" \
204     "\11M_BCAST\12M_MCAST\13M_CONF\14M_AUTH\15M_TUNNEL" \
205     "\16M_ZEROIZE\17M_COMP\20M_LINK0")
206 #endif
207 
208 /* flags copied when copying m_pkthdr */
209 #define	M_COPYFLAGS	(M_PKTHDR|M_EOR|M_PROTO1|M_BCAST|M_MCAST|M_CONF|M_COMP|\
210 			 M_AUTH|M_LOOP|M_TUNNEL|M_LINK0|M_VLANTAG|M_ZEROIZE)
211 
212 /* Checksumming flags */
213 #define	M_IPV4_CSUM_OUT		0x0001	/* IPv4 checksum needed */
214 #define	M_TCP_CSUM_OUT		0x0002	/* TCP checksum needed */
215 #define	M_UDP_CSUM_OUT		0x0004	/* UDP checksum needed */
216 #define	M_IPV4_CSUM_IN_OK	0x0008	/* IPv4 checksum verified */
217 #define	M_IPV4_CSUM_IN_BAD	0x0010	/* IPv4 checksum bad */
218 #define	M_TCP_CSUM_IN_OK	0x0020	/* TCP checksum verified */
219 #define	M_TCP_CSUM_IN_BAD	0x0040	/* TCP checksum bad */
220 #define	M_UDP_CSUM_IN_OK	0x0080	/* UDP checksum verified */
221 #define	M_UDP_CSUM_IN_BAD	0x0100	/* UDP checksum bad */
222 #define	M_ICMP_CSUM_OUT		0x0200	/* ICMP/ICMPv6 checksum needed */
223 #define	M_ICMP_CSUM_IN_OK	0x0400	/* ICMP/ICMPv6 checksum verified */
224 #define	M_ICMP_CSUM_IN_BAD	0x0800	/* ICMP/ICMPv6 checksum bad */
225 #define	M_IPV6_DF_OUT		0x1000	/* don't fragment outgoing IPv6 */
226 #define	M_TIMESTAMP		0x2000	/* ph_timestamp is set */
227 #define	M_FLOWID		0x4000	/* ph_flowid is set */
228 #define	M_TCP_TSO		0x8000	/* TCP Segmentation Offload needed */
229 
230 #ifdef _KERNEL
231 #define MCS_BITS \
232     ("\20\1IPV4_CSUM_OUT\2TCP_CSUM_OUT\3UDP_CSUM_OUT\4IPV4_CSUM_IN_OK" \
233     "\5IPV4_CSUM_IN_BAD\6TCP_CSUM_IN_OK\7TCP_CSUM_IN_BAD\10UDP_CSUM_IN_OK" \
234     "\11UDP_CSUM_IN_BAD\12ICMP_CSUM_OUT\13ICMP_CSUM_IN_OK\14ICMP_CSUM_IN_BAD" \
235     "\15IPV6_NODF_OUT" "\16TIMESTAMP" "\17FLOWID" "\20TCP_TSO")
236 #endif
237 
238 /* mbuf types */
239 #define	MT_FREE		0	/* should be on free list */
240 #define	MT_DATA		1	/* dynamic (data) allocation */
241 #define	MT_HEADER	2	/* packet header */
242 #define	MT_SONAME	3	/* socket name */
243 #define	MT_SOOPTS	4	/* socket options */
244 #define	MT_FTABLE	5	/* fragment reassembly header */
245 #define	MT_CONTROL	6	/* extra-data protocol message */
246 #define	MT_OOBDATA	7	/* expedited data  */
247 #define	MT_NTYPES	8
248 
249 /* flags to m_get/MGET */
250 #include <sys/malloc.h>
251 #define	M_DONTWAIT	M_NOWAIT
252 #define	M_WAIT		M_WAITOK
253 
254 /*
255  * mbuf allocation/deallocation macros:
256  *
257  *	MGET(struct mbuf *m, int how, int type)
258  * allocates an mbuf and initializes it to contain internal data.
259  *
260  *	MGETHDR(struct mbuf *m, int how, int type)
261  * allocates an mbuf and initializes it to contain a packet header
262  * and internal data.
263  */
264 #define MGET(m, how, type) m = m_get((how), (type))
265 
266 #define MGETHDR(m, how, type) m = m_gethdr((how), (type))
267 
268 /*
269  * Macros for tracking external storage associated with an mbuf.
270  */
271 #ifdef DEBUG
272 #define MCLREFDEBUGN(m, file, line) do {				\
273 		(m)->m_ext.ext_nfile = (file);				\
274 		(m)->m_ext.ext_nline = (line);				\
275 	} while (/* CONSTCOND */ 0)
276 #define MCLREFDEBUGO(m, file, line) do {				\
277 		(m)->m_ext.ext_ofile = (file);				\
278 		(m)->m_ext.ext_oline = (line);				\
279 	} while (/* CONSTCOND */ 0)
280 #else
281 #define MCLREFDEBUGN(m, file, line)
282 #define MCLREFDEBUGO(m, file, line)
283 #endif
284 
285 #define	MCLISREFERENCED(m)	((m)->m_ext.ext_nextref != (m))
286 
287 #define	MCLADDREFERENCE(o, n)	m_extref((o), (n))
288 
289 #define	MCLINITREFERENCE(m)	do {					\
290 		(m)->m_ext.ext_prevref = (m);				\
291 		(m)->m_ext.ext_nextref = (m);				\
292 		MCLREFDEBUGO((m), __FILE__, __LINE__);			\
293 		MCLREFDEBUGN((m), NULL, 0);				\
294 	} while (/* CONSTCOND */ 0)
295 
296 /*
297  * Macros for mbuf external storage.
298  *
299  * MEXTADD adds pre-allocated external storage to
300  * a normal mbuf; the flag M_EXT is set.
301  *
302  * MCLGET allocates and adds an mbuf cluster to a normal mbuf;
303  * the flag M_EXT is set upon success.
304  */
305 #define	MEXTADD(m, buf, size, mflags, freefn, arg) do {			\
306 	(m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf);		\
307 	(m)->m_flags |= M_EXT | (mflags & M_EXTWR);			\
308 	(m)->m_ext.ext_size = (size);					\
309 	(m)->m_ext.ext_free_fn = (freefn);					\
310 	(m)->m_ext.ext_arg = (arg);					\
311 	MCLINITREFERENCE(m);						\
312 } while (/* CONSTCOND */ 0)
313 
314 #define MCLGET(m, how) (void) m_clget((m), (how), MCLBYTES)
315 #define MCLGETL(m, how, l) m_clget((m), (how), (l))
316 
317 u_int mextfree_register(void (*)(caddr_t, u_int, void *));
318 #define	MEXTFREE_POOL 0
319 
320 /*
321  * Move just m_pkthdr from from to to,
322  * remove M_PKTHDR and clean flags/tags for from.
323  */
324 #define M_MOVE_HDR(to, from) do {					\
325 	(to)->m_pkthdr = (from)->m_pkthdr;				\
326 	(from)->m_flags &= ~M_PKTHDR;					\
327 	SLIST_INIT(&(from)->m_pkthdr.ph_tags);				\
328 	(from)->m_pkthdr.pf.statekey = NULL;				\
329 } while (/* CONSTCOND */ 0)
330 
331 /*
332  * MOVE mbuf pkthdr from from to to.
333  * from must have M_PKTHDR set, and to must be empty.
334  */
335 #define	M_MOVE_PKTHDR(to, from) do {					\
336 	(to)->m_flags = ((to)->m_flags & (M_EXT | M_EXTWR));		\
337 	(to)->m_flags |= (from)->m_flags & M_COPYFLAGS;			\
338 	M_MOVE_HDR((to), (from));					\
339 	if (((to)->m_flags & M_EXT) == 0)				\
340 		(to)->m_data = (to)->m_pktdat;				\
341 } while (/* CONSTCOND */ 0)
342 
343 /*
344  * Determine if an mbuf's data area is read-only. This is true for
345  * non-cluster external storage and for clusters that are being
346  * referenced by more than one mbuf.
347  */
348 #define	M_READONLY(m)							\
349 	(((m)->m_flags & M_EXT) != 0 &&					\
350 	  (((m)->m_flags & M_EXTWR) == 0 || MCLISREFERENCED(m)))
351 
352 /*
353  * Arrange to prepend space of size plen to mbuf m.
354  * If a new mbuf must be allocated, how specifies whether to wait.
355  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
356  * is freed and m is set to NULL.
357  */
358 #define	M_PREPEND(m, plen, how) \
359 		(m) = m_prepend((m), (plen), (how))
360 
361 /* length to m_copy to copy all */
362 #define	M_COPYALL	1000000000
363 
364 #define MBSTAT_TYPES		MT_NTYPES
365 #define MBSTAT_DROPS		(MBSTAT_TYPES + 0)
366 #define MBSTAT_WAIT		(MBSTAT_TYPES + 1)
367 #define MBSTAT_DRAIN		(MBSTAT_TYPES + 2)
368 #define MBSTAT_DEFRAG_ALLOC	(MBSTAT_TYPES + 3)
369 #define MBSTAT_PREPEND_ALLOC	(MBSTAT_TYPES + 4)
370 #define MBSTAT_PULLUP_ALLOC	(MBSTAT_TYPES + 5)
371 #define MBSTAT_PULLUP_COPY	(MBSTAT_TYPES + 6)
372 #define MBSTAT_PULLDOWN_ALLOC	(MBSTAT_TYPES + 7)
373 #define MBSTAT_PULLDOWN_COPY	(MBSTAT_TYPES + 8)
374 #define MBSTAT_COUNT		(MBSTAT_TYPES + 9)
375 
376 /*
377  * Mbuf statistics.
378  * For statistics related to mbuf and cluster allocations, see also the
379  * pool headers (mbpool and mclpool).
380  */
381 struct mbstat {
382 	u_long	m_drops;	/* times failed to find space */
383 	u_long	m_wait;		/* times waited for space */
384 	u_long	m_drain;	/* times drained protocols for space */
385 	u_long	m_mtypes[MBSTAT_TYPES];
386 				/* type specific mbuf allocations */
387 	u_long	m_defrag_alloc;
388 	u_long	m_prepend_alloc;
389 	u_long	m_pullup_alloc;
390 	u_long	m_pullup_copy;
391 	u_long	m_pulldown_alloc;
392 	u_long	m_pulldown_copy;
393 };
394 
395 #include <sys/mutex.h>
396 
397 struct mbuf_list {
398 	struct mbuf		*ml_head;
399 	struct mbuf		*ml_tail;
400 	u_int			ml_len;
401 };
402 
403 struct mbuf_queue {
404 	struct mutex		mq_mtx;
405 	struct mbuf_list	mq_list;
406 	u_int			mq_maxlen;
407 	u_int			mq_drops;
408 };
409 
410 #ifdef	_KERNEL
411 struct pool;
412 
413 extern	long nmbclust;			/* limit on the # of clusters */
414 extern	int max_linkhdr;		/* largest link-level header */
415 extern	int max_protohdr;		/* largest protocol header */
416 extern	int max_hdr;			/* largest link+protocol header */
417 extern	struct cpumem *mbstat;		/* mbuf statistics counter */
418 
419 void	mbinit(void);
420 void	mbcpuinit(void);
421 int	nmbclust_update(long);
422 struct	mbuf *m_copym(struct mbuf *, int, int, int);
423 struct	mbuf *m_free(struct mbuf *);
424 struct	mbuf *m_get(int, int);
425 struct	mbuf *m_getclr(int, int);
426 struct	mbuf *m_gethdr(int, int);
427 struct	mbuf *m_inithdr(struct mbuf *);
428 void	m_removehdr(struct mbuf *);
429 void	m_resethdr(struct mbuf *);
430 void	m_calchdrlen(struct mbuf *);
431 int	m_defrag(struct mbuf *, int);
432 struct	mbuf *m_prepend(struct mbuf *, int, int);
433 struct	mbuf *m_pulldown(struct mbuf *, int, int, int *);
434 struct	mbuf *m_pullup(struct mbuf *, int);
435 struct	mbuf *m_split(struct mbuf *, int, int);
436 struct	mbuf *m_makespace(struct mbuf *, int, int, int *);
437 struct  mbuf *m_getptr(struct mbuf *, int, int *);
438 int	m_leadingspace(struct mbuf *);
439 int	m_trailingspace(struct mbuf *);
440 void	m_align(struct mbuf *, int);
441 struct mbuf *m_clget(struct mbuf *, int, u_int);
442 void	m_extref(struct mbuf *, struct mbuf *);
443 void	m_pool_init(struct pool *, u_int, u_int, const char *);
444 u_int	m_pool_used(void);
445 void	m_extfree_pool(caddr_t, u_int, void *);
446 void	m_adj(struct mbuf *, int);
447 int	m_copyback(struct mbuf *, int, int, const void *, int);
448 struct mbuf *m_freem(struct mbuf *);
449 void	m_purge(struct mbuf *);
450 void	m_copydata(struct mbuf *, int, int, void *);
451 void	m_cat(struct mbuf *, struct mbuf *);
452 struct mbuf *m_devget(char *, int, int);
453 int	m_apply(struct mbuf *, int, int,
454 	    int (*)(caddr_t, caddr_t, unsigned int), caddr_t);
455 struct mbuf *m_dup_pkt(struct mbuf *, unsigned int, int);
456 int	m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
457 
458 void	m_microtime(const struct mbuf *, struct timeval *);
459 
460 static inline struct mbuf *
m_freemp(struct mbuf ** mp)461 m_freemp(struct mbuf **mp)
462 {
463 	struct mbuf *m = *mp;
464 
465 	*mp = NULL;
466 	return m_freem(m);
467 }
468 
469 /* Packet tag routines */
470 struct m_tag *m_tag_get(int, int, int);
471 void	m_tag_prepend(struct mbuf *, struct m_tag *);
472 void	m_tag_delete(struct mbuf *, struct m_tag *);
473 void	m_tag_delete_chain(struct mbuf *);
474 struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
475 struct m_tag *m_tag_copy(struct m_tag *, int);
476 int	m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
477 void	m_tag_init(struct mbuf *);
478 struct m_tag *m_tag_first(struct mbuf *);
479 struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
480 
481 /* Packet tag types */
482 #define PACKET_TAG_IPSEC_IN_DONE	0x0001  /* IPsec applied, in */
483 #define PACKET_TAG_IPSEC_OUT_DONE	0x0002  /* IPsec applied, out */
484 #define PACKET_TAG_IPSEC_FLOWINFO	0x0004	/* IPsec flowinfo */
485 #define PACKET_TAG_IP_OFFNXT		0x0010  /* IPv4 offset and next proto */
486 #define PACKET_TAG_IP6_OFFNXT		0x0020  /* IPv6 offset and next proto */
487 #define PACKET_TAG_WIREGUARD		0x0040  /* WireGuard data */
488 #define PACKET_TAG_GRE			0x0080  /* GRE processing done */
489 #define PACKET_TAG_DLT			0x0100 /* data link layer type */
490 #define PACKET_TAG_PF_DIVERT		0x0200 /* pf(4) diverted packet */
491 #define PACKET_TAG_PF_REASSEMBLED	0x0800 /* pf reassembled ipv6 packet */
492 #define PACKET_TAG_SRCROUTE		0x1000 /* IPv4 source routing options */
493 #define PACKET_TAG_TUNNEL		0x2000	/* Tunnel endpoint address */
494 #define PACKET_TAG_CARP_BAL_IP		0x4000  /* carp(4) ip balanced marker */
495 
496 #define MTAG_BITS \
497     ("\20\1IPSEC_IN_DONE\2IPSEC_OUT_DONE\3IPSEC_FLOWINFO" \
498     "\4IPSEC_OUT_CRYPTO_NEEDED\5IPSEC_PENDING_TDB\6BRIDGE\7WG\10GRE\11DLT" \
499     "\12PF_DIVERT\14PF_REASSEMBLED\15SRCROUTE\16TUNNEL\17CARP_BAL_IP")
500 
501 /*
502  * Maximum tag payload length (that is excluding the m_tag structure).
503  * Please make sure to update this value when increasing the payload
504  * length for an existing packet tag type or when adding a new one that
505  * has payload larger than the value below.
506  */
507 #define PACKET_TAG_MAXSIZE		80
508 
509 /* Detect mbufs looping in the kernel when spliced too often. */
510 #define M_MAXLOOP	128
511 
512 /*
513  * mbuf lists
514  */
515 
516 #define MBUF_LIST_INITIALIZER() { NULL, NULL, 0 }
517 
518 void			ml_init(struct mbuf_list *);
519 void			ml_enqueue(struct mbuf_list *, struct mbuf *);
520 struct mbuf *		ml_dequeue(struct mbuf_list *);
521 void			ml_enlist(struct mbuf_list *, struct mbuf_list *);
522 struct mbuf *		ml_dechain(struct mbuf_list *);
523 unsigned int		ml_purge(struct mbuf_list *);
524 unsigned int		ml_hdatalen(struct mbuf_list *);
525 
526 #define	ml_len(_ml)		((_ml)->ml_len)
527 #define	ml_empty(_ml)		((_ml)->ml_len == 0)
528 
529 #define MBUF_LIST_FIRST(_ml)	((_ml)->ml_head)
530 #define MBUF_LIST_NEXT(_m)	((_m)->m_nextpkt)
531 
532 #define MBUF_LIST_FOREACH(_ml, _m)					\
533 	for ((_m) = MBUF_LIST_FIRST(_ml);				\
534 	    (_m) != NULL;						\
535 	    (_m) = MBUF_LIST_NEXT(_m))
536 
537 /*
538  * mbuf queues
539  */
540 
541 #include <sys/atomic.h>
542 
543 #define MBUF_QUEUE_INITIALIZER(_maxlen, _ipl) \
544     { MUTEX_INITIALIZER(_ipl), MBUF_LIST_INITIALIZER(), (_maxlen), 0 }
545 
546 void			mq_init(struct mbuf_queue *, u_int, int);
547 int			mq_push(struct mbuf_queue *, struct mbuf *);
548 int			mq_enqueue(struct mbuf_queue *, struct mbuf *);
549 struct mbuf *		mq_dequeue(struct mbuf_queue *);
550 int			mq_enlist(struct mbuf_queue *, struct mbuf_list *);
551 void			mq_delist(struct mbuf_queue *, struct mbuf_list *);
552 struct mbuf *		mq_dechain(struct mbuf_queue *);
553 unsigned int		mq_purge(struct mbuf_queue *);
554 unsigned int		mq_hdatalen(struct mbuf_queue *);
555 void			mq_set_maxlen(struct mbuf_queue *, u_int);
556 
557 #define mq_len(_mq)		READ_ONCE((_mq)->mq_list.ml_len)
558 #define mq_empty(_mq)		(mq_len(_mq) == 0)
559 #define mq_full(_mq)		(mq_len((_mq)) >= READ_ONCE((_mq)->mq_maxlen))
560 #define mq_drops(_mq)		READ_ONCE((_mq)->mq_drops)
561 
562 #endif /* _KERNEL */
563 #endif /* _SYS_MBUF_H_ */
564