| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-3-Clause |
| 3 | * |
| 4 | * Copyright (c) 1982, 1986, 1988, 1993 |
| 5 | *	The Regents of the University of California. |
| 6 | * 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 | |
| 33 | #ifndef _SYS_MBUF_H_ |
| 34 | #define	_SYS_MBUF_H_ |
| 35 | |
| 36 | /* XXX: These includes suck. Sorry! */ |
| 37 | #include <sys/queue.h> |
| 38 | #ifdef _KERNEL |
| 39 | #include <sys/systm.h> |
| 40 | #include <sys/refcount.h> |
| 41 | #include <vm/uma.h> |
| 42 | |
| 43 | #include <sys/sdt.h> |
| 44 | |
| 45 | #define	MBUF_PROBE1(probe, arg0)					\ |
| 46 | 	SDT_PROBE1(sdt, , , probe, arg0) |
| 47 | #define	MBUF_PROBE2(probe, arg0, arg1)					\ |
| 48 | 	SDT_PROBE2(sdt, , , probe, arg0, arg1) |
| 49 | #define	MBUF_PROBE3(probe, arg0, arg1, arg2)				\ |
| 50 | 	SDT_PROBE3(sdt, , , probe, arg0, arg1, arg2) |
| 51 | #define	MBUF_PROBE4(probe, arg0, arg1, arg2, arg3)			\ |
| 52 | 	SDT_PROBE4(sdt, , , probe, arg0, arg1, arg2, arg3) |
| 53 | #define	MBUF_PROBE5(probe, arg0, arg1, arg2, arg3, arg4)		\ |
| 54 | 	SDT_PROBE5(sdt, , , probe, arg0, arg1, arg2, arg3, arg4) |
| 55 | |
| 56 | SDT_PROBE_DECLARE(sdt, , , m__init); |
| 57 | SDT_PROBE_DECLARE(sdt, , , m__gethdr_raw); |
| 58 | SDT_PROBE_DECLARE(sdt, , , m__gethdr); |
| 59 | SDT_PROBE_DECLARE(sdt, , , m__get_raw); |
| 60 | SDT_PROBE_DECLARE(sdt, , , m__get); |
| 61 | SDT_PROBE_DECLARE(sdt, , , m__getcl); |
| 62 | SDT_PROBE_DECLARE(sdt, , , m__getjcl); |
| 63 | SDT_PROBE_DECLARE(sdt, , , m__clget); |
| 64 | SDT_PROBE_DECLARE(sdt, , , m__cljget); |
| 65 | SDT_PROBE_DECLARE(sdt, , , m__cljset); |
| 66 | SDT_PROBE_DECLARE(sdt, , , m__free); |
| 67 | SDT_PROBE_DECLARE(sdt, , , m__freem); |
| 68 | SDT_PROBE_DECLARE(sdt, , , m__freemp); |
| 69 | |
| 70 | #endif /* _KERNEL */ |
| 71 | |
| 72 | /* |
| 73 | * Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead. |
| 74 | * An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in |
| 75 | * sys/param.h), which has no additional overhead and is used instead of the |
| 76 | * internal data area; this is done when at least MINCLSIZE of data must be |
| 77 | * stored. Additionally, it is possible to allocate a separate buffer |
| 78 | * externally and attach it to the mbuf in a way similar to that of mbuf |
| 79 | * clusters. |
| 80 | * |
| 81 | * NB: These calculation do not take actual compiler-induced alignment and |
| 82 | * padding inside the complete struct mbuf into account. Appropriate |
| 83 | * attention is required when changing members of struct mbuf. |
| 84 | * |
| 85 | * MLEN is data length in a normal mbuf. |
| 86 | * MHLEN is data length in an mbuf with pktheader. |
| 87 | * MINCLSIZE is a smallest amount of data that should be put into cluster. |
| 88 | * |
| 89 | * Compile-time assertions in uipc_mbuf.c test these values to ensure that |
| 90 | * they are sensible. |
| 91 | */ |
| 92 | struct mbuf; |
| 93 | #define	MHSIZE		offsetof(struct mbuf, m_dat) |
| 94 | #define	MPKTHSIZE	offsetof(struct mbuf, m_pktdat) |
| 95 | #define	MLEN		((int)(MSIZE - MHSIZE)) |
| 96 | #define	MHLEN		((int)(MSIZE - MPKTHSIZE)) |
| 97 | #define	MINCLSIZE	(MHLEN + 1) |
| 98 | #define	M_NODOM		255 |
| 99 | |
| 100 | #ifdef _KERNEL |
| 101 | /*- |
| 102 | * Macro for type conversion: convert mbuf pointer to data pointer of correct |
| 103 | * type: |
| 104 | * |
| 105 | * mtod(m, t)	-- Convert mbuf pointer to data pointer of correct type. |
| 106 | * mtodo(m, o) -- Same as above but with offset 'o' into data. |
| 107 | */ |
| 108 | #define	mtod(m, t)	((t)((m)->m_data)) |
| 109 | #define	mtodo(m, o)	((void *)(((m)->m_data) + (o))) |
| 110 | |
| 111 | /* |
| 112 | * Argument structure passed to UMA routines during mbuf and packet |
| 113 | * allocations. |
| 114 | */ |
| 115 | struct mb_args { |
| 116 | 	int	flags;	/* Flags for mbuf being allocated */ |
| 117 | 	short	type;	/* Type of mbuf being allocated */ |
| 118 | }; |
| 119 | #endif /* _KERNEL */ |
| 120 | |
| 121 | /* |
| 122 | * Packet tag structure (see below for details). |
| 123 | */ |
| 124 | struct m_tag { |
| 125 | 	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */ |
| 126 | 	u_int16_t		m_tag_id;	/* Tag ID */ |
| 127 | 	u_int16_t		m_tag_len;	/* Length of data */ |
| 128 | 	u_int32_t		m_tag_cookie;	/* ABI/Module ID */ |
| 129 | 	void			(*m_tag_free)(struct m_tag *); |
| 130 | }; |
| 131 | |
| 132 | /* |
| 133 | * Static network interface owned tag. |
| 134 | * Allocated through ifp->if_snd_tag_alloc(). |
| 135 | */ |
| 136 | struct if_snd_tag_sw; |
| 137 | |
| 138 | struct m_snd_tag { |
| 139 | 	struct ifnet *ifp;		/* network interface tag belongs to */ |
| 140 | 	const struct if_snd_tag_sw *sw; |
| 141 | 	volatile u_int refcount; |
| 142 | }; |
| 143 | |
| 144 | /* |
| 145 | * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set. |
| 146 | * Size ILP32: 56 |
| 147 | *	 LP64: 64 |
| 148 | * Compile-time assertions in uipc_mbuf.c test these values to ensure that |
| 149 | * they are correct. |
| 150 | */ |
| 151 | struct pkthdr { |
| 152 | 	union { |
| 153 | 		struct m_snd_tag *snd_tag;	/* send tag, if any */ |
| 154 | 		struct ifnet	*rcvif;		/* rcv interface */ |
| 155 | 		struct { |
| 156 | 			uint16_t rcvidx;	/* rcv interface index ... */ |
| 157 | 			uint16_t rcvgen;	/* ... and generation count */ |
| 158 | 		}; |
| 159 | 	}; |
| 160 | 	union { |
| 161 | 		struct ifnet	*leaf_rcvif;	/* leaf rcv interface */ |
| 162 | 		struct { |
| 163 | 			uint16_t leaf_rcvidx;	/* leaf rcv interface index ... */ |
| 164 | 			uint16_t leaf_rcvgen;	/* ... and generation count */ |
| 165 | 		}; |
| 166 | 	}; |
| 167 | 	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */ |
| 168 | 	int32_t		 len;		/* total packet length */ |
| 169 | |
| 170 | 	/* Layer crossing persistent information. */ |
| 171 | 	uint32_t	 flowid;	/* packet's 4-tuple system */ |
| 172 | 	uint32_t	 csum_flags;	/* checksum and offload features */ |
| 173 | 	uint16_t	 fibnum;	/* this packet should use this fib */ |
| 174 | 	uint8_t		 numa_domain;	/* NUMA domain of recvd pkt */ |
| 175 | 	uint8_t		 rsstype;	/* hash type */ |
| 176 | #if !defined(__LP64__) |
| 177 | 	uint32_t	 pad;		/* pad for 64bit alignment */ |
| 178 | #endif |
| 179 | 	union { |
| 180 | 		uint64_t	rcv_tstmp;	/* timestamp in ns */ |
| 181 | 		struct { |
| 182 | 			uint8_t		 l2hlen;	/* layer 2 hdr len */ |
| 183 | 			uint8_t		 l3hlen;	/* layer 3 hdr len */ |
| 184 | 			uint8_t		 l4hlen;	/* layer 4 hdr len */ |
| 185 | 			uint8_t		 l5hlen;	/* layer 5 hdr len */ |
| 186 | 			uint8_t		 inner_l2hlen; |
| 187 | 			uint8_t		 inner_l3hlen; |
| 188 | 			uint8_t		 inner_l4hlen; |
| 189 | 			uint8_t		 inner_l5hlen; |
| 190 | 		}; |
| 191 | 	}; |
| 192 | 	union { |
| 193 | 		uint8_t eight[8]; |
| 194 | 		uint16_t sixteen[4]; |
| 195 | 		uint32_t thirtytwo[2]; |
| 196 | 		uint64_t sixtyfour[1]; |
| 197 | 		uintptr_t unintptr[1]; |
| 198 | 		void	*ptr; |
| 199 | 	} PH_per; |
| 200 | |
| 201 | 	/* Layer specific non-persistent local storage for reassembly, etc. */ |
| 202 | 	union { |
| 203 | 		union { |
| 204 | 			uint8_t eight[8]; |
| 205 | 			uint16_t sixteen[4]; |
| 206 | 			uint32_t thirtytwo[2]; |
| 207 | 			uint64_t sixtyfour[1]; |
| 208 | 			uintptr_t unintptr[1]; |
| 209 | 			void 	*ptr; |
| 210 | 		} PH_loc; |
| 211 | 		/* Upon allocation: total packet memory consumption. */ |
| 212 | 		u_int	memlen; |
| 213 | 	}; |
| 214 | }; |
| 215 | #define	ether_vtag	PH_per.sixteen[0] |
| 216 | #define tcp_tun_port	PH_per.sixteen[0] /* outbound */ |
| 217 | #define	vt_nrecs	PH_per.sixteen[0]	 /* mld and v6-ND */ |
| 218 | #define	tso_segsz	PH_per.sixteen[1] /* inbound after LRO */ |
| 219 | #define	lro_nsegs	tso_segsz	 /* inbound after LRO */ |
| 220 | #define	csum_data	PH_per.thirtytwo[1] /* inbound from hardware up */ |
| 221 | #define	lro_tcp_d_len	PH_loc.sixteen[0] /* inbound during LRO (no reassembly) */ |
| 222 | #define	lro_tcp_d_csum	PH_loc.sixteen[1] /* inbound during LRO (no reassembly) */ |
| 223 | #define	lro_tcp_h_off	PH_loc.sixteen[2] /* inbound during LRO (no reassembly) */ |
| 224 | #define	lro_etype	PH_loc.sixteen[3] /* inbound during LRO (no reassembly) */ |
| 225 | /* Note PH_loc is used during IP reassembly (all 8 bytes as a ptr) */ |
| 226 | |
| 227 | /* |
| 228 | * TLS records for TLS 1.0-1.2 can have the following header lengths: |
| 229 | * - 5 (AES-CBC with implicit IV) |
| 230 | * - 21 (AES-CBC with explicit IV) |
| 231 | * - 13 (AES-GCM with 8 byte explicit IV) |
| 232 | */ |
| 233 | #define	MBUF_PEXT_HDR_LEN	23 |
| 234 | |
| 235 | /* |
| 236 | * TLS records for TLS 1.0-1.2 can have the following maximum trailer |
| 237 | * lengths: |
| 238 | * - 16 (AES-GCM) |
| 239 | * - 36 (AES-CBC with SHA1 and up to 16 bytes of padding) |
| 240 | * - 48 (AES-CBC with SHA2-256 and up to 16 bytes of padding) |
| 241 | * - 64 (AES-CBC with SHA2-384 and up to 16 bytes of padding) |
| 242 | */ |
| 243 | #define	MBUF_PEXT_TRAIL_LEN	64 |
| 244 | |
| 245 | #if defined(__LP64__) |
| 246 | #define MBUF_PEXT_MAX_PGS (40 / sizeof(vm_paddr_t)) |
| 247 | #else |
| 248 | #define MBUF_PEXT_MAX_PGS (64 / sizeof(vm_paddr_t)) |
| 249 | #endif |
| 250 | |
| 251 | #define	MBUF_PEXT_MAX_BYTES						\ |
| 252 | (MBUF_PEXT_MAX_PGS * PAGE_SIZE + MBUF_PEXT_HDR_LEN + MBUF_PEXT_TRAIL_LEN) |
| 253 | |
| 254 | struct ktls_session; |
| 255 | struct socket; |
| 256 | |
| 257 | /* |
| 258 | * Description of external storage mapped into mbuf; valid only if M_EXT is |
| 259 | * set. |
| 260 | * Size ILP32: 28 |
| 261 | *	 LP64: 48 |
| 262 | * Compile-time assertions in uipc_mbuf.c test these values to ensure that |
| 263 | * they are correct. |
| 264 | */ |
| 265 | typedef	void m_ext_free_t(struct mbuf *); |
| 266 | struct m_ext { |
| 267 | 	union { |
| 268 | 		/* |
| 269 | 		 * If EXT_FLAG_EMBREF is set, then we use refcount in the |
| 270 | 		 * mbuf, the 'ext_count' member. Otherwise, we have a |
| 271 | 		 * shadow copy and we use pointer 'ext_cnt'. The original |
| 272 | 		 * mbuf is responsible to carry the pointer to free routine |
| 273 | 		 * and its arguments. They aren't copied into shadows in |
| 274 | 		 * mb_dupcl() to avoid dereferencing next cachelines. |
| 275 | 		 */ |
| 276 | 		volatile u_int	 ext_count; |
| 277 | 		volatile u_int	*ext_cnt; |
| 278 | 	}; |
| 279 | 	uint32_t	 ext_size;	/* size of buffer, for ext_free */ |
| 280 | 	uint32_t	 ext_type:8,	/* type of external storage */ |
| 281 | 			 ext_flags:24;	/* external storage mbuf flags */ |
| 282 | 	union { |
| 283 | 		struct { |
| 284 | 			/* |
| 285 | 			 * Regular M_EXT mbuf: |
| 286 | 			 * o ext_buf always points to the external buffer. |
| 287 | 			 * o ext_free (below) and two optional arguments |
| 288 | 			 * ext_arg1 and ext_arg2 store the free context for |
| 289 | 			 * the external storage. They are set only in the |
| 290 | 			 * refcount carrying mbuf, the one with |
| 291 | 			 * EXT_FLAG_EMBREF flag, with exclusion for |
| 292 | 			 * EXT_EXTREF type, where the free context is copied |
| 293 | 			 * into all mbufs that use same external storage. |
| 294 | 			 */ |
| 295 | 			char 	*ext_buf;	/* start of buffer */ |
| 296 | #define	m_ext_copylen	offsetof(struct m_ext, ext_arg2) |
| 297 | 			void	*ext_arg2; |
| 298 | 		}; |
| 299 | 		struct { |
| 300 | 			/* |
| 301 | 			 * Multi-page M_EXTPG mbuf: |
| 302 | 			 * o extpg_pa - page vector. |
| 303 | 			 * o extpg_trail and extpg_hdr - TLS trailer and |
| 304 | 			 * header. |
| 305 | 			 * Uses ext_free and may also use ext_arg1. |
| 306 | 			 */ |
| 307 | 			vm_paddr_t	extpg_pa[MBUF_PEXT_MAX_PGS]; |
| 308 | 			char		extpg_trail[MBUF_PEXT_TRAIL_LEN]; |
| 309 | 			char		extpg_hdr[MBUF_PEXT_HDR_LEN]; |
| 310 | 			/* Pretend these 3 fields are part of mbuf itself. */ |
| 311 | #define	m_epg_pa	m_ext.extpg_pa |
| 312 | #define	m_epg_trail	m_ext.extpg_trail |
| 313 | #define	m_epg_hdr	m_ext.extpg_hdr |
| 314 | #define	m_epg_ext_copylen	offsetof(struct m_ext, ext_free) |
| 315 | 		}; |
| 316 | 	}; |
| 317 | 	/* |
| 318 | 	 * Free method and optional argument pointer, both |
| 319 | 	 * used by M_EXT and M_EXTPG. |
| 320 | 	 */ |
| 321 | 	m_ext_free_t	*ext_free; |
| 322 | 	void		*ext_arg1; |
| 323 | }; |
| 324 | |
| 325 | /* |
| 326 | * The core of the mbuf object along with some shortcut defines for practical |
| 327 | * purposes. |
| 328 | */ |
| 329 | struct mbuf { |
| 330 | 	/* |
| 331 | 	 * Header present at the beginning of every mbuf. |
| 332 | 	 * Size ILP32: 24 |
| 333 | 	 * LP64: 32 |
| 334 | 	 * Compile-time assertions in uipc_mbuf.c test these values to ensure |
| 335 | 	 * that they are correct. |
| 336 | 	 */ |
| 337 | 	union {	/* next buffer in chain */ |
| 338 | 		struct mbuf		*m_next; |
| 339 | 		SLIST_ENTRY(mbuf)	m_slist; |
| 340 | 		STAILQ_ENTRY(mbuf)	m_stailq; |
| 341 | 	}; |
| 342 | 	union {	/* next chain in queue/record */ |
| 343 | 		struct mbuf		*m_nextpkt; |
| 344 | 		SLIST_ENTRY(mbuf)	m_slistpkt; |
| 345 | 		STAILQ_ENTRY(mbuf)	m_stailqpkt; |
| 346 | 	}; |
| 347 | 	caddr_t		 m_data;	/* location of data */ |
| 348 | 	int32_t		 m_len;		/* amount of data in this mbuf */ |
| 349 | 	uint32_t	 m_type:8,	/* type of data in this mbuf */ |
| 350 | 			 m_flags:24;	/* flags; see below */ |
| 351 | #if !defined(__LP64__) |
| 352 | 	uint32_t	 m_pad;		/* pad for 64bit alignment */ |
| 353 | #endif |
| 354 | |
| 355 | 	/* |
| 356 | 	 * A set of optional headers (packet header, external storage header) |
| 357 | 	 * and internal data storage. Historically, these arrays were sized |
| 358 | 	 * to MHLEN (space left after a packet header) and MLEN (space left |
| 359 | 	 * after only a regular mbuf header); they are now variable size in |
| 360 | 	 * order to support future work on variable-size mbufs. |
| 361 | 	 */ |
| 362 | 	union { |
| 363 | 		struct { |
| 364 | 			union { |
| 365 | 				/* M_PKTHDR set. */ |
| 366 | 				struct pkthdr	m_pkthdr; |
| 367 | |
| 368 | 				/* M_EXTPG set. |
| 369 | 				 * Multi-page M_EXTPG mbuf has its meta data |
| 370 | 				 * split between the below anonymous structure |
| 371 | 				 * and m_ext. It carries vector of pages, |
| 372 | 				 * optional header and trailer char vectors |
| 373 | 				 * and pointers to socket/TLS data. |
| 374 | 				 */ |
| 375 | #define	m_epg_startcopy		m_epg_npgs |
| 376 | #define	m_epg_endcopy		m_epg_stailq |
| 377 | 				struct { |
| 378 | 					/* Overall count of pages and count of |
| 379 | 					 * pages with I/O pending. */ |
| 380 | 					uint8_t	m_epg_npgs; |
| 381 | 					uint8_t	m_epg_nrdy; |
| 382 | 					/* TLS header and trailer lengths. |
| 383 | 					 * The data itself resides in m_ext. */ |
| 384 | 					uint8_t	m_epg_hdrlen; |
| 385 | 					uint8_t	m_epg_trllen; |
| 386 | 					/* Offset into 1st page and length of |
| 387 | 					 * data in the last page. */ |
| 388 | 					uint16_t m_epg_1st_off; |
| 389 | 					uint16_t m_epg_last_len; |
| 390 | 					uint8_t	m_epg_flags; |
| 391 | #define	EPG_FLAG_ANON	0x1	/* Data can be encrypted in place. */ |
| 392 | #define	EPG_FLAG_2FREE	0x2	/* Scheduled for free. */ |
| 393 | 					uint8_t	m_epg_record_type; |
| 394 | 					uint8_t	__spare[2]; |
| 395 | 					int	m_epg_enc_cnt; |
| 396 | 					struct ktls_session *m_epg_tls; |
| 397 | 					struct socket	*m_epg_so; |
| 398 | 					uint64_t	m_epg_seqno; |
| 399 | 					STAILQ_ENTRY(mbuf) m_epg_stailq; |
| 400 | 				}; |
| 401 | 			}; |
| 402 | 			union { |
| 403 | 				/* M_EXT or M_EXTPG set. */ |
| 404 | 				struct m_ext	m_ext; |
| 405 | 				/* M_PKTHDR set, neither M_EXT nor M_EXTPG. */ |
| 406 | 				char		m_pktdat[0]; |
| 407 | 			}; |
| 408 | 		}; |
| 409 | 		char	m_dat[0];			/* !M_PKTHDR, !M_EXT */ |
| 410 | 	}; |
| 411 | }; |
| 412 | |
| 413 | #ifdef _KERNEL |
| 414 | static inline int |
| 415 | m_epg_pagelen(const struct mbuf *m, int pidx, int pgoff) |
| 416 | { |
| 417 | |
| 418 | 	KASSERT(pgoff == 0 || pidx == 0, |
| 419 | 	 ("page %d with non-zero offset %d in %p", pidx, pgoff, m)); |
| 420 | |
| 421 | 	if (pidx == m->m_epg_npgs - 1) { |
| 422 | 		return (m->m_epg_last_len); |
| 423 | 	} else { |
| 424 | 		return (PAGE_SIZE - pgoff); |
| 425 | 	} |
| 426 | } |
| 427 | |
| 428 | #ifdef INVARIANTS |
| 429 | #define	MCHECK(ex, msg)	KASSERT((ex),				\ |
| 430 | 	 ("Multi page mbuf %p with " #msg " at %s:%d",	\ |
| 431 | 	 m, __FILE__, __LINE__)) |
| 432 | /* |
| 433 | * NB: This expects a non-empty buffer (npgs > 0 and |
| 434 | * last_pg_len > 0). |
| 435 | */ |
| 436 | #define	MBUF_EXT_PGS_ASSERT_SANITY(m)	do {				\ |
| 437 | 	MCHECK(m->m_epg_npgs > 0, "no valid pages");		\ |
| 438 | 	MCHECK(m->m_epg_npgs <= nitems(m->m_epg_pa),		\ |
| 439 | 	 "too many pages");						\ |
| 440 | 	MCHECK(m->m_epg_nrdy <= m->m_epg_npgs,			\ |
| 441 | 	 "too many ready pages");					\ |
| 442 | 	MCHECK(m->m_epg_1st_off < PAGE_SIZE,			\ |
| 443 | 		"too large page offset");				\ |
| 444 | 	MCHECK(m->m_epg_last_len > 0, "zero last page length");	\ |
| 445 | 	MCHECK(m->m_epg_last_len <= PAGE_SIZE,			\ |
| 446 | 	 "too large last page length");				\ |
| 447 | 	if (m->m_epg_npgs == 1)					\ |
| 448 | 		MCHECK(m->m_epg_1st_off +			\ |
| 449 | 		 m->m_epg_last_len <=	 PAGE_SIZE,		\ |
| 450 | 		 "single page too large");				\ |
| 451 | 	MCHECK(m->m_epg_hdrlen <= sizeof(m->m_epg_hdr),		\ |
| 452 | 	 "too large header length");					\ |
| 453 | 	MCHECK(m->m_epg_trllen <= sizeof(m->m_epg_trail),	\ |
| 454 | 	 "too large header length");					\ |
| 455 | } while (0) |
| 456 | #else |
| 457 | #define	MBUF_EXT_PGS_ASSERT_SANITY(m)	do {} while (0) |
| 458 | #endif |
| 459 | #endif |
| 460 | |
| 461 | /* |
| 462 | * mbuf flags of global significance and layer crossing. |
| 463 | * Those of only protocol/layer specific significance are to be mapped |
| 464 | * to M_PROTO[1-11] and cleared at layer handoff boundaries. |
| 465 | * NB: Limited to the lower 24 bits. |
| 466 | */ |
| 467 | #define	M_EXT		0x00000001 /* has associated external storage */ |
| 468 | #define	M_PKTHDR	0x00000002 /* start of record */ |
| 469 | #define	M_EOR		0x00000004 /* end of record */ |
| 470 | #define	M_RDONLY	0x00000008 /* associated data is marked read-only */ |
| 471 | #define	M_BCAST		0x00000010 /* send/received as link-level broadcast */ |
| 472 | #define	M_MCAST		0x00000020 /* send/received as link-level multicast */ |
| 473 | #define	M_PROMISC	0x00000040 /* packet was not for us */ |
| 474 | #define	M_VLANTAG	0x00000080 /* ether_vtag is valid */ |
| 475 | #define	M_EXTPG		0x00000100 /* has array of unmapped pages and TLS */ |
| 476 | #define	M_NOFREE	0x00000200 /* do not free mbuf, embedded in cluster */ |
| 477 | #define	M_TSTMP		0x00000400 /* rcv_tstmp field is valid */ |
| 478 | #define	M_TSTMP_HPREC	0x00000800 /* rcv_tstmp is high-prec, typically |
| 479 | 				 hw-stamped on port (useful for IEEE 1588 |
| 480 | 				 and 802.1AS) */ |
| 481 | #define M_TSTMP_LRO	0x00001000 /* Time LRO pushed in pkt is valid in (PH_loc) */ |
| 482 | |
| 483 | #define	M_PROTO1	0x00002000 /* protocol-specific */ |
| 484 | #define	M_PROTO2	0x00004000 /* protocol-specific */ |
| 485 | #define	M_PROTO3	0x00008000 /* protocol-specific */ |
| 486 | #define	M_PROTO4	0x00010000 /* protocol-specific */ |
| 487 | #define	M_PROTO5	0x00020000 /* protocol-specific */ |
| 488 | #define	M_PROTO6	0x00040000 /* protocol-specific */ |
| 489 | #define	M_PROTO7	0x00080000 /* protocol-specific */ |
| 490 | #define	M_PROTO8	0x00100000 /* protocol-specific */ |
| 491 | #define	M_PROTO9	0x00200000 /* protocol-specific */ |
| 492 | #define	M_PROTO10	0x00400000 /* protocol-specific */ |
| 493 | #define	M_PROTO11	0x00800000 /* protocol-specific */ |
| 494 | |
| 495 | /* |
| 496 | * Flags to purge when crossing layers. |
| 497 | */ |
| 498 | #define	M_PROTOFLAGS \ |
| 499 | (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\ |
| 500 | M_PROTO9|M_PROTO10|M_PROTO11) |
| 501 | |
| 502 | /* |
| 503 | * Flags preserved when copying m_pkthdr. |
| 504 | */ |
| 505 | #define M_COPYFLAGS \ |
| 506 | (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_PROMISC|M_VLANTAG|M_TSTMP| \ |
| 507 | M_TSTMP_HPREC|M_TSTMP_LRO|M_PROTOFLAGS) |
| 508 | |
| 509 | /* |
| 510 | * Flags preserved during demote. |
| 511 | */ |
| 512 | #define	M_DEMOTEFLAGS \ |
| 513 | (M_EXT | M_RDONLY | M_NOFREE | M_EXTPG) |
| 514 | |
| 515 | /* |
| 516 | * Mbuf flag description for use with printf(9) %b identifier. |
| 517 | */ |
| 518 | #define	M_FLAG_BITS \ |
| 519 | "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY\5M_BCAST\6M_MCAST" \ |
| 520 | "\7M_PROMISC\10M_VLANTAG\11M_EXTPG\12M_NOFREE\13M_TSTMP\14M_TSTMP_HPREC\15M_TSTMP_LRO" |
| 521 | #define	M_FLAG_PROTOBITS \ |
| 522 | "\16M_PROTO1\17M_PROTO2\20M_PROTO3\21M_PROTO4" \ |
| 523 | "\22M_PROTO5\23M_PROTO6\24M_PROTO7\25M_PROTO8\26M_PROTO9" \ |
| 524 | "\27M_PROTO10\28M_PROTO11" |
| 525 | #define	M_FLAG_PRINTF (M_FLAG_BITS M_FLAG_PROTOBITS) |
| 526 | |
| 527 | /* |
| 528 | * Network interface cards are able to hash protocol fields (such as IPv4 |
| 529 | * addresses and TCP port numbers) classify packets into flows. These flows |
| 530 | * can then be used to maintain ordering while delivering packets to the OS |
| 531 | * via parallel input queues, as well as to provide a stateless affinity |
| 532 | * model. NIC drivers can pass up the hash via m->m_pkthdr.flowid, and set |
| 533 | * m_flag fields to indicate how the hash should be interpreted by the |
| 534 | * network stack. |
| 535 | * |
| 536 | * Most NICs support RSS, which provides ordering and explicit affinity, and |
| 537 | * use the hash m_flag bits to indicate what header fields were covered by |
| 538 | * the hash. M_HASHTYPE_OPAQUE and M_HASHTYPE_OPAQUE_HASH can be set by non- |
| 539 | * RSS cards or configurations that provide an opaque flow identifier, allowing |
| 540 | * for ordering and distribution without explicit affinity. Additionally, |
| 541 | * M_HASHTYPE_OPAQUE_HASH indicates that the flow identifier has hash |
| 542 | * properties. |
| 543 | * |
| 544 | * The meaning of the IPV6_EX suffix: |
| 545 | * "o Home address from the home address option in the IPv6 destination |
| 546 | * options header. If the extension header is not present, use the Source |
| 547 | * IPv6 Address. |
| 548 | * o IPv6 address that is contained in the Routing-Header-Type-2 from the |
| 549 | * associated extension header. If the extension header is not present, |
| 550 | * use the Destination IPv6 Address." |
| 551 | * Quoted from: |
| 552 | * https://docs.microsoft.com/en-us/windows-hardware/drivers/network/rss-hashing-types#ndishashipv6ex |
| 553 | */ |
| 554 | #define	M_HASHTYPE_HASHPROP		0x80	/* has hash properties */ |
| 555 | #define	M_HASHTYPE_INNER		0x40	/* calculated from inner headers */ |
| 556 | #define	M_HASHTYPE_HASH(t)		(M_HASHTYPE_HASHPROP | (t)) |
| 557 | /* Microsoft RSS standard hash types */ |
| 558 | #define	M_HASHTYPE_NONE			0 |
| 559 | #define	M_HASHTYPE_RSS_IPV4		M_HASHTYPE_HASH(1) /* IPv4 2-tuple */ |
| 560 | #define	M_HASHTYPE_RSS_TCP_IPV4		M_HASHTYPE_HASH(2) /* TCPv4 4-tuple */ |
| 561 | #define	M_HASHTYPE_RSS_IPV6		M_HASHTYPE_HASH(3) /* IPv6 2-tuple */ |
| 562 | #define	M_HASHTYPE_RSS_TCP_IPV6		M_HASHTYPE_HASH(4) /* TCPv6 4-tuple */ |
| 563 | #define	M_HASHTYPE_RSS_IPV6_EX		M_HASHTYPE_HASH(5) /* IPv6 2-tuple + |
| 564 | 							 * ext hdrs */ |
| 565 | #define	M_HASHTYPE_RSS_TCP_IPV6_EX	M_HASHTYPE_HASH(6) /* TCPv6 4-tuple + |
| 566 | 							 * ext hdrs */ |
| 567 | #define	M_HASHTYPE_RSS_UDP_IPV4		M_HASHTYPE_HASH(7) /* IPv4 UDP 4-tuple*/ |
| 568 | #define	M_HASHTYPE_RSS_UDP_IPV6		M_HASHTYPE_HASH(9) /* IPv6 UDP 4-tuple*/ |
| 569 | #define	M_HASHTYPE_RSS_UDP_IPV6_EX	M_HASHTYPE_HASH(10)/* IPv6 UDP 4-tuple + |
| 570 | 							 * ext hdrs */ |
| 571 | |
| 572 | #define	M_HASHTYPE_OPAQUE		0x3f	/* ordering, not affinity */ |
| 573 | #define	M_HASHTYPE_OPAQUE_HASH		M_HASHTYPE_HASH(M_HASHTYPE_OPAQUE) |
| 574 | 						/* ordering+hash, not affinity*/ |
| 575 | |
| 576 | #define	M_HASHTYPE_CLEAR(m)	((m)->m_pkthdr.rsstype = 0) |
| 577 | #define	M_HASHTYPE_GET(m)	((m)->m_pkthdr.rsstype & ~M_HASHTYPE_INNER) |
| 578 | #define	M_HASHTYPE_SET(m, v)	((m)->m_pkthdr.rsstype = (v)) |
| 579 | #define	M_HASHTYPE_TEST(m, v)	(M_HASHTYPE_GET(m) == (v)) |
| 580 | #define	M_HASHTYPE_ISHASH(m)	\ |
| 581 | (((m)->m_pkthdr.rsstype & M_HASHTYPE_HASHPROP) != 0) |
| 582 | #define	M_HASHTYPE_SETINNER(m)	do {			\ |
| 583 | 	(m)->m_pkthdr.rsstype |= M_HASHTYPE_INNER;	\ |
| 584 | } while (0) |
| 585 | |
| 586 | /* |
| 587 | * External mbuf storage buffer types. |
| 588 | */ |
| 589 | #define	EXT_CLUSTER	1	/* mbuf cluster */ |
| 590 | #define	EXT_SFBUF	2	/* sendfile(2)'s sf_buf */ |
| 591 | #define	EXT_JUMBOP	3	/* jumbo cluster page sized */ |
| 592 | #define	EXT_JUMBO9	4	/* jumbo cluster 9216 bytes */ |
| 593 | #define	EXT_JUMBO16	5	/* jumbo cluster 16184 bytes */ |
| 594 | #define	EXT_PACKET	6	/* mbuf+cluster from packet zone */ |
| 595 | #define	EXT_MBUF	7	/* external mbuf reference */ |
| 596 | #define	EXT_RXRING	8	/* data in NIC receive ring */ |
| 597 | #define	EXT_CTL		9	/* buffer from a ctl(4) backend */ |
| 598 | |
| 599 | #define	EXT_VENDOR1	224	/* for vendor-internal use */ |
| 600 | #define	EXT_VENDOR2	225	/* for vendor-internal use */ |
| 601 | #define	EXT_VENDOR3	226	/* for vendor-internal use */ |
| 602 | #define	EXT_VENDOR4	227	/* for vendor-internal use */ |
| 603 | |
| 604 | #define	EXT_EXP1	244	/* for experimental use */ |
| 605 | #define	EXT_EXP2	245	/* for experimental use */ |
| 606 | #define	EXT_EXP3	246	/* for experimental use */ |
| 607 | #define	EXT_EXP4	247	/* for experimental use */ |
| 608 | |
| 609 | #define	EXT_NET_DRV	252	/* custom ext_buf provided by net driver(s) */ |
| 610 | #define	EXT_MOD_TYPE	253	/* custom module's ext_buf type */ |
| 611 | #define	EXT_DISPOSABLE	254	/* can throw this buffer away w/page flipping */ |
| 612 | #define	EXT_EXTREF	255	/* has externally maintained ext_cnt ptr */ |
| 613 | |
| 614 | /* |
| 615 | * Flags for external mbuf buffer types. |
| 616 | * NB: limited to the lower 24 bits. |
| 617 | */ |
| 618 | #define	EXT_FLAG_EMBREF		0x000001	/* embedded ext_count */ |
| 619 | #define	EXT_FLAG_EXTREF		0x000002	/* external ext_cnt, notyet */ |
| 620 | |
| 621 | #define	EXT_FLAG_NOFREE		0x000010	/* don't free mbuf to pool, notyet */ |
| 622 | |
| 623 | #define	EXT_FLAG_VENDOR1	0x010000	/* These flags are vendor */ |
| 624 | #define	EXT_FLAG_VENDOR2	0x020000	/* or submodule specific, */ |
| 625 | #define	EXT_FLAG_VENDOR3	0x040000	/* not used by mbuf code. */ |
| 626 | #define	EXT_FLAG_VENDOR4	0x080000	/* Set/read by submodule. */ |
| 627 | |
| 628 | #define	EXT_FLAG_EXP1		0x100000	/* for experimental use */ |
| 629 | #define	EXT_FLAG_EXP2		0x200000	/* for experimental use */ |
| 630 | #define	EXT_FLAG_EXP3		0x400000	/* for experimental use */ |
| 631 | #define	EXT_FLAG_EXP4		0x800000	/* for experimental use */ |
| 632 | |
| 633 | /* |
| 634 | * EXT flag description for use with printf(9) %b identifier. |
| 635 | */ |
| 636 | #define	EXT_FLAG_BITS \ |
| 637 | "\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_NOFREE" \ |
| 638 | "\21EXT_FLAG_VENDOR1\22EXT_FLAG_VENDOR2\23EXT_FLAG_VENDOR3" \ |
| 639 | "\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \ |
| 640 | "\30EXT_FLAG_EXP4" |
| 641 | |
| 642 | /* |
| 643 | * Flags indicating checksum, segmentation and other offload work to be |
| 644 | * done, or already done, by hardware or lower layers. |
| 645 | * |
| 646 | * Flags that are set by upper protocol layers requesting lower |
| 647 | * layers, or ideally the hardware, to perform these offloading tasks. |
| 648 | * Before passing packets to a network interface this field and its flags can |
| 649 | * be directly tested against ifnet if_hwassist. Note that the flags |
| 650 | * CSUM_IP_SCTP, CSUM_IP_TCP, and CSUM_IP_UDP can appear on input processing |
| 651 | * of SCTP, TCP, and UDP. In such a case the checksum will not be computed or |
| 652 | * validated by SCTP, TCP, or TCP, since the packet has not been on the wire. |
| 653 | * |
| 654 | * CSUM_INNER_<x> is the same as CSUM_<x> but it applies to the inner frame. |
| 655 | * The CSUM_ENCAP_<x> bits identify the outer encapsulation. |
| 656 | */ |
| 657 | #define	CSUM_IP			0x00000001	/* IP header checksum offload */ |
| 658 | #define	CSUM_IP_UDP		0x00000002	/* UDP checksum offload */ |
| 659 | #define	CSUM_IP_TCP		0x00000004	/* TCP checksum offload */ |
| 660 | #define	CSUM_IP_SCTP		0x00000008	/* SCTP checksum offload */ |
| 661 | #define	CSUM_IP_TSO		0x00000010	/* TCP segmentation offload */ |
| 662 | #define	CSUM_IP_ISCSI		0x00000020	/* iSCSI checksum offload */ |
| 663 | |
| 664 | #define	CSUM_INNER_IP6_UDP	0x00000040 |
| 665 | #define	CSUM_INNER_IP6_TCP	0x00000080 |
| 666 | #define	CSUM_INNER_IP6_TSO	0x00000100 |
| 667 | #define	CSUM_IP6_UDP		0x00000200	/* UDP checksum offload */ |
| 668 | #define	CSUM_IP6_TCP		0x00000400	/* TCP checksum offload */ |
| 669 | #define	CSUM_IP6_SCTP		0x00000800	/* SCTP checksum offload */ |
| 670 | #define	CSUM_IP6_TSO		0x00001000	/* TCP segmentation offload */ |
| 671 | #define	CSUM_IP6_ISCSI		0x00002000	/* iSCSI checksum offload */ |
| 672 | |
| 673 | #define	CSUM_INNER_IP		0x00004000 |
| 674 | #define	CSUM_INNER_IP_UDP	0x00008000 |
| 675 | #define	CSUM_INNER_IP_TCP	0x00010000 |
| 676 | #define	CSUM_INNER_IP_TSO	0x00020000 |
| 677 | |
| 678 | #define	CSUM_ENCAP_VXLAN	0x00040000	/* VXLAN outer encapsulation */ |
| 679 | #define	CSUM_ENCAP_RSVD1	0x00080000 |
| 680 | |
| 681 | /* Flags used to indicate that the checksum was verified by hardware. */ |
| 682 | #define	CSUM_INNER_L3_CALC	0x00100000 |
| 683 | #define	CSUM_INNER_L3_VALID	0x00200000 |
| 684 | #define	CSUM_INNER_L4_CALC	0x00400000 |
| 685 | #define	CSUM_INNER_L4_VALID	0x00800000 |
| 686 | #define	CSUM_L3_CALC		0x01000000	/* calculated layer 3 csum */ |
| 687 | #define	CSUM_L3_VALID		0x02000000	/* checksum is correct */ |
| 688 | #define	CSUM_L4_CALC		0x04000000	/* calculated layer 4 csum */ |
| 689 | #define	CSUM_L4_VALID		0x08000000	/* checksum is correct */ |
| 690 | #define	CSUM_L5_CALC		0x10000000	/* calculated layer 5 csum */ |
| 691 | #define	CSUM_L5_VALID		0x20000000	/* checksum is correct */ |
| 692 | #define	CSUM_COALESCED		0x40000000	/* contains merged segments */ |
| 693 | |
| 694 | #define	CSUM_SND_TAG		0x80000000	/* Packet header has send tag */ |
| 695 | |
| 696 | #define CSUM_FLAGS_TX (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP | CSUM_IP_SCTP | \ |
| 697 | CSUM_IP_TSO | CSUM_IP_ISCSI | CSUM_INNER_IP6_UDP | CSUM_INNER_IP6_TCP | \ |
| 698 | CSUM_INNER_IP6_TSO | CSUM_IP6_UDP | CSUM_IP6_TCP | CSUM_IP6_SCTP | \ |
| 699 | CSUM_IP6_TSO | CSUM_IP6_ISCSI | CSUM_INNER_IP | CSUM_INNER_IP_UDP | \ |
| 700 | CSUM_INNER_IP_TCP | CSUM_INNER_IP_TSO | CSUM_ENCAP_VXLAN | \ |
| 701 | CSUM_ENCAP_RSVD1 | CSUM_SND_TAG) |
| 702 | |
| 703 | #define CSUM_FLAGS_RX (CSUM_INNER_L3_CALC | CSUM_INNER_L3_VALID | \ |
| 704 | CSUM_INNER_L4_CALC | CSUM_INNER_L4_VALID | CSUM_L3_CALC | CSUM_L3_VALID | \ |
| 705 | CSUM_L4_CALC | CSUM_L4_VALID | CSUM_L5_CALC | CSUM_L5_VALID | \ |
| 706 | CSUM_COALESCED) |
| 707 | |
| 708 | /* |
| 709 | * CSUM flag description for use with printf(9) %b identifier. |
| 710 | */ |
| 711 | #define	CSUM_BITS \ |
| 712 | "\20\1CSUM_IP\2CSUM_IP_UDP\3CSUM_IP_TCP\4CSUM_IP_SCTP\5CSUM_IP_TSO" \ |
| 713 | "\6CSUM_IP_ISCSI\7CSUM_INNER_IP6_UDP\10CSUM_INNER_IP6_TCP" \ |
| 714 | "\11CSUM_INNER_IP6_TSO\12CSUM_IP6_UDP\13CSUM_IP6_TCP\14CSUM_IP6_SCTP" \ |
| 715 | "\15CSUM_IP6_TSO\16CSUM_IP6_ISCSI\17CSUM_INNER_IP\20CSUM_INNER_IP_UDP" \ |
| 716 | "\21CSUM_INNER_IP_TCP\22CSUM_INNER_IP_TSO\23CSUM_ENCAP_VXLAN" \ |
| 717 | "\24CSUM_ENCAP_RSVD1\25CSUM_INNER_L3_CALC\26CSUM_INNER_L3_VALID" \ |
| 718 | "\27CSUM_INNER_L4_CALC\30CSUM_INNER_L4_VALID\31CSUM_L3_CALC" \ |
| 719 | "\32CSUM_L3_VALID\33CSUM_L4_CALC\34CSUM_L4_VALID\35CSUM_L5_CALC" \ |
| 720 | "\36CSUM_L5_VALID\37CSUM_COALESCED\40CSUM_SND_TAG" |
| 721 | |
| 722 | /* CSUM flags compatibility mappings. */ |
| 723 | #define	CSUM_IP_CHECKED		CSUM_L3_CALC |
| 724 | #define	CSUM_IP_VALID		CSUM_L3_VALID |
| 725 | #define	CSUM_DATA_VALID		CSUM_L4_VALID |
| 726 | #define	CSUM_PSEUDO_HDR		CSUM_L4_CALC |
| 727 | #define	CSUM_SCTP_VALID		CSUM_L4_VALID |
| 728 | #define	CSUM_DELAY_DATA		(CSUM_TCP|CSUM_UDP) |
| 729 | #define	CSUM_DELAY_IP		CSUM_IP		/* Only v4, no v6 IP hdr csum */ |
| 730 | #define	CSUM_DELAY_DATA_IPV6	(CSUM_TCP_IPV6|CSUM_UDP_IPV6) |
| 731 | #define	CSUM_DATA_VALID_IPV6	CSUM_DATA_VALID |
| 732 | #define	CSUM_TCP		CSUM_IP_TCP |
| 733 | #define	CSUM_UDP		CSUM_IP_UDP |
| 734 | #define	CSUM_SCTP		CSUM_IP_SCTP |
| 735 | #define	CSUM_TSO		(CSUM_IP_TSO|CSUM_IP6_TSO) |
| 736 | #define	CSUM_INNER_TSO		(CSUM_INNER_IP_TSO|CSUM_INNER_IP6_TSO) |
| 737 | #define	CSUM_UDP_IPV6		CSUM_IP6_UDP |
| 738 | #define	CSUM_TCP_IPV6		CSUM_IP6_TCP |
| 739 | #define	CSUM_SCTP_IPV6		CSUM_IP6_SCTP |
| 740 | #define	CSUM_TLS_MASK		(CSUM_L5_CALC|CSUM_L5_VALID) |
| 741 | #define	CSUM_TLS_DECRYPTED	CSUM_L5_CALC |
| 742 | |
| 743 | /* |
| 744 | * mbuf types describing the content of the mbuf (including external storage). |
| 745 | */ |
| 746 | #define	MT_NOTMBUF	0	/* USED INTERNALLY ONLY! Object is not mbuf */ |
| 747 | #define	MT_DATA		1	/* dynamic (data) allocation */ |
| 748 | #define	MT_HEADER	MT_DATA	/* packet header, use M_PKTHDR instead */ |
| 749 | |
| 750 | #define	MT_VENDOR1	4	/* for vendor-internal use */ |
| 751 | #define	MT_VENDOR2	5	/* for vendor-internal use */ |
| 752 | #define	MT_VENDOR3	6	/* for vendor-internal use */ |
| 753 | #define	MT_VENDOR4	7	/* for vendor-internal use */ |
| 754 | |
| 755 | #define	MT_SONAME	8	/* socket name */ |
| 756 | |
| 757 | #define	MT_EXP1		9	/* for experimental use */ |
| 758 | #define	MT_EXP2		10	/* for experimental use */ |
| 759 | #define	MT_EXP3		11	/* for experimental use */ |
| 760 | #define	MT_EXP4		12	/* for experimental use */ |
| 761 | |
| 762 | #define	MT_CONTROL	14	/* extra-data protocol message */ |
| 763 | #define	MT_EXTCONTROL	15	/* control message with externalized contents */ |
| 764 | #define	MT_OOBDATA	16	/* expedited data */ |
| 765 | |
| 766 | #define	MT_NOINIT	255	/* Not a type but a flag to allocate |
| 767 | 				 a non-initialized mbuf */ |
| 768 | |
| 769 | /* |
| 770 | * String names of mbuf-related UMA(9) and malloc(9) types. Exposed to |
| 771 | * !_KERNEL so that monitoring tools can look up the zones with |
| 772 | * libmemstat(3). |
| 773 | */ |
| 774 | #define	MBUF_MEM_NAME		"mbuf" |
| 775 | #define	MBUF_CLUSTER_MEM_NAME	"mbuf_cluster" |
| 776 | #define	MBUF_PACKET_MEM_NAME	"mbuf_packet" |
| 777 | #define	MBUF_JUMBOP_MEM_NAME	"mbuf_jumbo_page" |
| 778 | #define	MBUF_JUMBO9_MEM_NAME	"mbuf_jumbo_9k" |
| 779 | #define	MBUF_JUMBO16_MEM_NAME	"mbuf_jumbo_16k" |
| 780 | #define	MBUF_TAG_MEM_NAME	"mbuf_tag" |
| 781 | #define	MBUF_EXTREFCNT_MEM_NAME	"mbuf_ext_refcnt" |
| 782 | #define	MBUF_EXTPGS_MEM_NAME	"mbuf_extpgs" |
| 783 | |
| 784 | #ifdef _KERNEL |
| 785 | union if_snd_tag_alloc_params; |
| 786 | |
| 787 | #define	MBUF_CHECKSLEEP(how) do {					\ |
| 788 | 	if (how == M_WAITOK)						\ |
| 789 | 		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,		\ |
| 790 | 		 "Sleeping in \"%s\"", __func__);			\ |
| 791 | } while (0) |
| 792 | |
| 793 | /* |
| 794 | * Network buffer allocation API |
| 795 | * |
| 796 | * The rest of it is defined in kern/kern_mbuf.c |
| 797 | */ |
| 798 | extern uma_zone_t	zone_mbuf; |
| 799 | extern uma_zone_t	zone_clust; |
| 800 | extern uma_zone_t	zone_pack; |
| 801 | extern uma_zone_t	zone_jumbop; |
| 802 | extern uma_zone_t	zone_jumbo9; |
| 803 | extern uma_zone_t	zone_jumbo16; |
| 804 | extern uma_zone_t	zone_extpgs; |
| 805 | |
| 806 | void		 mb_dupcl(struct mbuf *, struct mbuf *); |
| 807 | void		 mb_free_ext(struct mbuf *); |
| 808 | void		 mb_free_extpg(struct mbuf *); |
| 809 | void		 mb_free_mext_pgs(struct mbuf *); |
| 810 | struct mbuf	*mb_alloc_ext_pgs(int, m_ext_free_t, int); |
| 811 | struct mbuf	*mb_alloc_ext_plus_pages(int, int); |
| 812 | struct mbuf	*mb_mapped_to_unmapped(struct mbuf *, int, int, int, |
| 813 | 		 struct mbuf **); |
| 814 | int		 mb_unmapped_compress(struct mbuf *m); |
| 815 | int		 mb_unmapped_to_ext(struct mbuf *m, struct mbuf **mres); |
| 816 | void		 mb_free_notready(struct mbuf *m, int count); |
| 817 | void		 m_adj(struct mbuf *, int); |
| 818 | void		 m_adj_decap(struct mbuf *, int); |
| 819 | int		 m_apply(struct mbuf *, int, int, |
| 820 | 		 int (*)(void *, void *, u_int), void *); |
| 821 | int		 m_append(struct mbuf *, int, c_caddr_t); |
| 822 | void		 m_cat(struct mbuf *, struct mbuf *); |
| 823 | void		 m_catpkt(struct mbuf *, struct mbuf *); |
| 824 | int		 m_clget(struct mbuf *m, int how); |
| 825 | void 		*m_cljget(struct mbuf *m, int how, int size); |
| 826 | struct mbuf	*m_collapse(struct mbuf *, int, int); |
| 827 | void		 m_copyback(struct mbuf *, int, int, c_caddr_t); |
| 828 | void		 m_copydata(const struct mbuf *, int, int, caddr_t); |
| 829 | struct mbuf	*m_copym(struct mbuf *, int, int, int); |
| 830 | struct mbuf	*m_copypacket(struct mbuf *, int); |
| 831 | void		 m_copy_pkthdr(struct mbuf *, struct mbuf *); |
| 832 | struct mbuf	*m_copyup(struct mbuf *, int, int); |
| 833 | struct mbuf	*m_defrag(struct mbuf *, int); |
| 834 | void		 m_demote_pkthdr(struct mbuf *); |
| 835 | void		 m_demote(struct mbuf *, int, int); |
| 836 | struct mbuf	*m_devget(char *, int, int, struct ifnet *, |
| 837 | 		 void (*)(char *, caddr_t, u_int)); |
| 838 | void		 m_dispose_extcontrolm(struct mbuf *m); |
| 839 | struct mbuf	*m_dup(const struct mbuf *, int); |
| 840 | int		 m_dup_pkthdr(struct mbuf *, const struct mbuf *, int); |
| 841 | void		 m_extadd(struct mbuf *, char *, u_int, m_ext_free_t, |
| 842 | 		 void *, void *, int, int); |
| 843 | u_int		 m_fixhdr(struct mbuf *); |
| 844 | struct mbuf	*m_fragment(struct mbuf *, int, int); |
| 845 | void		 m_freem(struct mbuf *); |
| 846 | void		 m_freemp(struct mbuf *); |
| 847 | void		 m_free_raw(struct mbuf *); |
| 848 | struct mbuf	*m_get2(int, int, short, int); |
| 849 | struct mbuf	*m_get3(int, int, short, int); |
| 850 | struct mbuf	*m_getjcl(int, short, int, int); |
| 851 | struct mbuf	*m_getm2(struct mbuf *, int, int, short, int); |
| 852 | struct mbuf	*m_getptr(struct mbuf *, int, int *); |
| 853 | u_int		 m_length(struct mbuf *, struct mbuf **); |
| 854 | int		 m_mbuftouio(struct uio *, const struct mbuf *, int); |
| 855 | void		 m_move_pkthdr(struct mbuf *, struct mbuf *); |
| 856 | int		 m_pkthdr_init(struct mbuf *, int); |
| 857 | struct mbuf	*m_prepend(struct mbuf *, int, int); |
| 858 | void		 m_print(const struct mbuf *, int); |
| 859 | struct mbuf	*m_pulldown(struct mbuf *, int, int, int *); |
| 860 | struct mbuf	*m_pullup(struct mbuf *, int); |
| 861 | int		 m_sanity(struct mbuf *, int); |
| 862 | struct mbuf	*m_split(struct mbuf *, int, int); |
| 863 | struct mbuf	*m_uiotombuf(struct uio *, int, int, int, int); |
| 864 | int		 m_unmapped_uiomove(const struct mbuf *, int, struct uio *, |
| 865 | 		 int); |
| 866 | struct mbuf	*m_unshare(struct mbuf *, int); |
| 867 | int		 m_snd_tag_alloc(struct ifnet *, |
| 868 | 		 union if_snd_tag_alloc_params *, struct m_snd_tag **); |
| 869 | void		 m_snd_tag_init(struct m_snd_tag *, struct ifnet *, |
| 870 | 		 const struct if_snd_tag_sw *); |
| 871 | void		 m_snd_tag_destroy(struct m_snd_tag *); |
| 872 | void		 m_rcvif_serialize(struct mbuf *); |
| 873 | struct ifnet	*m_rcvif_restore(struct mbuf *); |
| 874 | |
| 875 | static __inline int |
| 876 | m_gettype(int size) |
| 877 | { |
| 878 | 	int type; |
| 879 | |
| 880 | 	switch (size) { |
| 881 | 	case MSIZE: |
| 882 | 		type = EXT_MBUF; |
| 883 | 		break; |
| 884 | 	case MCLBYTES: |
| 885 | 		type = EXT_CLUSTER; |
| 886 | 		break; |
| 887 | #if MJUMPAGESIZE != MCLBYTES |
| 888 | 	case MJUMPAGESIZE: |
| 889 | 		type = EXT_JUMBOP; |
| 890 | 		break; |
| 891 | #endif |
| 892 | 	case MJUM9BYTES: |
| 893 | 		type = EXT_JUMBO9; |
| 894 | 		break; |
| 895 | 	case MJUM16BYTES: |
| 896 | 		type = EXT_JUMBO16; |
| 897 | 		break; |
| 898 | 	default: |
| 899 | 		panic("%s: invalid cluster size %d", __func__, size); |
| 900 | 	} |
| 901 | |
| 902 | 	return (type); |
| 903 | } |
| 904 | |
| 905 | /* |
| 906 | * Associated an external reference counted buffer with an mbuf. |
| 907 | */ |
| 908 | static __inline void |
| 909 | m_extaddref(struct mbuf *m, char *buf, u_int size, u_int *ref_cnt, |
| 910 | m_ext_free_t freef, void *arg1, void *arg2) |
| 911 | { |
| 912 | |
| 913 | 	KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__)); |
| 914 | |
| 915 | 	atomic_add_int(ref_cnt, 1); |
| 916 | 	m->m_flags |= M_EXT; |
| 917 | 	m->m_ext.ext_buf = buf; |
| 918 | 	m->m_ext.ext_cnt = ref_cnt; |
| 919 | 	m->m_data = m->m_ext.ext_buf; |
| 920 | 	m->m_ext.ext_size = size; |
| 921 | 	m->m_ext.ext_free = freef; |
| 922 | 	m->m_ext.ext_arg1 = arg1; |
| 923 | 	m->m_ext.ext_arg2 = arg2; |
| 924 | 	m->m_ext.ext_type = EXT_EXTREF; |
| 925 | 	m->m_ext.ext_flags = 0; |
| 926 | } |
| 927 | |
| 928 | static __inline uma_zone_t |
| 929 | m_getzone(int size) |
| 930 | { |
| 931 | 	uma_zone_t zone; |
| 932 | |
| 933 | 	switch (size) { |
| 934 | 	case MCLBYTES: |
| 935 | 		zone = zone_clust; |
| 936 | 		break; |
| 937 | #if MJUMPAGESIZE != MCLBYTES |
| 938 | 	case MJUMPAGESIZE: |
| 939 | 		zone = zone_jumbop; |
| 940 | 		break; |
| 941 | #endif |
| 942 | 	case MJUM9BYTES: |
| 943 | 		zone = zone_jumbo9; |
| 944 | 		break; |
| 945 | 	case MJUM16BYTES: |
| 946 | 		zone = zone_jumbo16; |
| 947 | 		break; |
| 948 | 	default: |
| 949 | 		panic("%s: invalid cluster size %d", __func__, size); |
| 950 | 	} |
| 951 | |
| 952 | 	return (zone); |
| 953 | } |
| 954 | |
| 955 | /* |
| 956 | * Initialize an mbuf with linear storage. |
| 957 | * |
| 958 | * Inline because the consumer text overhead will be roughly the same to |
| 959 | * initialize or call a function with this many parameters and M_PKTHDR |
| 960 | * should go away with constant propagation for !MGETHDR. |
| 961 | */ |
| 962 | static __inline int |
| 963 | m_init(struct mbuf *m, int how, short type, int flags) |
| 964 | { |
| 965 | 	int error; |
| 966 | |
| 967 | 	m->m_next = NULL; |
| 968 | 	m->m_nextpkt = NULL; |
| 969 | 	m->m_data = m->m_dat; |
| 970 | 	m->m_len = 0; |
| 971 | 	m->m_flags = flags; |
| 972 | 	m->m_type = type; |
| 973 | 	if (flags & M_PKTHDR) |
| 974 | 		error = m_pkthdr_init(m, how); |
| 975 | 	else |
| 976 | 		error = 0; |
| 977 | |
| 978 | 	MBUF_PROBE5(m__init, m, how, type, flags, error); |
| 979 | 	return (error); |
| 980 | } |
| 981 | |
| 982 | static __inline struct mbuf * |
| 983 | m_get_raw(int how, short type) |
| 984 | { |
| 985 | 	struct mbuf *m; |
| 986 | 	struct mb_args args; |
| 987 | |
| 988 | 	args.flags = 0; |
| 989 | 	args.type = type | MT_NOINIT; |
| 990 | 	m = uma_zalloc_arg(zone_mbuf, &args, how); |
| 991 | 	MBUF_PROBE3(m__get_raw, how, type, m); |
| 992 | 	return (m); |
| 993 | } |
| 994 | |
| 995 | static __inline struct mbuf * |
| 996 | m_get(int how, short type) |
| 997 | { |
| 998 | 	struct mbuf *m; |
| 999 | 	struct mb_args args; |
| 1000 | |
| 1001 | 	args.flags = 0; |
| 1002 | 	args.type = type; |
| 1003 | 	m = uma_zalloc_arg(zone_mbuf, &args, how); |
| 1004 | 	MBUF_PROBE3(m__get, how, type, m); |
| 1005 | 	return (m); |
| 1006 | } |
| 1007 | |
| 1008 | static __inline struct mbuf * |
| 1009 | m_gethdr_raw(int how, short type) |
| 1010 | { |
| 1011 | 	struct mbuf *m; |
| 1012 | 	struct mb_args args; |
| 1013 | |
| 1014 | 	args.flags = M_PKTHDR; |
| 1015 | 	args.type = type | MT_NOINIT; |
| 1016 | 	m = uma_zalloc_arg(zone_mbuf, &args, how); |
| 1017 | 	MBUF_PROBE3(m__gethdr_raw, how, type, m); |
| 1018 | 	return (m); |
| 1019 | } |
| 1020 | |
| 1021 | static __inline struct mbuf * |
| 1022 | m_gethdr(int how, short type) |
| 1023 | { |
| 1024 | 	struct mbuf *m; |
| 1025 | 	struct mb_args args; |
| 1026 | |
| 1027 | 	args.flags = M_PKTHDR; |
| 1028 | 	args.type = type; |
| 1029 | 	m = uma_zalloc_arg(zone_mbuf, &args, how); |
| 1030 | 	MBUF_PROBE3(m__gethdr, how, type, m); |
| 1031 | 	return (m); |
| 1032 | } |
| 1033 | |
| 1034 | static __inline struct mbuf * |
| 1035 | m_getcl(int how, short type, int flags) |
| 1036 | { |
| 1037 | 	struct mbuf *m; |
| 1038 | 	struct mb_args args; |
| 1039 | |
| 1040 | 	args.flags = flags; |
| 1041 | 	args.type = type; |
| 1042 | 	m = uma_zalloc_arg(zone_pack, &args, how); |
| 1043 | 	MBUF_PROBE4(m__getcl, how, type, flags, m); |
| 1044 | 	return (m); |
| 1045 | } |
| 1046 | |
| 1047 | /* |
| 1048 | * XXX: m_cljset() is a dangerous API. One must attach only a new, |
| 1049 | * unreferenced cluster to an mbuf(9). It is not possible to assert |
| 1050 | * that, so care can be taken only by users of the API. |
| 1051 | */ |
| 1052 | static __inline void |
| 1053 | m_cljset(struct mbuf *m, void *cl, int type) |
| 1054 | { |
| 1055 | 	int size; |
| 1056 | |
| 1057 | 	switch (type) { |
| 1058 | 	case EXT_CLUSTER: |
| 1059 | 		size = MCLBYTES; |
| 1060 | 		break; |
| 1061 | #if MJUMPAGESIZE != MCLBYTES |
| 1062 | 	case EXT_JUMBOP: |
| 1063 | 		size = MJUMPAGESIZE; |
| 1064 | 		break; |
| 1065 | #endif |
| 1066 | 	case EXT_JUMBO9: |
| 1067 | 		size = MJUM9BYTES; |
| 1068 | 		break; |
| 1069 | 	case EXT_JUMBO16: |
| 1070 | 		size = MJUM16BYTES; |
| 1071 | 		break; |
| 1072 | 	default: |
| 1073 | 		panic("%s: unknown cluster type %d", __func__, type); |
| 1074 | 		break; |
| 1075 | 	} |
| 1076 | |
| 1077 | 	m->m_data = m->m_ext.ext_buf = cl; |
| 1078 | 	m->m_ext.ext_free = m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL; |
| 1079 | 	m->m_ext.ext_size = size; |
| 1080 | 	m->m_ext.ext_type = type; |
| 1081 | 	m->m_ext.ext_flags = EXT_FLAG_EMBREF; |
| 1082 | 	m->m_ext.ext_count = 1; |
| 1083 | 	m->m_flags |= M_EXT; |
| 1084 | 	MBUF_PROBE3(m__cljset, m, cl, type); |
| 1085 | } |
| 1086 | |
| 1087 | static __inline void |
| 1088 | m_chtype(struct mbuf *m, short new_type) |
| 1089 | { |
| 1090 | |
| 1091 | 	m->m_type = new_type; |
| 1092 | } |
| 1093 | |
| 1094 | static __inline void |
| 1095 | m_clrprotoflags(struct mbuf *m) |
| 1096 | { |
| 1097 | |
| 1098 | 	while (m) { |
| 1099 | 		m->m_flags &= ~M_PROTOFLAGS; |
| 1100 | 		m = m->m_next; |
| 1101 | 	} |
| 1102 | } |
| 1103 | |
| 1104 | static __inline struct mbuf * |
| 1105 | m_last(struct mbuf *m) |
| 1106 | { |
| 1107 | |
| 1108 | 	while (m->m_next) |
| 1109 | 		m = m->m_next; |
| 1110 | 	return (m); |
| 1111 | } |
| 1112 | |
| 1113 | static inline u_int |
| 1114 | m_extrefcnt(struct mbuf *m) |
| 1115 | { |
| 1116 | |
| 1117 | 	KASSERT(m->m_flags & M_EXT, ("%s: M_EXT missing for %p", __func__, m)); |
| 1118 | |
| 1119 | 	return ((m->m_ext.ext_flags & EXT_FLAG_EMBREF) ? m->m_ext.ext_count : |
| 1120 | 	 *m->m_ext.ext_cnt); |
| 1121 | } |
| 1122 | |
| 1123 | /* |
| 1124 | * mbuf, cluster, and external object allocation macros (for compatibility |
| 1125 | * purposes). |
| 1126 | */ |
| 1127 | #define	M_MOVE_PKTHDR(to, from)	m_move_pkthdr((to), (from)) |
| 1128 | #define	MGET(m, how, type)	((m) = m_get((how), (type))) |
| 1129 | #define	MGETHDR(m, how, type)	((m) = m_gethdr((how), (type))) |
| 1130 | #define	MCLGET(m, how)		m_clget((m), (how)) |
| 1131 | #define	MEXTADD(m, buf, size, free, arg1, arg2, flags, type)		\ |
| 1132 | m_extadd((m), (char *)(buf), (size), (free), (arg1), (arg2),	\ |
| 1133 | (flags), (type)) |
| 1134 | #define	m_getm(m, len, how, type)					\ |
| 1135 | m_getm2((m), (len), (how), (type), M_PKTHDR) |
| 1136 | |
| 1137 | /* |
| 1138 | * Evaluate TRUE if it's safe to write to the mbuf m's data region (this can |
| 1139 | * be both the local data payload, or an external buffer area, depending on |
| 1140 | * whether M_EXT is set). |
| 1141 | */ |
| 1142 | #define	M_WRITABLE(m)	(((m)->m_flags & (M_RDONLY | M_EXTPG)) == 0 &&	\ |
| 1143 | 			 (!(((m)->m_flags & M_EXT)) ||			\ |
| 1144 | 			 (m_extrefcnt(m) == 1))) |
| 1145 | |
| 1146 | /* Check if the supplied mbuf has a packet header, or else panic. */ |
| 1147 | #define	M_ASSERTPKTHDR(m)						\ |
| 1148 | 	KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR,			\ |
| 1149 | 	 ("%s: no mbuf %p packet header!", __func__, (m))) |
| 1150 | |
| 1151 | /* Check if the supplied mbuf has no send tag, or else panic. */ |
| 1152 | #define	M_ASSERT_NO_SND_TAG(m)						\ |
| 1153 | 	KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR &&		\ |
| 1154 | 	 ((m)->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0,		\ |
| 1155 | 	 ("%s: receive mbuf %p has send tag!", __func__, (m))) |
| 1156 | |
| 1157 | /* Check if mbuf is multipage. */ |
| 1158 | #define M_ASSERTEXTPG(m)						\ |
| 1159 | 	KASSERT(((m)->m_flags & (M_EXTPG|M_PKTHDR)) == M_EXTPG,		\ |
| 1160 | 	 ("%s: m %p is not multipage!", __func__, m)) |
| 1161 | |
| 1162 | /* |
| 1163 | * Ensure that the supplied mbuf is a valid, non-free mbuf. |
| 1164 | * |
| 1165 | * XXX: Broken at the moment. Need some UMA magic to make it work again. |
| 1166 | */ |
| 1167 | #define	M_ASSERTVALID(m)						\ |
| 1168 | 	KASSERT((((struct mbuf *)m)->m_flags & 0) == 0,			\ |
| 1169 | 	 ("%s: attempted use of a free mbuf %p!", __func__, (m))) |
| 1170 | |
| 1171 | /* Check whether any mbuf in the chain is unmapped. */ |
| 1172 | #ifdef INVARIANTS |
| 1173 | #define	M_ASSERTMAPPED(m) do {						\ |
| 1174 | 	for (struct mbuf *__m = (m); __m != NULL; __m = __m->m_next)	\ |
| 1175 | 		KASSERT((__m->m_flags & M_EXTPG) == 0,			\ |
| 1176 | 		 ("%s: chain %p contains an unmapped mbuf", __func__, (m)));\ |
| 1177 | } while (0) |
| 1178 | #else |
| 1179 | #define	M_ASSERTMAPPED(m) do {} while (0) |
| 1180 | #endif |
| 1181 | |
| 1182 | /* |
| 1183 | * Return the address of the start of the buffer associated with an mbuf, |
| 1184 | * handling external storage, packet-header mbufs, and regular data mbufs. |
| 1185 | */ |
| 1186 | #define	M_START(m)							\ |
| 1187 | 	(((m)->m_flags & M_EXTPG) ? NULL :				\ |
| 1188 | 	 ((m)->m_flags & M_EXT) ? (m)->m_ext.ext_buf :			\ |
| 1189 | 	 ((m)->m_flags & M_PKTHDR) ? &(m)->m_pktdat[0] :		\ |
| 1190 | 	 &(m)->m_dat[0]) |
| 1191 | |
| 1192 | /* |
| 1193 | * Return the size of the buffer associated with an mbuf, handling external |
| 1194 | * storage, packet-header mbufs, and regular data mbufs. |
| 1195 | */ |
| 1196 | #define	M_SIZE(m)							\ |
| 1197 | 	(((m)->m_flags & M_EXT) ? (m)->m_ext.ext_size :			\ |
| 1198 | 	 ((m)->m_flags & M_PKTHDR) ? MHLEN :				\ |
| 1199 | 	 MLEN) |
| 1200 | |
| 1201 | /* |
| 1202 | * Set the m_data pointer of a newly allocated mbuf to place an object of the |
| 1203 | * specified size at the end of the mbuf, longword aligned. |
| 1204 | * |
| 1205 | * NB: Historically, we had M_ALIGN(), MH_ALIGN(), and MEXT_ALIGN() as |
| 1206 | * separate macros, each asserting that it was called at the proper moment. |
| 1207 | * This required callers to themselves test the storage type and call the |
| 1208 | * right one. Rather than require callers to be aware of those layout |
| 1209 | * decisions, we centralize here. |
| 1210 | */ |
| 1211 | static __inline void |
| 1212 | m_align(struct mbuf *m, int len) |
| 1213 | { |
| 1214 | 	int adjust; |
| 1215 | 	KASSERT(m->m_data == M_START(m), |
| 1216 | 	 ("%s: not a virgin mbuf %p", __func__, m)); |
| 1217 | |
| 1218 | 	adjust = M_SIZE(m) - len; |
| 1219 | 	m->m_data += adjust &~ (sizeof(long)-1); |
| 1220 | } |
| 1221 | |
| 1222 | #define	M_ALIGN(m, len)		m_align(m, len) |
| 1223 | #define	MH_ALIGN(m, len)	m_align(m, len) |
| 1224 | #define	MEXT_ALIGN(m, len)	m_align(m, len) |
| 1225 | |
| 1226 | /* |
| 1227 | * Compute the amount of space available before the current start of data in |
| 1228 | * an mbuf. |
| 1229 | * |
| 1230 | * The M_WRITABLE() is a temporary, conservative safety measure: the burden |
| 1231 | * of checking writability of the mbuf data area rests solely with the caller. |
| 1232 | * |
| 1233 | * NB: In previous versions, M_LEADINGSPACE() would only check M_WRITABLE() |
| 1234 | * for mbufs with external storage. We now allow mbuf-embedded data to be |
| 1235 | * read-only as well. |
| 1236 | */ |
| 1237 | #define	M_LEADINGSPACE(m)						\ |
| 1238 | 	(M_WRITABLE(m) ? ((m)->m_data - M_START(m)) : 0) |
| 1239 | |
| 1240 | /* |
| 1241 | * So M_TRAILINGROOM() is for when you want to know how much space |
| 1242 | * would be there if it was writable. This can be used to |
| 1243 | * detect changes in mbufs by knowing the value at one point |
| 1244 | * and then being able to compare it later to the current M_TRAILINGROOM(). |
| 1245 | * The TRAILINGSPACE() macro is not suitable for this since an mbuf |
| 1246 | * at one point might not be writable and then later it becomes writable |
| 1247 | * even though the space at the back of it has not changed. |
| 1248 | */ |
| 1249 | #define M_TRAILINGROOM(m) ((M_START(m) + M_SIZE(m)) - ((m)->m_data + (m)->m_len)) |
| 1250 | /* |
| 1251 | * Compute the amount of space available after the end of data in an mbuf. |
| 1252 | * |
| 1253 | * The M_WRITABLE() is a temporary, conservative safety measure: the burden |
| 1254 | * of checking writability of the mbuf data area rests solely with the caller. |
| 1255 | * |
| 1256 | * NB: In previous versions, M_TRAILINGSPACE() would only check M_WRITABLE() |
| 1257 | * for mbufs with external storage. We now allow mbuf-embedded data to be |
| 1258 | * read-only as well. |
| 1259 | */ |
| 1260 | #define	M_TRAILINGSPACE(m) (M_WRITABLE(m) ? M_TRAILINGROOM(m) : 0) |
| 1261 | |
| 1262 | /* |
| 1263 | * Arrange to prepend space of size plen to mbuf m. If a new mbuf must be |
| 1264 | * allocated, how specifies whether to wait. If the allocation fails, the |
| 1265 | * original mbuf chain is freed and m is set to NULL. |
| 1266 | */ |
| 1267 | #define	M_PREPEND(m, plen, how) do {					\ |
| 1268 | 	struct mbuf **_mmp = &(m);					\ |
| 1269 | 	struct mbuf *_mm = *_mmp;					\ |
| 1270 | 	int _mplen = (plen);						\ |
| 1271 | 	int __mhow = (how);						\ |
| 1272 | 									\ |
| 1273 | 	MBUF_CHECKSLEEP(how);						\ |
| 1274 | 	if (M_LEADINGSPACE(_mm) >= _mplen) {				\ |
| 1275 | 		_mm->m_data -= _mplen;					\ |
| 1276 | 		_mm->m_len += _mplen;					\ |
| 1277 | 	} else								\ |
| 1278 | 		_mm = m_prepend(_mm, _mplen, __mhow);			\ |
| 1279 | 	if (_mm != NULL && _mm->m_flags & M_PKTHDR)			\ |
| 1280 | 		_mm->m_pkthdr.len += _mplen;				\ |
| 1281 | 	*_mmp = _mm;							\ |
| 1282 | } while (0) |
| 1283 | |
| 1284 | /* |
| 1285 | * Change mbuf to new type. This is a relatively expensive operation and |
| 1286 | * should be avoided. |
| 1287 | */ |
| 1288 | #define	MCHTYPE(m, t)	m_chtype((m), (t)) |
| 1289 | |
| 1290 | /* Return the rcvif of a packet header. */ |
| 1291 | static __inline struct ifnet * |
| 1292 | m_rcvif(struct mbuf *m) |
| 1293 | { |
| 1294 | |
| 1295 | 	M_ASSERTPKTHDR(m); |
| 1296 | 	if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) |
| 1297 | 		return (NULL); |
| 1298 | 	return (m->m_pkthdr.rcvif); |
| 1299 | } |
| 1300 | |
| 1301 | /* Length to m_copy to copy all. */ |
| 1302 | #define	M_COPYALL	1000000000 |
| 1303 | |
| 1304 | extern u_int		max_linkhdr;	/* Largest link-level header */ |
| 1305 | extern u_int		max_hdr;	/* Largest link + protocol header */ |
| 1306 | extern u_int		max_protohdr;	/* Largest protocol header */ |
| 1307 | void max_linkhdr_grow(u_int); |
| 1308 | void max_protohdr_grow(u_int); |
| 1309 | |
| 1310 | extern int		nmbclusters;	/* Maximum number of clusters */ |
| 1311 | extern bool		mb_use_ext_pgs;	/* Use ext_pgs for sendfile */ |
| 1312 | |
| 1313 | /*- |
| 1314 | * Network packets may have annotations attached by affixing a list of |
| 1315 | * "packet tags" to the pkthdr structure. Packet tags are dynamically |
| 1316 | * allocated semi-opaque data structures that have a fixed header |
| 1317 | * (struct m_tag) that specifies the size of the memory block and a |
| 1318 | * <cookie,type> pair that identifies it. The cookie is a 32-bit unique |
| 1319 | * unsigned value used to identify a module or ABI. By convention this value |
| 1320 | * is chosen as the date+time that the module is created, expressed as the |
| 1321 | * number of seconds since the epoch (e.g., using date -u +'%s'). The type |
| 1322 | * value is an ABI/module-specific value that identifies a particular |
| 1323 | * annotation and is private to the module. For compatibility with systems |
| 1324 | * like OpenBSD that define packet tags w/o an ABI/module cookie, the value |
| 1325 | * PACKET_ABI_COMPAT is used to implement m_tag_get and m_tag_find |
| 1326 | * compatibility shim functions and several tag types are defined below. |
| 1327 | * Users that do not require compatibility should use a private cookie value |
| 1328 | * so that packet tag-related definitions can be maintained privately. |
| 1329 | * |
| 1330 | * Note that the packet tag returned by m_tag_alloc has the default memory |
| 1331 | * alignment implemented by malloc. To reference private data one can use a |
| 1332 | * construct like: |
| 1333 | * |
| 1334 | *	struct m_tag *mtag = m_tag_alloc(...); |
| 1335 | *	struct foo *p = (struct foo *)(mtag+1); |
| 1336 | * |
| 1337 | * if the alignment of struct m_tag is sufficient for referencing members of |
| 1338 | * struct foo. Otherwise it is necessary to embed struct m_tag within the |
| 1339 | * private data structure to insure proper alignment; e.g., |
| 1340 | * |
| 1341 | *	struct foo { |
| 1342 | *		struct m_tag	tag; |
| 1343 | *		... |
| 1344 | *	}; |
| 1345 | *	struct foo *p = (struct foo *) m_tag_alloc(...); |
| 1346 | *	struct m_tag *mtag = &p->tag; |
| 1347 | */ |
| 1348 | |
| 1349 | /* |
| 1350 | * Persistent tags stay with an mbuf until the mbuf is reclaimed. Otherwise |
| 1351 | * tags are expected to ``vanish'' when they pass through a network |
| 1352 | * interface. For most interfaces this happens normally as the tags are |
| 1353 | * reclaimed when the mbuf is free'd. However in some special cases |
| 1354 | * reclaiming must be done manually. An example is packets that pass through |
| 1355 | * the loopback interface. Also, one must be careful to do this when |
| 1356 | * ``turning around'' packets (e.g., icmp_reflect). |
| 1357 | * |
| 1358 | * To mark a tag persistent bit-or this flag in when defining the tag id. |
| 1359 | * The tag will then be treated as described above. |
| 1360 | */ |
| 1361 | #define	MTAG_PERSISTENT				0x800 |
| 1362 | |
| 1363 | #define	PACKET_TAG_NONE				0 /* Nadda */ |
| 1364 | |
| 1365 | /* Packet tags for use with PACKET_ABI_COMPAT. */ |
| 1366 | #define	PACKET_TAG_IPSEC_IN_DONE		1 /* IPsec applied, in */ |
| 1367 | #define	PACKET_TAG_IPSEC_OUT_DONE		2 /* IPsec applied, out */ |
| 1368 | #define	PACKET_TAG_IPSEC_IN_CRYPTO_DONE		3 /* NIC IPsec crypto done */ |
| 1369 | #define	PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED	4 /* NIC IPsec crypto req'ed */ |
| 1370 | #define	PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO	5 /* NIC notifies IPsec */ |
| 1371 | #define	PACKET_TAG_IPSEC_PENDING_TDB		6 /* Reminder to do IPsec */ |
| 1372 | #define	PACKET_TAG_BRIDGE			7 /* Bridge processing done */ |
| 1373 | #define	PACKET_TAG_GIF				8 /* GIF processing done */ |
| 1374 | #define	PACKET_TAG_GRE				9 /* GRE processing done */ |
| 1375 | #define	PACKET_TAG_IN_PACKET_CHECKSUM		10 /* NIC checksumming done */ |
| 1376 | #define	PACKET_TAG_ENCAP			11 /* Encap. processing */ |
| 1377 | #define	PACKET_TAG_IPSEC_SOCKET			12 /* IPSEC socket ref */ |
| 1378 | #define	PACKET_TAG_IPSEC_HISTORY		13 /* IPSEC history */ |
| 1379 | #define	PACKET_TAG_IPV6_INPUT			14 /* IPV6 input processing */ |
| 1380 | #define	PACKET_TAG_DUMMYNET			15 /* dummynet info */ |
| 1381 | #define	PACKET_TAG_DIVERT			17 /* divert info */ |
| 1382 | #define	PACKET_TAG_IPFORWARD			18 /* ipforward info */ |
| 1383 | #define	PACKET_TAG_MACLABEL	(19 | MTAG_PERSISTENT) /* MAC label */ |
| 1384 | #define	PACKET_TAG_PF				21 /* PF/ALTQ information */ |
| 1385 | /* was	PACKET_TAG_RTSOCKFAM			25 rtsock sa family */ |
| 1386 | #define	PACKET_TAG_IPOPTIONS			27 /* Saved IP options */ |
| 1387 | #define	PACKET_TAG_CARP				28 /* CARP info */ |
| 1388 | #define	PACKET_TAG_IPSEC_NAT_T_PORTS		29 /* two uint16_t */ |
| 1389 | #define	PACKET_TAG_ND_OUTGOING			30 /* ND outgoing */ |
| 1390 | #define	PACKET_TAG_PF_REASSEMBLED		31 |
| 1391 | #define	PACKET_TAG_IPSEC_ACCEL_OUT		32 /* IPSEC accel out */ |
| 1392 | #define	PACKET_TAG_IPSEC_ACCEL_IN		33 /* IPSEC accel in */ |
| 1393 | #define	PACKET_TAG_OVPN				34 /* if_ovpn */ |
| 1394 | |
| 1395 | /* Specific cookies and tags. */ |
| 1396 | |
| 1397 | /* Packet tag routines. */ |
| 1398 | struct m_tag	*m_tag_alloc(uint32_t, uint16_t, int, int); |
| 1399 | void		 m_tag_delete(struct mbuf *, struct m_tag *); |
| 1400 | void		 m_tag_delete_chain(struct mbuf *, struct m_tag *); |
| 1401 | void		 m_tag_free_default(struct m_tag *); |
| 1402 | struct m_tag	*m_tag_locate(struct mbuf *, uint32_t, uint16_t, |
| 1403 | struct m_tag *); |
| 1404 | struct m_tag	*m_tag_copy(struct m_tag *, int); |
| 1405 | int		 m_tag_copy_chain(struct mbuf *, const struct mbuf *, int); |
| 1406 | void		 m_tag_delete_nonpersistent(struct mbuf *); |
| 1407 | |
| 1408 | /* |
| 1409 | * Initialize the list of tags associated with an mbuf. |
| 1410 | */ |
| 1411 | static __inline void |
| 1412 | m_tag_init(struct mbuf *m) |
| 1413 | { |
| 1414 | |
| 1415 | 	SLIST_INIT(&m->m_pkthdr.tags); |
| 1416 | } |
| 1417 | |
| 1418 | /* |
| 1419 | * Set up the contents of a tag. Note that this does not fill in the free |
| 1420 | * method; the caller is expected to do that. |
| 1421 | * |
| 1422 | * XXX probably should be called m_tag_init, but that was already taken. |
| 1423 | */ |
| 1424 | static __inline void |
| 1425 | m_tag_setup(struct m_tag *t, uint32_t cookie, uint16_t type, int len) |
| 1426 | { |
| 1427 | |
| 1428 | 	t->m_tag_id = type; |
| 1429 | 	t->m_tag_len = len; |
| 1430 | 	t->m_tag_cookie = cookie; |
| 1431 | } |
| 1432 | |
| 1433 | /* |
| 1434 | * Reclaim resources associated with a tag. |
| 1435 | */ |
| 1436 | static __inline void |
| 1437 | m_tag_free(struct m_tag *t) |
| 1438 | { |
| 1439 | |
| 1440 | 	(*t->m_tag_free)(t); |
| 1441 | } |
| 1442 | |
| 1443 | /* |
| 1444 | * Return the first tag associated with an mbuf. |
| 1445 | */ |
| 1446 | static __inline struct m_tag * |
| 1447 | m_tag_first(struct mbuf *m) |
| 1448 | { |
| 1449 | |
| 1450 | 	return (SLIST_FIRST(&m->m_pkthdr.tags)); |
| 1451 | } |
| 1452 | |
| 1453 | /* |
| 1454 | * Return the next tag in the list of tags associated with an mbuf. |
| 1455 | */ |
| 1456 | static __inline struct m_tag * |
| 1457 | m_tag_next(struct mbuf *m __unused, struct m_tag *t) |
| 1458 | { |
| 1459 | |
| 1460 | 	return (SLIST_NEXT(t, m_tag_link)); |
| 1461 | } |
| 1462 | |
| 1463 | /* |
| 1464 | * Prepend a tag to the list of tags associated with an mbuf. |
| 1465 | */ |
| 1466 | static __inline void |
| 1467 | m_tag_prepend(struct mbuf *m, struct m_tag *t) |
| 1468 | { |
| 1469 | |
| 1470 | 	SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link); |
| 1471 | } |
| 1472 | |
| 1473 | /* |
| 1474 | * Unlink a tag from the list of tags associated with an mbuf. |
| 1475 | */ |
| 1476 | static __inline void |
| 1477 | m_tag_unlink(struct mbuf *m, struct m_tag *t) |
| 1478 | { |
| 1479 | |
| 1480 | 	SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link); |
| 1481 | } |
| 1482 | |
| 1483 | /* These are for OpenBSD compatibility. */ |
| 1484 | #define	MTAG_ABI_COMPAT		0		/* compatibility ABI */ |
| 1485 | |
| 1486 | static __inline struct m_tag * |
| 1487 | m_tag_get(uint16_t type, int length, int wait) |
| 1488 | { |
| 1489 | 	return (m_tag_alloc(MTAG_ABI_COMPAT, type, length, wait)); |
| 1490 | } |
| 1491 | |
| 1492 | static __inline struct m_tag * |
| 1493 | m_tag_find(struct mbuf *m, uint16_t type, struct m_tag *start) |
| 1494 | { |
| 1495 | 	return (SLIST_EMPTY(&m->m_pkthdr.tags) ? (struct m_tag *)NULL : |
| 1496 | 	 m_tag_locate(m, MTAG_ABI_COMPAT, type, start)); |
| 1497 | } |
| 1498 | |
| 1499 | static inline struct m_snd_tag * |
| 1500 | m_snd_tag_ref(struct m_snd_tag *mst) |
| 1501 | { |
| 1502 | |
| 1503 | 	refcount_acquire(&mst->refcount); |
| 1504 | 	return (mst); |
| 1505 | } |
| 1506 | |
| 1507 | static inline void |
| 1508 | m_snd_tag_rele(struct m_snd_tag *mst) |
| 1509 | { |
| 1510 | |
| 1511 | 	if (refcount_release(&mst->refcount)) |
| 1512 | 		m_snd_tag_destroy(mst); |
| 1513 | } |
| 1514 | |
| 1515 | static __inline struct mbuf * |
| 1516 | m_free(struct mbuf *m) |
| 1517 | { |
| 1518 | 	struct mbuf *n = m->m_next; |
| 1519 | |
| 1520 | 	MBUF_PROBE1(m__free, m); |
| 1521 | 	if ((m->m_flags & (M_PKTHDR|M_NOFREE)) == (M_PKTHDR|M_NOFREE)) |
| 1522 | 		m_tag_delete_chain(m, NULL); |
| 1523 | 	if (m->m_flags & M_PKTHDR && m->m_pkthdr.csum_flags & CSUM_SND_TAG) |
| 1524 | 		m_snd_tag_rele(m->m_pkthdr.snd_tag); |
| 1525 | 	if (m->m_flags & M_EXTPG) |
| 1526 | 		mb_free_extpg(m); |
| 1527 | 	else if (m->m_flags & M_EXT) |
| 1528 | 		mb_free_ext(m); |
| 1529 | 	else if ((m->m_flags & M_NOFREE) == 0) |
| 1530 | 		uma_zfree(zone_mbuf, m); |
| 1531 | 	return (n); |
| 1532 | } |
| 1533 | |
| 1534 | static __inline int |
| 1535 | rt_m_getfib(struct mbuf *m) |
| 1536 | { |
| 1537 | 	KASSERT(m->m_flags & M_PKTHDR, |
| 1538 | 	 ("%s: Attempt to get FIB from non header mbuf %p", __func__, m)); |
| 1539 | 	return (m->m_pkthdr.fibnum); |
| 1540 | } |
| 1541 | |
| 1542 | #define M_GETFIB(_m) rt_m_getfib(_m) |
| 1543 | |
| 1544 | #define M_SETFIB(_m, _fib) do {						\ |
| 1545 | KASSERT((_m)->m_flags & M_PKTHDR, \ |
| 1546 | 	 ("%s: Attempt to set FIB on non header mbuf %p", __func__, (_m))); \ |
| 1547 | 	((_m)->m_pkthdr.fibnum) = (_fib);				\ |
| 1548 | } while (0) |
| 1549 | |
| 1550 | /* flags passed as first argument for "m_xxx_tcpip_hash()" */ |
| 1551 | #define	MBUF_HASHFLAG_L2	(1 << 2) |
| 1552 | #define	MBUF_HASHFLAG_L3	(1 << 3) |
| 1553 | #define	MBUF_HASHFLAG_L4	(1 << 4) |
| 1554 | |
| 1555 | /* mbuf hashing helper routines */ |
| 1556 | uint32_t	m_ether_tcpip_hash_init(void); |
| 1557 | uint32_t	m_ether_tcpip_hash(const uint32_t, const struct mbuf *, uint32_t); |
| 1558 | uint32_t	m_infiniband_tcpip_hash_init(void); |
| 1559 | uint32_t	m_infiniband_tcpip_hash(const uint32_t, const struct mbuf *, uint32_t); |
| 1560 | |
| 1561 | #ifdef MBUF_PROFILING |
| 1562 | void m_profile(struct mbuf *m); |
| 1563 | #define M_PROFILE(m) m_profile(m) |
| 1564 | #else |
| 1565 | #define M_PROFILE(m) |
| 1566 | #endif |
| 1567 | |
| 1568 | /* |
| 1569 | * Structure describing a packet queue: mbufs linked by m_stailqpkt. |
| 1570 | * Does accounting of number of packets and has a cap. |
| 1571 | */ |
| 1572 | struct mbufq { |
| 1573 | 	STAILQ_HEAD(, mbuf)	mq_head; |
| 1574 | 	int			mq_len; |
| 1575 | 	int			mq_maxlen; |
| 1576 | }; |
| 1577 | |
| 1578 | static inline void |
| 1579 | mbufq_init(struct mbufq *mq, int maxlen) |
| 1580 | { |
| 1581 | |
| 1582 | 	STAILQ_INIT(&mq->mq_head); |
| 1583 | 	mq->mq_maxlen = maxlen; |
| 1584 | 	mq->mq_len = 0; |
| 1585 | } |
| 1586 | |
| 1587 | static inline struct mbuf * |
| 1588 | mbufq_flush(struct mbufq *mq) |
| 1589 | { |
| 1590 | 	struct mbuf *m; |
| 1591 | |
| 1592 | 	m = STAILQ_FIRST(&mq->mq_head); |
| 1593 | 	STAILQ_INIT(&mq->mq_head); |
| 1594 | 	mq->mq_len = 0; |
| 1595 | 	return (m); |
| 1596 | } |
| 1597 | |
| 1598 | static inline void |
| 1599 | mbufq_drain(struct mbufq *mq) |
| 1600 | { |
| 1601 | 	struct mbuf *m, *n; |
| 1602 | |
| 1603 | 	n = mbufq_flush(mq); |
| 1604 | 	while ((m = n) != NULL) { |
| 1605 | 		n = STAILQ_NEXT(m, m_stailqpkt); |
| 1606 | 		m_freem(m); |
| 1607 | 	} |
| 1608 | } |
| 1609 | |
| 1610 | static inline struct mbuf * |
| 1611 | mbufq_first(const struct mbufq *mq) |
| 1612 | { |
| 1613 | |
| 1614 | 	return (STAILQ_FIRST(&mq->mq_head)); |
| 1615 | } |
| 1616 | |
| 1617 | static inline struct mbuf * |
| 1618 | mbufq_last(const struct mbufq *mq) |
| 1619 | { |
| 1620 | |
| 1621 | 	return (STAILQ_LAST(&mq->mq_head, mbuf, m_stailqpkt)); |
| 1622 | } |
| 1623 | |
| 1624 | static inline bool |
| 1625 | mbufq_empty(const struct mbufq *mq) |
| 1626 | { |
| 1627 | 	return (mq->mq_len == 0); |
| 1628 | } |
| 1629 | |
| 1630 | static inline int |
| 1631 | mbufq_full(const struct mbufq *mq) |
| 1632 | { |
| 1633 | |
| 1634 | 	return (mq->mq_maxlen > 0 && mq->mq_len >= mq->mq_maxlen); |
| 1635 | } |
| 1636 | |
| 1637 | static inline int |
| 1638 | mbufq_len(const struct mbufq *mq) |
| 1639 | { |
| 1640 | |
| 1641 | 	return (mq->mq_len); |
| 1642 | } |
| 1643 | |
| 1644 | static inline int |
| 1645 | mbufq_enqueue(struct mbufq *mq, struct mbuf *m) |
| 1646 | { |
| 1647 | |
| 1648 | 	if (mbufq_full(mq)) |
| 1649 | 		return (ENOBUFS); |
| 1650 | 	STAILQ_INSERT_TAIL(&mq->mq_head, m, m_stailqpkt); |
| 1651 | 	mq->mq_len++; |
| 1652 | 	return (0); |
| 1653 | } |
| 1654 | |
| 1655 | static inline struct mbuf * |
| 1656 | mbufq_dequeue(struct mbufq *mq) |
| 1657 | { |
| 1658 | 	struct mbuf *m; |
| 1659 | |
| 1660 | 	m = STAILQ_FIRST(&mq->mq_head); |
| 1661 | 	if (m) { |
| 1662 | 		STAILQ_REMOVE_HEAD(&mq->mq_head, m_stailqpkt); |
| 1663 | 		m->m_nextpkt = NULL; |
| 1664 | 		mq->mq_len--; |
| 1665 | 	} |
| 1666 | 	return (m); |
| 1667 | } |
| 1668 | |
| 1669 | static inline void |
| 1670 | mbufq_prepend(struct mbufq *mq, struct mbuf *m) |
| 1671 | { |
| 1672 | |
| 1673 | 	STAILQ_INSERT_HEAD(&mq->mq_head, m, m_stailqpkt); |
| 1674 | 	mq->mq_len++; |
| 1675 | } |
| 1676 | |
| 1677 | /* |
| 1678 | * Note: this doesn't enforce the maximum list size for dst. |
| 1679 | */ |
| 1680 | static inline void |
| 1681 | mbufq_concat(struct mbufq *mq_dst, struct mbufq *mq_src) |
| 1682 | { |
| 1683 | |
| 1684 | 	mq_dst->mq_len += mq_src->mq_len; |
| 1685 | 	STAILQ_CONCAT(&mq_dst->mq_head, &mq_src->mq_head); |
| 1686 | 	mq_src->mq_len = 0; |
| 1687 | } |
| 1688 | |
| 1689 | /* |
| 1690 | * Structure describing a chain of mbufs linked by m_stailq, also tracking |
| 1691 | * the pointer to the last. Also does accounting of data length and memory |
| 1692 | * usage. |
| 1693 | * To be used as an argument to mbuf chain allocation and manipulation KPIs, |
| 1694 | * and can be allocated on the stack of a caller. Kernel facilities may use |
| 1695 | * it internally as a most simple implementation of a stream data buffer. |
| 1696 | */ |
| 1697 | struct mchain { |
| 1698 | 	STAILQ_HEAD(, mbuf) mc_q; |
| 1699 | 	u_int mc_len; |
| 1700 | 	u_int mc_mlen; |
| 1701 | }; |
| 1702 | |
| 1703 | #define	MCHAIN_INITIALIZER(mc)	\ |
| 1704 | 	(struct mchain){ .mc_q = STAILQ_HEAD_INITIALIZER((mc)->mc_q) } |
| 1705 | |
| 1706 | static inline struct mbuf * |
| 1707 | mc_first(struct mchain *mc) |
| 1708 | { |
| 1709 | 	return (STAILQ_FIRST(&mc->mc_q)); |
| 1710 | } |
| 1711 | |
| 1712 | static inline struct mbuf * |
| 1713 | mc_last(struct mchain *mc) |
| 1714 | { |
| 1715 | 	return (STAILQ_LAST(&mc->mc_q, mbuf, m_stailq)); |
| 1716 | } |
| 1717 | |
| 1718 | static inline bool |
| 1719 | mc_empty(struct mchain *mc) |
| 1720 | { |
| 1721 | 	return (STAILQ_EMPTY(&mc->mc_q)); |
| 1722 | } |
| 1723 | |
| 1724 | /* Account addition of m to mc. */ |
| 1725 | static inline void |
| 1726 | mc_inc(struct mchain *mc, struct mbuf *m) |
| 1727 | { |
| 1728 | 	mc->mc_len += m->m_len; |
| 1729 | 	mc->mc_mlen += MSIZE; |
| 1730 | 	if (m->m_flags & M_EXT) |
| 1731 | 		mc->mc_mlen += m->m_ext.ext_size; |
| 1732 | } |
| 1733 | |
| 1734 | /* Account removal of m from mc. */ |
| 1735 | static inline void |
| 1736 | mc_dec(struct mchain *mc, struct mbuf *m) |
| 1737 | { |
| 1738 | 	MPASS(mc->mc_len >= m->m_len); |
| 1739 | 	mc->mc_len -= m->m_len; |
| 1740 | 	MPASS(mc->mc_mlen >= MSIZE); |
| 1741 | 	mc->mc_mlen -= MSIZE; |
| 1742 | 	if (m->m_flags & M_EXT) { |
| 1743 | 		MPASS(mc->mc_mlen >= m->m_ext.ext_size); |
| 1744 | 		mc->mc_mlen -= m->m_ext.ext_size; |
| 1745 | 	} |
| 1746 | } |
| 1747 | |
| 1748 | /* |
| 1749 | * Get mchain from a classic mbuf chain linked by m_next. Two hacks here: |
| 1750 | * we use the fact that m_next is alias to m_stailq, we use internal queue(3) |
| 1751 | * fields. |
| 1752 | */ |
| 1753 | static inline void |
| 1754 | mc_init_m(struct mchain *mc, struct mbuf *m) |
| 1755 | { |
| 1756 | 	struct mbuf *last; |
| 1757 | |
| 1758 | 	STAILQ_FIRST(&mc->mc_q) = m; |
| 1759 | 	mc->mc_len = mc->mc_mlen = 0; |
| 1760 | 	STAILQ_FOREACH(m, &mc->mc_q, m_stailq) { |
| 1761 | 		mc_inc(mc, m); |
| 1762 | 		last = m; |
| 1763 | 	} |
| 1764 | 	mc->mc_q.stqh_last = &STAILQ_NEXT(last, m_stailq); |
| 1765 | } |
| 1766 | |
| 1767 | static inline void |
| 1768 | mc_freem(struct mchain *mc) |
| 1769 | { |
| 1770 | 	if (!mc_empty(mc)) |
| 1771 | 		m_freem(mc_first(mc)); |
| 1772 | } |
| 1773 | |
| 1774 | static inline void |
| 1775 | mc_prepend(struct mchain *mc, struct mbuf *m) |
| 1776 | { |
| 1777 | 	STAILQ_INSERT_HEAD(&mc->mc_q, m, m_stailq); |
| 1778 | 	mc_inc(mc, m); |
| 1779 | } |
| 1780 | |
| 1781 | static inline void |
| 1782 | mc_append(struct mchain *mc, struct mbuf *m) |
| 1783 | { |
| 1784 | 	STAILQ_INSERT_TAIL(&mc->mc_q, m, m_stailq); |
| 1785 | 	mc_inc(mc, m); |
| 1786 | } |
| 1787 | |
| 1788 | static inline void |
| 1789 | mc_concat(struct mchain *head, struct mchain *tail) |
| 1790 | { |
| 1791 | 	STAILQ_CONCAT(&head->mc_q, &tail->mc_q); |
| 1792 | 	head->mc_len += tail->mc_len; |
| 1793 | 	head->mc_mlen += tail->mc_mlen; |
| 1794 | 	tail->mc_len = tail->mc_mlen = 0; |
| 1795 | } |
| 1796 | |
| 1797 | /* |
| 1798 | * Note: STAILQ_REMOVE() is expensive. mc_remove_after() needs to be provided |
| 1799 | * as long as there consumers that would benefit from it. |
| 1800 | */ |
| 1801 | static inline void |
| 1802 | mc_remove(struct mchain *mc, struct mbuf *m) |
| 1803 | { |
| 1804 | 	STAILQ_REMOVE(&mc->mc_q, m, mbuf, m_stailq); |
| 1805 | 	mc_dec(mc, m); |
| 1806 | } |
| 1807 | |
| 1808 | int mc_get(struct mchain *, u_int, int, short, int); |
| 1809 | int mc_split(struct mchain *, struct mchain *, u_int, int); |
| 1810 | int mc_uiotomc(struct mchain *, struct uio *, u_int, u_int, int, int); |
| 1811 | |
| 1812 | #ifdef _SYS_TIMESPEC_H_ |
| 1813 | static inline void |
| 1814 | mbuf_tstmp2timespec(struct mbuf *m, struct timespec *ts) |
| 1815 | { |
| 1816 | |
| 1817 | 	M_ASSERTPKTHDR(m); |
| 1818 | 	KASSERT((m->m_flags & (M_TSTMP|M_TSTMP_LRO)) != 0, |
| 1819 | 	 ("%s: mbuf %p no M_TSTMP or M_TSTMP_LRO", __func__, m)); |
| 1820 | 	ts->tv_sec = m->m_pkthdr.rcv_tstmp / 1000000000; |
| 1821 | 	ts->tv_nsec = m->m_pkthdr.rcv_tstmp % 1000000000; |
| 1822 | } |
| 1823 | #endif |
| 1824 | |
| 1825 | static inline void |
| 1826 | mbuf_tstmp2timeval(struct mbuf *m, struct timeval *tv) |
| 1827 | { |
| 1828 | |
| 1829 | 	M_ASSERTPKTHDR(m); |
| 1830 | 	KASSERT((m->m_flags & (M_TSTMP|M_TSTMP_LRO)) != 0, |
| 1831 | 	 ("%s: mbuf %p no M_TSTMP or M_TSTMP_LRO", __func__, m)); |
| 1832 | 	tv->tv_sec = m->m_pkthdr.rcv_tstmp / 1000000000; |
| 1833 | 	tv->tv_usec = (m->m_pkthdr.rcv_tstmp % 1000000000) / 1000; |
| 1834 | } |
| 1835 | |
| 1836 | #ifdef DEBUGNET |
| 1837 | /* Invoked from the debugnet client code. */ |
| 1838 | void	debugnet_mbuf_drain(void); |
| 1839 | void	debugnet_mbuf_start(void); |
| 1840 | void	debugnet_mbuf_finish(void); |
| 1841 | void	debugnet_mbuf_reinit(int nmbuf, int nclust, int clsize); |
| 1842 | #endif |
| 1843 | |
| 1844 | static inline bool |
| 1845 | mbuf_has_tls_session(struct mbuf *m) |
| 1846 | { |
| 1847 | |
| 1848 | 	if (m->m_flags & M_EXTPG) { |
| 1849 | 		if (m->m_epg_tls != NULL) { |
| 1850 | 			return (true); |
| 1851 | 		} |
| 1852 | 	} |
| 1853 | 	return (false); |
| 1854 | } |
| 1855 | |
| 1856 | #endif /* _KERNEL */ |
| 1857 | #endif /* !_SYS_MBUF_H_ */ |