root / lab4 / .minix-src / include / sys / mbuf.h @ 13
History | View | Annotate | Download (30.5 KB)
1 |
/* $NetBSD: mbuf.h,v 1.158 2015/06/04 09:19:59 ozaki-r Exp $ */
|
---|---|
2 |
|
3 |
/*-
|
4 |
* Copyright (c) 1996, 1997, 1999, 2001, 2007 The NetBSD Foundation, Inc.
|
5 |
* All rights reserved.
|
6 |
*
|
7 |
* This code is derived from software contributed to The NetBSD Foundation
|
8 |
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
9 |
* NASA Ames Research Center and Matt Thomas of 3am Software Foundry.
|
10 |
*
|
11 |
* Redistribution and use in source and binary forms, with or without
|
12 |
* modification, are permitted provided that the following conditions
|
13 |
* are met:
|
14 |
* 1. Redistributions of source code must retain the above copyright
|
15 |
* notice, this list of conditions and the following disclaimer.
|
16 |
* 2. Redistributions in binary form must reproduce the above copyright
|
17 |
* notice, this list of conditions and the following disclaimer in the
|
18 |
* documentation and/or other materials provided with the distribution.
|
19 |
*
|
20 |
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
21 |
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
22 |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
23 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
24 |
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25 |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26 |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30 |
* POSSIBILITY OF SUCH DAMAGE.
|
31 |
*/
|
32 |
|
33 |
/*
|
34 |
* Copyright (c) 1982, 1986, 1988, 1993
|
35 |
* The Regents of the University of California. All rights reserved.
|
36 |
*
|
37 |
* Redistribution and use in source and binary forms, with or without
|
38 |
* modification, are permitted provided that the following conditions
|
39 |
* are met:
|
40 |
* 1. Redistributions of source code must retain the above copyright
|
41 |
* notice, this list of conditions and the following disclaimer.
|
42 |
* 2. Redistributions in binary form must reproduce the above copyright
|
43 |
* notice, this list of conditions and the following disclaimer in the
|
44 |
* documentation and/or other materials provided with the distribution.
|
45 |
* 3. Neither the name of the University nor the names of its contributors
|
46 |
* may be used to endorse or promote products derived from this software
|
47 |
* without specific prior written permission.
|
48 |
*
|
49 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
50 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
51 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
52 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
53 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
54 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
55 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
56 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
57 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
58 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
59 |
* SUCH DAMAGE.
|
60 |
*
|
61 |
* @(#)mbuf.h 8.5 (Berkeley) 2/19/95
|
62 |
*/
|
63 |
|
64 |
#ifndef _SYS_MBUF_H_
|
65 |
#define _SYS_MBUF_H_
|
66 |
|
67 |
#ifdef _KERNEL_OPT
|
68 |
#include "opt_mbuftrace.h" |
69 |
#endif
|
70 |
|
71 |
#ifndef M_WAITOK
|
72 |
#include <sys/malloc.h> |
73 |
#endif
|
74 |
#include <sys/pool.h> |
75 |
#include <sys/queue.h> |
76 |
#if defined(_KERNEL)
|
77 |
#include <sys/percpu_types.h> |
78 |
#endif /* defined(_KERNEL) */ |
79 |
|
80 |
/* For offsetof() */
|
81 |
#if defined(_KERNEL) || defined(_STANDALONE)
|
82 |
#include <sys/systm.h> |
83 |
#else
|
84 |
#include <stddef.h> |
85 |
#endif
|
86 |
|
87 |
#include <uvm/uvm_param.h> /* for MIN_PAGE_SIZE */ |
88 |
|
89 |
/*
|
90 |
* Mbufs are of a single size, MSIZE (machine/param.h), which
|
91 |
* includes overhead. An mbuf may add a single "mbuf cluster" of size
|
92 |
* MCLBYTES (also in machine/param.h), which has no additional overhead
|
93 |
* and is used instead of the internal data area; this is done when
|
94 |
* at least MINCLSIZE of data must be stored.
|
95 |
*/
|
96 |
|
97 |
/* Packet tags structure */
|
98 |
struct m_tag {
|
99 |
SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */
|
100 |
uint16_t m_tag_id; /* Tag ID */
|
101 |
uint16_t m_tag_len; /* Length of data */
|
102 |
}; |
103 |
|
104 |
/* mbuf ownership structure */
|
105 |
struct mowner {
|
106 |
char mo_name[16]; /* owner name (fxp0) */ |
107 |
char mo_descr[16]; /* owner description (input) */ |
108 |
LIST_ENTRY(mowner) mo_link; /* */
|
109 |
struct percpu *mo_counters;
|
110 |
}; |
111 |
|
112 |
#define MOWNER_INIT(x, y) { .mo_name = x, .mo_descr = y }
|
113 |
|
114 |
enum mowner_counter_index {
|
115 |
MOWNER_COUNTER_CLAIMS, /* # of small mbuf claimed */
|
116 |
MOWNER_COUNTER_RELEASES, /* # of small mbuf released */
|
117 |
MOWNER_COUNTER_CLUSTER_CLAIMS, /* # of M_CLUSTER mbuf claimed */
|
118 |
MOWNER_COUNTER_CLUSTER_RELEASES,/* # of M_CLUSTER mbuf released */
|
119 |
MOWNER_COUNTER_EXT_CLAIMS, /* # of M_EXT mbuf claimed */
|
120 |
MOWNER_COUNTER_EXT_RELEASES, /* # of M_EXT mbuf released */
|
121 |
|
122 |
MOWNER_COUNTER_NCOUNTERS, |
123 |
}; |
124 |
|
125 |
#if defined(_KERNEL)
|
126 |
struct mowner_counter {
|
127 |
u_long mc_counter[MOWNER_COUNTER_NCOUNTERS]; |
128 |
}; |
129 |
#endif /* defined(_KERNEL) */ |
130 |
|
131 |
/* userland-exported version of struct mowner */
|
132 |
struct mowner_user {
|
133 |
char mo_name[16]; /* owner name (fxp0) */ |
134 |
char mo_descr[16]; /* owner description (input) */ |
135 |
LIST_ENTRY(mowner) mo_link; /* unused padding; for compatibility */
|
136 |
u_long mo_counter[MOWNER_COUNTER_NCOUNTERS]; /* counters */
|
137 |
}; |
138 |
|
139 |
/*
|
140 |
* Macros for type conversion
|
141 |
* mtod(m,t) - convert mbuf pointer to data pointer of correct type
|
142 |
*/
|
143 |
#define mtod(m, t) ((t)((m)->m_data))
|
144 |
|
145 |
/* header at beginning of each mbuf: */
|
146 |
struct m_hdr {
|
147 |
struct mbuf *mh_next; /* next buffer in chain */ |
148 |
struct mbuf *mh_nextpkt; /* next chain in queue/record */ |
149 |
char *mh_data; /* location of data */ |
150 |
struct mowner *mh_owner; /* mbuf owner */ |
151 |
int mh_len; /* amount of data in this mbuf */ |
152 |
int mh_flags; /* flags; see below */ |
153 |
paddr_t mh_paddr; /* physical address of mbuf */
|
154 |
short mh_type; /* type of data in this mbuf */ |
155 |
}; |
156 |
|
157 |
/*
|
158 |
* record/packet header in first mbuf of chain; valid if M_PKTHDR set
|
159 |
*
|
160 |
* A note about csum_data: For the out-bound direction, the low 16 bits
|
161 |
* indicates the offset after the L4 header where the final L4 checksum value
|
162 |
* is to be stored and the high 16 bits is the length of the L3 header (the
|
163 |
* start of the data to be checksumed). For the in-bound direction, it is only
|
164 |
* valid if the M_CSUM_DATA flag is set. In this case, an L4 checksum has been
|
165 |
* calculated by hardware, but it is up to software to perform final
|
166 |
* verification.
|
167 |
*
|
168 |
* Note for in-bound TCP/UDP checksums, we expect the csum_data to NOT
|
169 |
* be bit-wise inverted (the final step in the calculation of an IP
|
170 |
* checksum) -- this is so we can accumulate the checksum for fragmented
|
171 |
* packets during reassembly.
|
172 |
*/
|
173 |
struct pkthdr {
|
174 |
struct ifnet *rcvif; /* rcv interface */ |
175 |
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
|
176 |
int len; /* total packet length */ |
177 |
int csum_flags; /* checksum flags */ |
178 |
uint32_t csum_data; /* checksum data */
|
179 |
u_int segsz; /* segment size */
|
180 |
}; |
181 |
|
182 |
/*
|
183 |
* Note: These bits are carefully arrange so that the compiler can have
|
184 |
* a prayer of generating a jump table.
|
185 |
*/
|
186 |
#define M_CSUM_TCPv4 0x00000001 /* TCP header/payload */ |
187 |
#define M_CSUM_UDPv4 0x00000002 /* UDP header/payload */ |
188 |
#define M_CSUM_TCP_UDP_BAD 0x00000004 /* TCP/UDP checksum bad */ |
189 |
#define M_CSUM_DATA 0x00000008 /* consult csum_data */ |
190 |
#define M_CSUM_TCPv6 0x00000010 /* IPv6 TCP header/payload */ |
191 |
#define M_CSUM_UDPv6 0x00000020 /* IPv6 UDP header/payload */ |
192 |
#define M_CSUM_IPv4 0x00000040 /* IPv4 header */ |
193 |
#define M_CSUM_IPv4_BAD 0x00000080 /* IPv4 header checksum bad */ |
194 |
#define M_CSUM_TSOv4 0x00000100 /* TCPv4 segmentation offload */ |
195 |
#define M_CSUM_TSOv6 0x00000200 /* TCPv6 segmentation offload */ |
196 |
|
197 |
/* Checksum-assist quirks: keep separate from jump-table bits. */
|
198 |
#define M_CSUM_NO_PSEUDOHDR 0x80000000 /* Rx csum_data does not include |
199 |
* the UDP/TCP pseudo-hdr, and
|
200 |
* is not yet 1s-complemented.
|
201 |
*/
|
202 |
|
203 |
#define M_CSUM_BITS \
|
204 |
"\20\1TCPv4\2UDPv4\3TCP_UDP_BAD\4DATA\5TCPv6\6UDPv6\7IPv4\10IPv4_BAD" \
|
205 |
"\11TSOv4\12TSOv6\40NO_PSEUDOHDR"
|
206 |
|
207 |
/*
|
208 |
* Macros for manipulating csum_data on outgoing packets. These are
|
209 |
* used to pass information down from the L4/L3 to the L2.
|
210 |
*/
|
211 |
#define M_CSUM_DATA_IPv4_IPHL(x) ((x) >> 16) |
212 |
#define M_CSUM_DATA_IPv4_OFFSET(x) ((x) & 0xffff) |
213 |
|
214 |
/*
|
215 |
* Macros for M_CSUM_TCPv6 and M_CSUM_UDPv6
|
216 |
*
|
217 |
* M_CSUM_DATA_IPv6_HL: length of ip6_hdr + ext header.
|
218 |
* ie. offset of UDP/TCP header in the packet.
|
219 |
*
|
220 |
* M_CSUM_DATA_IPv6_OFFSET: offset of the checksum field in UDP/TCP header.
|
221 |
*/
|
222 |
|
223 |
#define M_CSUM_DATA_IPv6_HL(x) ((x) >> 16) |
224 |
#define M_CSUM_DATA_IPv6_HL_SET(x, v) (x) = ((x) & 0xffff) | ((v) << 16) |
225 |
#define M_CSUM_DATA_IPv6_OFFSET(x) ((x) & 0xffff) |
226 |
|
227 |
/*
|
228 |
* Max # of pages we can attach to m_ext. This is carefully chosen
|
229 |
* to be able to handle SOSEND_LOAN_CHUNK with our minimum sized page.
|
230 |
*/
|
231 |
#ifdef MIN_PAGE_SIZE
|
232 |
#define M_EXT_MAXPAGES ((65536 / MIN_PAGE_SIZE) + 1) |
233 |
#endif
|
234 |
|
235 |
/* description of external storage mapped into mbuf, valid if M_EXT set */
|
236 |
struct _m_ext_storage {
|
237 |
unsigned int ext_refcnt; |
238 |
int ext_flags;
|
239 |
char *ext_buf; /* start of buffer */ |
240 |
void (*ext_free) /* free routine if not the usual */ |
241 |
(struct mbuf *, void *, size_t, void *); |
242 |
void *ext_arg; /* argument for ext_free */ |
243 |
size_t ext_size; /* size of buffer, for ext_free */
|
244 |
union {
|
245 |
paddr_t extun_paddr; /* physical address (M_EXT_CLUSTER) */
|
246 |
/* pages (M_EXT_PAGES) */
|
247 |
/*
|
248 |
* XXX This is gross, but it doesn't really matter; this is
|
249 |
* XXX overlaid on top of the mbuf data area.
|
250 |
*/
|
251 |
#ifdef M_EXT_MAXPAGES
|
252 |
struct vm_page *extun_pgs[M_EXT_MAXPAGES];
|
253 |
#endif
|
254 |
} ext_un; |
255 |
#define ext_paddr ext_un.extun_paddr
|
256 |
#define ext_pgs ext_un.extun_pgs
|
257 |
#ifdef DEBUG
|
258 |
const char *ext_ofile; |
259 |
const char *ext_nfile; |
260 |
int ext_oline;
|
261 |
int ext_nline;
|
262 |
#endif
|
263 |
}; |
264 |
|
265 |
struct _m_ext {
|
266 |
struct mbuf *ext_ref;
|
267 |
struct _m_ext_storage ext_storage;
|
268 |
}; |
269 |
|
270 |
#define M_PADDR_INVALID POOL_PADDR_INVALID
|
271 |
|
272 |
/*
|
273 |
* Definition of "struct mbuf".
|
274 |
* Don't change this without understanding how MHLEN/MLEN are defined.
|
275 |
*/
|
276 |
#define MBUF_DEFINE(name, mhlen, mlen) \
|
277 |
struct name { \
|
278 |
struct m_hdr m_hdr; \
|
279 |
union { \
|
280 |
struct { \
|
281 |
struct pkthdr MH_pkthdr; \
|
282 |
union { \
|
283 |
struct _m_ext MH_ext; \
|
284 |
char MH_databuf[(mhlen)]; \
|
285 |
} MH_dat; \ |
286 |
} MH; \ |
287 |
char M_databuf[(mlen)]; \
|
288 |
} M_dat; \ |
289 |
} |
290 |
#define m_next m_hdr.mh_next
|
291 |
#define m_len m_hdr.mh_len
|
292 |
#define m_data m_hdr.mh_data
|
293 |
#define m_owner m_hdr.mh_owner
|
294 |
#define m_type m_hdr.mh_type
|
295 |
#define m_flags m_hdr.mh_flags
|
296 |
#define m_nextpkt m_hdr.mh_nextpkt
|
297 |
#define m_paddr m_hdr.mh_paddr
|
298 |
#define m_pkthdr M_dat.MH.MH_pkthdr
|
299 |
#define m_ext_storage M_dat.MH.MH_dat.MH_ext.ext_storage
|
300 |
#define m_ext_ref M_dat.MH.MH_dat.MH_ext.ext_ref
|
301 |
#define m_ext m_ext_ref->m_ext_storage
|
302 |
#define m_pktdat M_dat.MH.MH_dat.MH_databuf
|
303 |
#define m_dat M_dat.M_databuf
|
304 |
|
305 |
/*
|
306 |
* Dummy mbuf structure to calculate the right values for MLEN/MHLEN, taking
|
307 |
* into account inter-structure padding.
|
308 |
*/
|
309 |
MBUF_DEFINE(_mbuf_dummy, 1, 1); |
310 |
|
311 |
/* normal data len */
|
312 |
#define MLEN (MSIZE - offsetof(struct _mbuf_dummy, m_dat)) |
313 |
/* data len w/pkthdr */
|
314 |
#define MHLEN (MSIZE - offsetof(struct _mbuf_dummy, m_pktdat)) |
315 |
|
316 |
#define MINCLSIZE (MHLEN+MLEN+1) /* smallest amount to put in cluster */ |
317 |
#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */ |
318 |
|
319 |
/*
|
320 |
* The *real* struct mbuf
|
321 |
*/
|
322 |
MBUF_DEFINE(mbuf, MHLEN, MLEN); |
323 |
|
324 |
/* mbuf flags */
|
325 |
#define M_EXT 0x00000001 /* has associated external storage */ |
326 |
#define M_PKTHDR 0x00000002 /* start of record */ |
327 |
#define M_EOR 0x00000004 /* end of record */ |
328 |
#define M_PROTO1 0x00000008 /* protocol-specific */ |
329 |
|
330 |
/* mbuf pkthdr flags, also in m_flags */
|
331 |
#define M_AUTHIPHDR 0x00000010 /* data origin authentication for |
332 |
* IP header */
|
333 |
#define M_DECRYPTED 0x00000020 /* confidentiality */ |
334 |
#define M_LOOP 0x00000040 /* for Mbuf statistics */ |
335 |
#define M_AUTHIPDGM 0x00000080 /* data origin authentication */ |
336 |
#define M_BCAST 0x00000100 /* send/received as link-level |
337 |
* broadcast */
|
338 |
#define M_MCAST 0x00000200 /* send/received as link-level |
339 |
* multicast */
|
340 |
#define M_CANFASTFWD 0x00000400 /* used by filters to indicate |
341 |
* packet can be fast-forwarded */
|
342 |
#define M_ANYCAST6 0x00000800 /* received as IPv6 anycast */ |
343 |
|
344 |
#define M_LINK0 0x00001000 /* link layer specific flag */ |
345 |
#define M_LINK1 0x00002000 /* link layer specific flag */ |
346 |
#define M_LINK2 0x00004000 /* link layer specific flag */ |
347 |
|
348 |
#define M_LINK3 0x00008000 /* link layer specific flag */ |
349 |
#define M_LINK4 0x00010000 /* link layer specific flag */ |
350 |
#define M_LINK5 0x00020000 /* link layer specific flag */ |
351 |
#define M_LINK6 0x00040000 /* link layer specific flag */ |
352 |
#define M_LINK7 0x00080000 /* link layer specific flag */ |
353 |
|
354 |
/* additional flags for M_EXT mbufs */
|
355 |
#define M_EXT_FLAGS 0xff000000 |
356 |
#define M_EXT_CLUSTER 0x01000000 /* ext is a cluster */ |
357 |
#define M_EXT_PAGES 0x02000000 /* ext_pgs is valid */ |
358 |
#define M_EXT_ROMAP 0x04000000 /* ext mapping is r-o at MMU */ |
359 |
#define M_EXT_RW 0x08000000 /* ext storage is writable */ |
360 |
|
361 |
/* for source-level compatibility */
|
362 |
#define M_CLUSTER M_EXT_CLUSTER
|
363 |
|
364 |
#define M_FLAGS_BITS \
|
365 |
"\20\1EXT\2PKTHDR\3EOR\4PROTO1\5AUTHIPHDR\6DECRYPTED\7LOOP\10AUTHIPDGM" \
|
366 |
"\11BCAST\12MCAST\13CANFASTFWD\14ANYCAST6\15LINK0\16LINK1\17LINK2\20LINK3" \
|
367 |
"\21LINK4\22LINK5\23LINK6\24LINK7" \
|
368 |
"\31EXT_CLUSTER\32EXT_PAGES\33EXT_ROMAP\34EXT_RW"
|
369 |
|
370 |
/* flags copied when copying m_pkthdr */
|
371 |
#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_BCAST|M_MCAST|M_CANFASTFWD|M_ANYCAST6|M_LINK0|M_LINK1|M_LINK2|M_AUTHIPHDR|M_DECRYPTED|M_LOOP|M_AUTHIPDGM)
|
372 |
|
373 |
/* flag copied when shallow-copying external storage */
|
374 |
#define M_EXTCOPYFLAGS (M_EXT|M_EXT_FLAGS)
|
375 |
|
376 |
/* mbuf types */
|
377 |
#define MT_FREE 0 /* should be on free list */ |
378 |
#define MT_DATA 1 /* dynamic (data) allocation */ |
379 |
#define MT_HEADER 2 /* packet header */ |
380 |
#define MT_SONAME 3 /* socket name */ |
381 |
#define MT_SOOPTS 4 /* socket options */ |
382 |
#define MT_FTABLE 5 /* fragment reassembly header */ |
383 |
#define MT_CONTROL 6 /* extra-data protocol message */ |
384 |
#define MT_OOBDATA 7 /* expedited data */ |
385 |
|
386 |
#ifdef MBUFTYPES
|
387 |
static const char * const mbuftypes[] = { |
388 |
"mbfree",
|
389 |
"mbdata",
|
390 |
"mbheader",
|
391 |
"mbsoname",
|
392 |
"mbsopts",
|
393 |
"mbftable",
|
394 |
"mbcontrol",
|
395 |
"mboobdata",
|
396 |
}; |
397 |
#endif
|
398 |
|
399 |
/* flags to m_get/MGET */
|
400 |
#define M_DONTWAIT M_NOWAIT
|
401 |
#define M_WAIT M_WAITOK
|
402 |
|
403 |
#ifdef MBUFTRACE
|
404 |
/*
|
405 |
* mbuf allocation tracing
|
406 |
*/
|
407 |
void mowner_init(struct mbuf *, int); |
408 |
void mowner_ref(struct mbuf *, int); |
409 |
void m_claim(struct mbuf *, struct mowner *); |
410 |
void mowner_revoke(struct mbuf *, bool, int); |
411 |
void mowner_attach(struct mowner *); |
412 |
void mowner_detach(struct mowner *); |
413 |
void m_claimm(struct mbuf *, struct mowner *); |
414 |
#else
|
415 |
#define mowner_init(m, type) do { } while (/* CONSTCOND */ 0) |
416 |
#define mowner_ref(m, flags) do { } while (/* CONSTCOND */ 0) |
417 |
#define mowner_revoke(m, all, flags) do { } while (/* CONSTCOND */ 0) |
418 |
#define m_claim(m, mowner) do { } while (/* CONSTCOND */ 0) |
419 |
#define mowner_attach(mo) do { } while (/* CONSTCOND */ 0) |
420 |
#define mowner_detach(mo) do { } while (/* CONSTCOND */ 0) |
421 |
#define m_claimm(m, mo) do { } while (/* CONSTCOND */ 0) |
422 |
#endif
|
423 |
|
424 |
#define MCLAIM(m, mo) m_claim((m), (mo))
|
425 |
#define MOWNER_ATTACH(mo) mowner_attach(mo)
|
426 |
#define MOWNER_DETACH(mo) mowner_detach(mo)
|
427 |
|
428 |
/*
|
429 |
* mbuf allocation/deallocation macros:
|
430 |
*
|
431 |
* MGET(struct mbuf *m, int how, int type)
|
432 |
* allocates an mbuf and initializes it to contain internal data.
|
433 |
*
|
434 |
* MGETHDR(struct mbuf *m, int how, int type)
|
435 |
* allocates an mbuf and initializes it to contain a packet header
|
436 |
* and internal data.
|
437 |
*
|
438 |
* If 'how' is M_WAIT, these macros (and the corresponding functions)
|
439 |
* are guaranteed to return successfully.
|
440 |
*/
|
441 |
#define MGET(m, how, type) m = m_get((how), (type))
|
442 |
#define MGETHDR(m, how, type) m = m_gethdr((how), (type))
|
443 |
|
444 |
#if defined(_KERNEL)
|
445 |
#define _M_
|
446 |
/*
|
447 |
* Macros for tracking external storage associated with an mbuf.
|
448 |
*/
|
449 |
#ifdef DEBUG
|
450 |
#define MCLREFDEBUGN(m, file, line) \
|
451 |
do { \
|
452 |
(m)->m_ext.ext_nfile = (file); \ |
453 |
(m)->m_ext.ext_nline = (line); \ |
454 |
} while (/* CONSTCOND */ 0) |
455 |
|
456 |
#define MCLREFDEBUGO(m, file, line) \
|
457 |
do { \
|
458 |
(m)->m_ext.ext_ofile = (file); \ |
459 |
(m)->m_ext.ext_oline = (line); \ |
460 |
} while (/* CONSTCOND */ 0) |
461 |
#else
|
462 |
#define MCLREFDEBUGN(m, file, line)
|
463 |
#define MCLREFDEBUGO(m, file, line)
|
464 |
#endif
|
465 |
|
466 |
#define MCLINITREFERENCE(m) \
|
467 |
do { \
|
468 |
KDASSERT(((m)->m_flags & M_EXT) == 0); \
|
469 |
(m)->m_ext_ref = (m); \ |
470 |
(m)->m_ext.ext_refcnt = 1; \
|
471 |
MCLREFDEBUGO((m), __FILE__, __LINE__); \ |
472 |
MCLREFDEBUGN((m), NULL, 0); \ |
473 |
} while (/* CONSTCOND */ 0) |
474 |
|
475 |
/*
|
476 |
* Macros for mbuf external storage.
|
477 |
*
|
478 |
* MCLGET allocates and adds an mbuf cluster to a normal mbuf;
|
479 |
* the flag M_EXT is set upon success.
|
480 |
*
|
481 |
* MEXTMALLOC allocates external storage and adds it to
|
482 |
* a normal mbuf; the flag M_EXT is set upon success.
|
483 |
*
|
484 |
* MEXTADD adds pre-allocated external storage to
|
485 |
* a normal mbuf; the flag M_EXT is set upon success.
|
486 |
*/
|
487 |
|
488 |
#define _MCLGET(m, pool_cache, size, how) \
|
489 |
do { \
|
490 |
(m)->m_ext_storage.ext_buf = (char *) \
|
491 |
pool_cache_get_paddr((pool_cache), \ |
492 |
(how) == M_WAIT ? (PR_WAITOK|PR_LIMITFAIL) : 0, \
|
493 |
&(m)->m_ext_storage.ext_paddr); \ |
494 |
if ((m)->m_ext_storage.ext_buf != NULL) { \ |
495 |
MCLINITREFERENCE(m); \ |
496 |
(m)->m_data = (m)->m_ext.ext_buf; \ |
497 |
(m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | \ |
498 |
M_EXT|M_CLUSTER|M_EXT_RW; \ |
499 |
(m)->m_ext.ext_flags = 0; \
|
500 |
(m)->m_ext.ext_size = (size); \ |
501 |
(m)->m_ext.ext_free = NULL; \
|
502 |
(m)->m_ext.ext_arg = (pool_cache); \ |
503 |
/* ext_paddr initialized above */ \
|
504 |
mowner_ref((m), M_EXT|M_CLUSTER); \ |
505 |
} \ |
506 |
} while (/* CONSTCOND */ 0) |
507 |
|
508 |
/*
|
509 |
* The standard mbuf cluster pool.
|
510 |
*/
|
511 |
#define MCLGET(m, how) _MCLGET((m), mcl_cache, MCLBYTES, (how))
|
512 |
|
513 |
#define MEXTMALLOC(m, size, how) \
|
514 |
do { \
|
515 |
(m)->m_ext_storage.ext_buf = (char *) \
|
516 |
malloc((size), mbtypes[(m)->m_type], (how)); \ |
517 |
if ((m)->m_ext_storage.ext_buf != NULL) { \ |
518 |
MCLINITREFERENCE(m); \ |
519 |
(m)->m_data = (m)->m_ext.ext_buf; \ |
520 |
(m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | \ |
521 |
M_EXT|M_EXT_RW; \ |
522 |
(m)->m_ext.ext_flags = 0; \
|
523 |
(m)->m_ext.ext_size = (size); \ |
524 |
(m)->m_ext.ext_free = NULL; \
|
525 |
(m)->m_ext.ext_arg = NULL; \
|
526 |
mowner_ref((m), M_EXT); \ |
527 |
} \ |
528 |
} while (/* CONSTCOND */ 0) |
529 |
|
530 |
#define MEXTADD(m, buf, size, type, free, arg) \
|
531 |
do { \
|
532 |
MCLINITREFERENCE(m); \ |
533 |
(m)->m_data = (m)->m_ext.ext_buf = (char *)(buf); \
|
534 |
(m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | M_EXT; \ |
535 |
(m)->m_ext.ext_flags = 0; \
|
536 |
(m)->m_ext.ext_size = (size); \ |
537 |
(m)->m_ext.ext_free = (free); \ |
538 |
(m)->m_ext.ext_arg = (arg); \ |
539 |
mowner_ref((m), M_EXT); \ |
540 |
} while (/* CONSTCOND */ 0) |
541 |
|
542 |
/*
|
543 |
* Reset the data pointer on an mbuf.
|
544 |
*/
|
545 |
#define MRESETDATA(m) \
|
546 |
do { \
|
547 |
if ((m)->m_flags & M_EXT) \
|
548 |
(m)->m_data = (m)->m_ext.ext_buf; \ |
549 |
else if ((m)->m_flags & M_PKTHDR) \ |
550 |
(m)->m_data = (m)->m_pktdat; \ |
551 |
else \
|
552 |
(m)->m_data = (m)->m_dat; \ |
553 |
} while (/* CONSTCOND */ 0) |
554 |
|
555 |
/*
|
556 |
* MFREE(struct mbuf *m, struct mbuf *n)
|
557 |
* Free a single mbuf and associated external storage.
|
558 |
* Place the successor, if any, in n.
|
559 |
*/
|
560 |
#define MFREE(m, n) \
|
561 |
mowner_revoke((m), 1, (m)->m_flags); \
|
562 |
mbstat_type_add((m)->m_type, -1); \
|
563 |
if ((m)->m_flags & M_PKTHDR) \
|
564 |
m_tag_delete_chain((m), NULL); \
|
565 |
(n) = (m)->m_next; \ |
566 |
if ((m)->m_flags & M_EXT) { \
|
567 |
m_ext_free((m)); \ |
568 |
} else { \
|
569 |
KASSERT((m)->m_type != MT_FREE); \ |
570 |
(m)->m_type = MT_FREE; \ |
571 |
pool_cache_put(mb_cache, (m)); \ |
572 |
} \ |
573 |
|
574 |
/*
|
575 |
* Copy mbuf pkthdr from `from' to `to'.
|
576 |
* `from' must have M_PKTHDR set, and `to' must be empty.
|
577 |
*/
|
578 |
#define M_COPY_PKTHDR(to, from) \
|
579 |
do { \
|
580 |
(to)->m_pkthdr = (from)->m_pkthdr; \ |
581 |
(to)->m_flags = (from)->m_flags & M_COPYFLAGS; \ |
582 |
SLIST_INIT(&(to)->m_pkthdr.tags); \ |
583 |
m_tag_copy_chain((to), (from)); \ |
584 |
(to)->m_data = (to)->m_pktdat; \ |
585 |
} while (/* CONSTCOND */ 0) |
586 |
|
587 |
/*
|
588 |
* Move mbuf pkthdr from `from' to `to'.
|
589 |
* `from' must have M_PKTHDR set, and `to' must be empty.
|
590 |
*/
|
591 |
#define M_MOVE_PKTHDR(to, from) m_move_pkthdr(to, from)
|
592 |
|
593 |
/*
|
594 |
* Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
|
595 |
* an object of the specified size at the end of the mbuf, longword aligned.
|
596 |
*/
|
597 |
#define M_ALIGN(m, len) \
|
598 |
do { \
|
599 |
(m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); \ |
600 |
} while (/* CONSTCOND */ 0) |
601 |
|
602 |
/*
|
603 |
* As above, for mbufs allocated with m_gethdr/MGETHDR
|
604 |
* or initialized by M_COPY_PKTHDR.
|
605 |
*/
|
606 |
#define MH_ALIGN(m, len) \
|
607 |
do { \
|
608 |
(m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); \ |
609 |
} while (/* CONSTCOND */ 0) |
610 |
|
611 |
/*
|
612 |
* Determine if an mbuf's data area is read-only. This is true
|
613 |
* if external storage is read-only mapped, or not marked as R/W,
|
614 |
* or referenced by more than one mbuf.
|
615 |
*/
|
616 |
#define M_READONLY(m) \
|
617 |
(((m)->m_flags & M_EXT) != 0 && \
|
618 |
(((m)->m_flags & (M_EXT_ROMAP|M_EXT_RW)) != M_EXT_RW || \ |
619 |
(m)->m_ext.ext_refcnt > 1))
|
620 |
|
621 |
#define M_UNWRITABLE(__m, __len) \
|
622 |
((__m)->m_len < (__len) || M_READONLY((__m))) |
623 |
/*
|
624 |
* Determine if an mbuf's data area is read-only at the MMU.
|
625 |
*/
|
626 |
#define M_ROMAP(m) \
|
627 |
(((m)->m_flags & (M_EXT|M_EXT_ROMAP)) == (M_EXT|M_EXT_ROMAP)) |
628 |
|
629 |
/*
|
630 |
* Compute the amount of space available
|
631 |
* before the current start of data in an mbuf.
|
632 |
*/
|
633 |
#define _M_LEADINGSPACE(m) \
|
634 |
((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf : \ |
635 |
(m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \ |
636 |
(m)->m_data - (m)->m_dat) |
637 |
|
638 |
#define M_LEADINGSPACE(m) \
|
639 |
(M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m)))
|
640 |
|
641 |
/*
|
642 |
* Compute the amount of space available
|
643 |
* after the end of data in an mbuf.
|
644 |
*/
|
645 |
#define _M_TRAILINGSPACE(m) \
|
646 |
((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \ |
647 |
((m)->m_data + (m)->m_len) : \ |
648 |
&(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len)) |
649 |
|
650 |
#define M_TRAILINGSPACE(m) \
|
651 |
(M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m)))
|
652 |
|
653 |
/*
|
654 |
* Compute the address of an mbuf's data area.
|
655 |
*/
|
656 |
#define M_BUFADDR(m) \
|
657 |
(((m)->m_flags & M_PKTHDR) ? (m)->m_pktdat : (m)->m_dat) |
658 |
|
659 |
/*
|
660 |
* Compute the offset of the beginning of the data buffer of a non-ext
|
661 |
* mbuf.
|
662 |
*/
|
663 |
#define M_BUFOFFSET(m) \
|
664 |
(((m)->m_flags & M_PKTHDR) ? \ |
665 |
offsetof(struct mbuf, m_pktdat) : offsetof(struct mbuf, m_dat)) |
666 |
|
667 |
/*
|
668 |
* Arrange to prepend space of size plen to mbuf m.
|
669 |
* If a new mbuf must be allocated, how specifies whether to wait.
|
670 |
* If how is M_DONTWAIT and allocation fails, the original mbuf chain
|
671 |
* is freed and m is set to NULL.
|
672 |
*/
|
673 |
#define M_PREPEND(m, plen, how) \
|
674 |
do { \
|
675 |
if (M_LEADINGSPACE(m) >= (plen)) { \
|
676 |
(m)->m_data -= (plen); \ |
677 |
(m)->m_len += (plen); \ |
678 |
} else \
|
679 |
(m) = m_prepend((m), (plen), (how)); \ |
680 |
if ((m) && (m)->m_flags & M_PKTHDR) \
|
681 |
(m)->m_pkthdr.len += (plen); \ |
682 |
} while (/* CONSTCOND */ 0) |
683 |
|
684 |
/* change mbuf to new type */
|
685 |
#define MCHTYPE(m, t) \
|
686 |
do { \
|
687 |
KASSERT((t) != MT_FREE); \ |
688 |
mbstat_type_add((m)->m_type, -1); \
|
689 |
mbstat_type_add(t, 1); \
|
690 |
(m)->m_type = t; \ |
691 |
} while (/* CONSTCOND */ 0) |
692 |
|
693 |
/* length to m_copy to copy all */
|
694 |
#define M_COPYALL -1 |
695 |
|
696 |
/* compatibility with 4.3 */
|
697 |
#define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
|
698 |
|
699 |
/*
|
700 |
* Allow drivers and/or protocols to use the rcvif member of
|
701 |
* PKTHDR mbufs to store private context information.
|
702 |
*/
|
703 |
#define M_GETCTX(m, t) ((t)(m)->m_pkthdr.rcvif)
|
704 |
#define M_SETCTX(m, c) ((void)((m)->m_pkthdr.rcvif = (void *)(c))) |
705 |
|
706 |
#endif /* defined(_KERNEL) */ |
707 |
|
708 |
/*
|
709 |
* Simple mbuf queueing system
|
710 |
*
|
711 |
* this is basically a SIMPLEQ adapted to mbuf use (ie using
|
712 |
* m_nextpkt instead of field.sqe_next).
|
713 |
*
|
714 |
* m_next is ignored, so queueing chains of mbufs is possible
|
715 |
*/
|
716 |
#define MBUFQ_HEAD(name) \
|
717 |
struct name { \
|
718 |
struct mbuf *mq_first; \
|
719 |
struct mbuf **mq_last; \
|
720 |
} |
721 |
|
722 |
#define MBUFQ_INIT(q) do { \ |
723 |
(q)->mq_first = NULL; \
|
724 |
(q)->mq_last = &(q)->mq_first; \ |
725 |
} while (/*CONSTCOND*/0) |
726 |
|
727 |
#define MBUFQ_ENQUEUE(q, m) do { \ |
728 |
(m)->m_nextpkt = NULL; \
|
729 |
*(q)->mq_last = (m); \ |
730 |
(q)->mq_last = &(m)->m_nextpkt; \ |
731 |
} while (/*CONSTCOND*/0) |
732 |
|
733 |
#define MBUFQ_PREPEND(q, m) do { \ |
734 |
if (((m)->m_nextpkt = (q)->mq_first) == NULL) \ |
735 |
(q)->mq_last = &(m)->m_nextpkt; \ |
736 |
(q)->mq_first = (m); \ |
737 |
} while (/*CONSTCOND*/0) |
738 |
|
739 |
#define MBUFQ_DEQUEUE(q, m) do { \ |
740 |
if (((m) = (q)->mq_first) != NULL) { \ |
741 |
if (((q)->mq_first = (m)->m_nextpkt) == NULL) \ |
742 |
(q)->mq_last = &(q)->mq_first; \ |
743 |
else \
|
744 |
(m)->m_nextpkt = NULL; \
|
745 |
} \ |
746 |
} while (/*CONSTCOND*/0) |
747 |
|
748 |
#define MBUFQ_DRAIN(q) do { \ |
749 |
struct mbuf *__m0; \
|
750 |
while ((__m0 = (q)->mq_first) != NULL) { \ |
751 |
(q)->mq_first = __m0->m_nextpkt; \ |
752 |
m_freem(__m0); \ |
753 |
} \ |
754 |
(q)->mq_last = &(q)->mq_first; \ |
755 |
} while (/*CONSTCOND*/0) |
756 |
|
757 |
#define MBUFQ_FIRST(q) ((q)->mq_first)
|
758 |
#define MBUFQ_NEXT(m) ((m)->m_nextpkt)
|
759 |
#define MBUFQ_LAST(q) (*(q)->mq_last)
|
760 |
|
761 |
/*
|
762 |
* Mbuf statistics.
|
763 |
* For statistics related to mbuf and cluster allocations, see also the
|
764 |
* pool headers (mb_cache and mcl_cache).
|
765 |
*/
|
766 |
struct mbstat {
|
767 |
u_long _m_spare; /* formerly m_mbufs */
|
768 |
u_long _m_spare1; /* formerly m_clusters */
|
769 |
u_long _m_spare2; /* spare field */
|
770 |
u_long _m_spare3; /* formely m_clfree - free clusters */
|
771 |
u_long m_drops; /* times failed to find space */
|
772 |
u_long m_wait; /* times waited for space */
|
773 |
u_long m_drain; /* times drained protocols for space */
|
774 |
u_short m_mtypes[256]; /* type specific mbuf allocations */ |
775 |
}; |
776 |
|
777 |
struct mbstat_cpu {
|
778 |
u_int m_mtypes[256]; /* type specific mbuf allocations */ |
779 |
}; |
780 |
|
781 |
/*
|
782 |
* Mbuf sysctl variables.
|
783 |
*/
|
784 |
#define MBUF_MSIZE 1 /* int: mbuf base size */ |
785 |
#define MBUF_MCLBYTES 2 /* int: mbuf cluster size */ |
786 |
#define MBUF_NMBCLUSTERS 3 /* int: limit on the # of clusters */ |
787 |
#define MBUF_MBLOWAT 4 /* int: mbuf low water mark */ |
788 |
#define MBUF_MCLLOWAT 5 /* int: mbuf cluster low water mark */ |
789 |
#define MBUF_STATS 6 /* struct: mbstat */ |
790 |
#define MBUF_MOWNERS 7 /* struct: m_owner[] */ |
791 |
#define MBUF_MAXID 8 /* number of valid MBUF ids */ |
792 |
|
793 |
#define CTL_MBUF_NAMES { \
|
794 |
{ 0, 0 }, \ |
795 |
{ "msize", CTLTYPE_INT }, \
|
796 |
{ "mclbytes", CTLTYPE_INT }, \
|
797 |
{ "nmbclusters", CTLTYPE_INT }, \
|
798 |
{ "mblowat", CTLTYPE_INT }, \
|
799 |
{ "mcllowat", CTLTYPE_INT }, \
|
800 |
{ 0 /* "stats" */, CTLTYPE_STRUCT }, \ |
801 |
{ 0 /* "mowners" */, CTLTYPE_STRUCT }, \ |
802 |
} |
803 |
|
804 |
#ifdef _KERNEL
|
805 |
extern struct mbstat mbstat; |
806 |
extern int nmbclusters; /* limit on the # of clusters */ |
807 |
extern int mblowat; /* mbuf low water mark */ |
808 |
extern int mcllowat; /* mbuf cluster low water mark */ |
809 |
extern int max_linkhdr; /* largest link-level header */ |
810 |
extern int max_protohdr; /* largest protocol header */ |
811 |
extern int max_hdr; /* largest link+protocol header */ |
812 |
extern int max_datalen; /* MHLEN - max_hdr */ |
813 |
extern const int msize; /* mbuf base size */ |
814 |
extern const int mclbytes; /* mbuf cluster size */ |
815 |
extern pool_cache_t mb_cache;
|
816 |
extern pool_cache_t mcl_cache;
|
817 |
#ifdef MBUFTRACE
|
818 |
LIST_HEAD(mownerhead, mowner); |
819 |
extern struct mownerhead mowners; |
820 |
extern struct mowner unknown_mowners[]; |
821 |
extern struct mowner revoked_mowner; |
822 |
#endif
|
823 |
|
824 |
MALLOC_DECLARE(M_MBUF); |
825 |
MALLOC_DECLARE(M_SONAME); |
826 |
|
827 |
struct mbuf *m_copym(struct mbuf *, int, int, int); |
828 |
struct mbuf *m_copypacket(struct mbuf *, int); |
829 |
struct mbuf *m_devget(char *, int, int, struct ifnet *, |
830 |
void (*copy)(const void *, void *, size_t)); |
831 |
struct mbuf *m_dup(struct mbuf *, int, int, int); |
832 |
struct mbuf *m_free(struct mbuf *); |
833 |
struct mbuf *m_get(int, int); |
834 |
struct mbuf *m_getclr(int, int); |
835 |
struct mbuf *m_gethdr(int, int); |
836 |
struct mbuf *m_prepend(struct mbuf *,int, int); |
837 |
struct mbuf *m_pulldown(struct mbuf *, int, int, int *); |
838 |
struct mbuf *m_pullup(struct mbuf *, int); |
839 |
struct mbuf *m_copyup(struct mbuf *, int, int); |
840 |
struct mbuf *m_split(struct mbuf *,int, int); |
841 |
struct mbuf *m_getptr(struct mbuf *, int, int *); |
842 |
void m_adj(struct mbuf *, int); |
843 |
struct mbuf *m_defrag(struct mbuf *, int); |
844 |
int m_apply(struct mbuf *, int, int, |
845 |
int (*)(void *, void *, unsigned int), void *); |
846 |
void m_cat(struct mbuf *,struct mbuf *); |
847 |
void m_clget(struct mbuf *, int); |
848 |
int m_mballoc(int, int); |
849 |
void m_copyback(struct mbuf *, int, int, const void *); |
850 |
struct mbuf *m_copyback_cow(struct mbuf *, int, int, const void *, int); |
851 |
int m_makewritable(struct mbuf **, int, int, int); |
852 |
struct mbuf *m_getcl(int, int, int); |
853 |
void m_copydata(struct mbuf *, int, int, void *); |
854 |
void m_freem(struct mbuf *); |
855 |
void m_reclaim(void *, int); |
856 |
void mbinit(void); |
857 |
void m_ext_free(struct mbuf *); |
858 |
char * m_mapin(struct mbuf *); |
859 |
void m_move_pkthdr(struct mbuf *, struct mbuf *); |
860 |
|
861 |
bool m_ensure_contig(struct mbuf **, int); |
862 |
struct mbuf *m_add(struct mbuf *, struct mbuf *); |
863 |
void m_align(struct mbuf *, int); |
864 |
int m_append(struct mbuf *, int, const void *); |
865 |
|
866 |
/* Inline routines. */
|
867 |
static __inline u_int m_length(const struct mbuf *) __unused; |
868 |
|
869 |
/* Statistics */
|
870 |
void mbstat_type_add(int, int); |
871 |
|
872 |
/* Packet tag routines */
|
873 |
struct m_tag *m_tag_get(int, int, int); |
874 |
void m_tag_free(struct m_tag *); |
875 |
void m_tag_prepend(struct mbuf *, struct m_tag *); |
876 |
void m_tag_unlink(struct mbuf *, struct m_tag *); |
877 |
void m_tag_delete(struct mbuf *, struct m_tag *); |
878 |
void m_tag_delete_chain(struct mbuf *, struct m_tag *); |
879 |
void m_tag_delete_nonpersistent(struct mbuf *); |
880 |
struct m_tag *m_tag_find(const struct mbuf *, int, struct m_tag *); |
881 |
struct m_tag *m_tag_copy(struct m_tag *); |
882 |
int m_tag_copy_chain(struct mbuf *, struct mbuf *); |
883 |
void m_tag_init(struct mbuf *); |
884 |
struct m_tag *m_tag_first(struct mbuf *); |
885 |
struct m_tag *m_tag_next(struct mbuf *, struct m_tag *); |
886 |
|
887 |
/* Packet tag types */
|
888 |
#define PACKET_TAG_NONE 0 /* Nothing */ |
889 |
#define PACKET_TAG_VLAN 1 /* VLAN ID */ |
890 |
#define PACKET_TAG_ENCAP 2 /* encapsulation data */ |
891 |
#define PACKET_TAG_ESP 3 /* ESP information */ |
892 |
#define PACKET_TAG_PF 11 /* packet filter */ |
893 |
#define PACKET_TAG_ALTQ_QID 12 /* ALTQ queue id */ |
894 |
|
895 |
#define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 16 |
896 |
#define PACKET_TAG_IPSEC_IN_DONE 17 |
897 |
#define PACKET_TAG_IPSEC_OUT_DONE 18 |
898 |
#define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 19 /* NIC IPsec crypto req'ed */ |
899 |
#define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO 20 /* NIC notifies IPsec */ |
900 |
#define PACKET_TAG_IPSEC_PENDING_TDB 21 /* Reminder to do IPsec */ |
901 |
|
902 |
#define PACKET_TAG_IPSEC_SOCKET 22 /* IPSEC socket ref */ |
903 |
#define PACKET_TAG_IPSEC_HISTORY 23 /* IPSEC history */ |
904 |
|
905 |
#define PACKET_TAG_IPSEC_NAT_T_PORTS 25 /* two uint16_t */ |
906 |
|
907 |
#define PACKET_TAG_INET6 26 /* IPv6 info */ |
908 |
|
909 |
#define PACKET_TAG_ECO_RETRYPARMS 27 /* Econet retry parameters */ |
910 |
|
911 |
#define PACKET_TAG_TUNNEL_INFO 28 /* tunnel identification and |
912 |
* protocol callback, for
|
913 |
* loop detection/recovery
|
914 |
*/
|
915 |
|
916 |
#define PACKET_TAG_MPLS 29 /* Indicate it's for MPLS */ |
917 |
|
918 |
/*
|
919 |
* Return the number of bytes in the mbuf chain, m.
|
920 |
*/
|
921 |
static __inline u_int
|
922 |
m_length(const struct mbuf *m) |
923 |
{ |
924 |
const struct mbuf *m0; |
925 |
u_int pktlen; |
926 |
|
927 |
if ((m->m_flags & M_PKTHDR) != 0) |
928 |
return m->m_pkthdr.len;
|
929 |
|
930 |
pktlen = 0;
|
931 |
for (m0 = m; m0 != NULL; m0 = m0->m_next) |
932 |
pktlen += m0->m_len; |
933 |
return pktlen;
|
934 |
} |
935 |
|
936 |
void m_print(const struct mbuf *, const char *, void (*)(const char *, ...) |
937 |
__printflike(1, 2)); |
938 |
|
939 |
#endif /* _KERNEL */ |
940 |
#endif /* !_SYS_MBUF_H_ */ |