mbuf: revert part of b4e5a1079d852748f03f32aae87ecdda27a538d2
[dragonfly.git] / sys / sys / mbuf.h
CommitLineData
984263bc 1/*
02742ec6
JS
2 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
3 *
984263bc
MD
4 * Copyright (c) 1982, 1986, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 * @(#)mbuf.h 8.5 (Berkeley) 2/19/95
36 * $FreeBSD: src/sys/sys/mbuf.h,v 1.44.2.17 2003/04/15 06:15:02 silby Exp $
cf12ba3c 37 * $DragonFly: src/sys/sys/mbuf.h,v 1.54 2008/10/19 08:39:55 sephe Exp $
984263bc
MD
38 */
39
40#ifndef _SYS_MBUF_H_
41#define _SYS_MBUF_H_
42
03d6a592
MD
43#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
44
1bd40720
MD
45#ifndef _SYS_TYPES_H_
46#include <sys/types.h>
47#endif
48#ifndef _SYS_PARAM_H_
49#include <sys/param.h>
50#endif
51#ifndef _SYS_QUEUE_H_
984263bc 52#include <sys/queue.h>
1bd40720 53#endif
6aad077d
MD
54#ifndef _NET_NETISR_H_
55#include <net/netisr.h>
56#endif
be02a6a0
MD
57#ifndef _NET_ETHERNET_H_
58#include <net/ethernet.h>
59#endif
984263bc
MD
60
61/*
62 * Mbufs are of a single size, MSIZE (machine/param.h), which
63 * includes overhead. An mbuf may add a single "mbuf cluster" of size
64 * MCLBYTES (also in machine/param.h), which has no additional overhead
65 * and is used instead of the internal data area; this is done when
66 * at least MINCLSIZE of data must be stored.
67 */
68#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
69#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
70#define MINCLSIZE (MHLEN + 1) /* smallest amount to put in cluster */
71#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
72
73/*
74 * Macros for type conversion:
4bcae717
SZ
75 * mtod(m, t) -- Convert mbuf pointer to data pointer of correct type.
76 * mtodoff(m, t, off) -- Convert mbuf pointer at the specified offset to data
77 * pointer of correct type.
984263bc 78 */
c3c96e44
MD
79#define mtod(m, t) ((t)((m)->m_data))
80#define mtodoff(m, t, off) ((t)((m)->m_data + (off)))
984263bc
MD
81
82/*
83 * Header present at the beginning of every mbuf.
84 */
85struct m_hdr {
86 struct mbuf *mh_next; /* next buffer in chain */
87 struct mbuf *mh_nextpkt; /* next chain in queue/record */
88 caddr_t mh_data; /* location of data */
89 int mh_len; /* amount of data in this mbuf */
1514ff2e 90 int mh_flags; /* flags; see below */
984263bc 91 short mh_type; /* type of data in this mbuf */
1514ff2e 92 short mh_pad; /* padding */
78167773 93 /* XXX implicit 4 bytes padding on x86_64 */
1d9e900b
MD
94#ifdef MBUF_DEBUG
95 const char *mh_lastfunc;
96#endif
0ad8e15e
SZ
97 union {
98 struct netmsg_packet mhm_pkt; /* hardware->proto stack msg */
99 struct netmsg_pru_send mhm_snd; /* usrspace->proto stack msg */
858ae8d6 100 struct netmsg_inarp mhm_arp; /* proto stack<->route msg */
0ad8e15e 101 } mh_msgu;
984263bc 102};
0ad8e15e
SZ
103#define mh_netmsg mh_msgu.mhm_pkt
104#define mh_sndmsg mh_msgu.mhm_snd
858ae8d6 105#define mh_arpmsg mh_msgu.mhm_arp
984263bc 106
315a7da3
JL
107/* pf stuff */
108struct pkthdr_pf {
2889a684 109 void *hdr; /* saved hdr pos in mbuf, for ECN */
ed1f0be2 110 void *statekey; /* pf stackside statekey */
2889a684
SZ
111 u_int rtableid; /* alternate routing table id */
112 uint32_t qid; /* queue id */
113 uint16_t tag; /* tag id */
114 uint8_t flags;
115 uint8_t routed;
315a7da3
JL
116 uint32_t state_hash; /* identifies 'connections' */
117 uint8_t ecn_af; /* for altq_red */
118 uint8_t unused01;
119 uint8_t unused02;
120 uint8_t unused03;
78167773 121 /* XXX implicit 4 bytes padding on x86_64 */
315a7da3
JL
122};
123
ed1f0be2
JL
124/* pkthdr_pf.flags */
125#define PF_TAG_GENERATED 0x01
126#define PF_TAG_FRAGCACHE 0x02
127#define PF_TAG_TRANSLATE_LOCALHOST 0x04
128#define PF_TAG_DIVERTED 0x08
129#define PF_TAG_DIVERTED_PACKET 0x10
130#define PF_TAG_REROUTE 0x20
131
be02a6a0 132/*
984263bc
MD
133 * Packet tag structure (see below for details).
134 */
135struct m_tag {
136 SLIST_ENTRY(m_tag) m_tag_link; /* List of packet tags */
8344f18f
SZ
137 uint16_t m_tag_id; /* Tag ID */
138 uint16_t m_tag_len; /* Length of data */
139 uint32_t m_tag_cookie; /* ABI/Module ID */
984263bc
MD
140};
141
46ca7d86
MD
142SLIST_HEAD(packet_tags, m_tag);
143
984263bc
MD
144/*
145 * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
4d723e5a
JS
146 *
147 * Be careful: The fields have been carefully ordered to avoid hidden padding.
148 * Keep this in mind, when adding or removing fields!
984263bc
MD
149 */
150struct pkthdr {
151 struct ifnet *rcvif; /* rcv interface */
46ca7d86
MD
152 struct packet_tags tags; /* list of packet tags */
153
984263bc
MD
154 /* variables for ip and tcp reassembly */
155 void *header; /* pointer to packet header */
b4e5a107 156 int len; /* total packet length */
46ca7d86 157
984263bc
MD
158 /* variables for hardware checksum */
159 int csum_flags; /* flags regarding checksum */
160 int csum_data; /* data field used by csum routines */
7df36335
SZ
161 uint16_t csum_iphlen; /* IP header length */
162 /* valid if CSUM IP|UDP|TCP|TSO */
163 uint8_t csum_thlen; /* TCP/UDP header length */
164 /* valid if CSUM UDP|TCP|TSO */
165 uint8_t csum_lhlen; /* link header length */
46ca7d86 166
f0336d39 167 uint16_t tso_segsz; /* TSO segment size */
f415c5c2
SZ
168 uint16_t ether_vlantag; /* ethernet 802.1p+q vlan tag */
169
170 uint16_t hash; /* packet hash */
01d73edb
SZ
171 uint16_t unused1; /* reserved for route table id */
172 uint32_t unused2; /* reserved for codel timestamp */
173
174 uint16_t wlan_seqno; /* IEEE 802.11 seq no. */
b4e5a107
SZ
175 /*
176 * Valid if BRIDGE_MBUF_TAGGED is set in fw_flags, records
177 * the original ether source address (if compatible).
178 */
179 uint8_t ether_br_shost[ETHER_ADDR_LEN];
f415c5c2 180
4d723e5a 181 /* firewall flags */
b4e5a107 182 uint32_t fw_flags; /* flags for FW */
4d723e5a 183
02742ec6 184 /* variables for PF processing */
315a7da3 185 struct pkthdr_pf pf; /* structure for PF */
984263bc
MD
186};
187
188/*
189 * Description of external storage mapped into mbuf; valid only if M_EXT is set.
190 */
191struct m_ext {
192 caddr_t ext_buf; /* start of buffer */
b542cd49
JS
193 void (*ext_free)(void *);
194 u_int ext_size; /* size of buffer, for ext_free */
195 void (*ext_ref)(void *);
7eccf245 196 void *ext_arg;
984263bc
MD
197};
198
199/*
200 * The core of the mbuf object along with some shortcut defines for
201 * practical purposes.
202 */
203struct mbuf {
204 struct m_hdr m_hdr;
205 union {
206 struct {
207 struct pkthdr MH_pkthdr; /* M_PKTHDR set */
208 union {
209 struct m_ext MH_ext; /* M_EXT set */
210 char MH_databuf[MHLEN];
211 } MH_dat;
212 } MH;
213 char M_databuf[MLEN]; /* !M_PKTHDR, !M_EXT */
214 } M_dat;
215};
216#define m_next m_hdr.mh_next
217#define m_len m_hdr.mh_len
218#define m_data m_hdr.mh_data
219#define m_type m_hdr.mh_type
220#define m_flags m_hdr.mh_flags
221#define m_nextpkt m_hdr.mh_nextpkt
984263bc
MD
222#define m_pkthdr M_dat.MH.MH_pkthdr
223#define m_ext M_dat.MH.MH_dat.MH_ext
224#define m_pktdat M_dat.MH.MH_dat.MH_databuf
225#define m_dat M_dat.M_databuf
226
227/*
9a275e74
HP
228 * Code that uses m_act should be converted to use m_nextpkt
229 * instead; m_act is historical and deprecated.
230 */
231#define m_act m_nextpkt
232
233/*
984263bc
MD
234 * mbuf flags.
235 */
236#define M_EXT 0x0001 /* has associated external storage */
237#define M_PKTHDR 0x0002 /* start of record */
238#define M_EOR 0x0004 /* end of record */
239#define M_PROTO1 0x0008 /* protocol-specific */
240#define M_PROTO2 0x0010 /* protocol-specific */
241#define M_PROTO3 0x0020 /* protocol-specific */
242#define M_PROTO4 0x0040 /* protocol-specific */
243#define M_PROTO5 0x0080 /* protocol-specific */
244
245/*
246 * mbuf pkthdr flags (also stored in m_flags).
247 */
248#define M_BCAST 0x0100 /* send/received as link-level broadcast */
249#define M_MCAST 0x0200 /* send/received as link-level multicast */
250#define M_FRAG 0x0400 /* packet is a fragment of a larger packet */
251#define M_FIRSTFRAG 0x0800 /* packet is first fragment */
252#define M_LASTFRAG 0x1000 /* packet is last fragment */
77e294a1 253#define M_CLCACHE 0x2000 /* mbuf allocated from the cluster cache */
90775e29 254#define M_EXT_CLUSTER 0x4000 /* standard cluster else special */
77e294a1 255#define M_PHCACHE 0x8000 /* mbuf allocated from the pkt header cache */
78812139 256#define M_NOTIFICATION 0x10000 /* notification event */
83790f85 257#define M_VLANTAG 0x20000 /* ether_vlantag is valid */
cb8d752c 258#define M_MPLSLABELED 0x40000 /* packet is mpls labeled */
8697599b 259#define M_LENCHECKED 0x80000 /* packet proto lengths are checked */
6afb09f8 260#define M_HASH 0x100000/* hash field in pkthdr is valid */
9908bc55
RP
261#define M_PROTO6 0x200000/* protocol-specific */
262#define M_PROTO7 0x400000/* protocol-specific */
263#define M_PROTO8 0x800000/* protocol-specific */
234d1daa 264#define M_CKHASH 0x1000000/* hash needs software verification */
4cc8caef 265#define M_PRIO 0x2000000/* high priority mbuf */
984263bc
MD
266
267/*
268 * Flags copied when copying m_pkthdr.
269 */
ee42237d 270#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_PROTO1|M_PROTO2|M_PROTO3 | \
9908bc55
RP
271 M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8 | \
272 M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG | \
273 M_VLANTAG|M_MPLSLABELED | \
4cc8caef 274 M_LENCHECKED|M_HASH|M_CKHASH|M_PRIO)
984263bc
MD
275
276/*
277 * Flags indicating hw checksum support and sw checksum requirements.
278 */
279#define CSUM_IP 0x0001 /* will csum IP */
280#define CSUM_TCP 0x0002 /* will csum TCP */
281#define CSUM_UDP 0x0004 /* will csum UDP */
282#define CSUM_IP_FRAGS 0x0008 /* will csum IP fragments */
283#define CSUM_FRAGMENT 0x0010 /* will do IP fragmentation */
284
285#define CSUM_IP_CHECKED 0x0100 /* did csum IP */
286#define CSUM_IP_VALID 0x0200 /* ... the csum is valid */
287#define CSUM_DATA_VALID 0x0400 /* csum_data field is valid */
288#define CSUM_PSEUDO_HDR 0x0800 /* csum_data has pseudo hdr */
fbb35ef0
SZ
289#define CSUM_FRAG_NOT_CHECKED 0x1000 /* did _not_ csum fragment
290 * NB: This flag is only used
291 * by IP defragmenter.
292 */
5f60906c 293#define CSUM_TSO 0x2000 /* will do TCP segmentation */
984263bc
MD
294
295#define CSUM_DELAY_DATA (CSUM_TCP | CSUM_UDP)
296#define CSUM_DELAY_IP (CSUM_IP) /* XXX add ipv6 here too? */
297
298/*
02742ec6
JS
299 * Flags indicating PF processing status
300 */
f2c2ec09 301#define FW_MBUF_GENERATED 0x00000001
315a7da3 302#define PF_MBUF_STRUCTURE 0x00000002 /* m_pkthdr.pf valid */
02742ec6 303#define PF_MBUF_ROUTED 0x00000004 /* pf_routed field is valid */
9c5896a0 304#define PF_MBUF_TAGGED 0x00000008
315a7da3 305#define XX_MBUF_UNUSED10 0x00000010
70224baa 306#define XX_MBUF_UNUSED20 0x00000020
5de23090 307#define IPFORWARD_MBUF_TAGGED 0x00000040
84a3e25a 308#define DUMMYNET_MBUF_TAGGED 0x00000080
be02a6a0 309#define BRIDGE_MBUF_TAGGED 0x00000100
012d335d 310#define FW_MBUF_REDISPATCH 0x00000200
5de23090 311#define IPFW_MBUF_GENERATED FW_MBUF_GENERATED
70224baa 312/*
984263bc
MD
313 * mbuf types.
314 */
315#define MT_FREE 0 /* should be on free list */
316#define MT_DATA 1 /* dynamic (data) allocation */
317#define MT_HEADER 2 /* packet header */
60ed1291 318#define MT_SONAME 3 /* socket name */
5de23090 319/* 4 was MT_TAG */
60ed1291
JS
320#define MT_CONTROL 5 /* extra-data protocol message */
321#define MT_OOBDATA 6 /* expedited data */
322#define MT_NTYPES 7 /* number of mbuf types for mbtypes[] */
984263bc
MD
323
324/*
325 * General mbuf allocator statistics structure.
7a82f541
SZ
326 *
327 * NOTE: Make sure this struct's size is multiple cache line size.
984263bc
MD
328 */
329struct mbstat {
330 u_long m_mbufs; /* mbufs obtained from page pool */
331 u_long m_clusters; /* clusters obtained from page pool */
332 u_long m_spare; /* spare field */
333 u_long m_clfree; /* free clusters */
334 u_long m_drops; /* times failed to find space */
335 u_long m_wait; /* times waited for space */
336 u_long m_drain; /* times drained protocols for space */
337 u_long m_mcfail; /* times m_copym failed */
338 u_long m_mpfail; /* times m_pullup failed */
339 u_long m_msize; /* length of an mbuf */
340 u_long m_mclbytes; /* length of an mbuf cluster */
94eaee9a 341 u_long m_mjumpagesize; /* length of a jumbo mbuf cluster */
984263bc
MD
342 u_long m_minclsize; /* min length of data to allocate a cluster */
343 u_long m_mlen; /* length of data in an mbuf */
344 u_long m_mhlen; /* length of data in a header mbuf */
7a82f541 345 u_long m_pad; /* pad to cache line size (64B) */
984263bc
MD
346};
347
348/*
349 * Flags specifying how an allocation should be made.
350 */
351
74f1caca
EN
352#define MB_DONTWAIT 0x4
353#define MB_TRYWAIT 0x8
354#define MB_WAIT MB_TRYWAIT
97482992
HP
355
356/*
357 * Mbuf to Malloc Flag Conversion.
358 */
74f1caca 359#define MBTOM(how) ((how) & MB_TRYWAIT ? M_WAITOK : M_NOWAIT)
984263bc 360
984263bc
MD
361/*
362 * These are identifying numbers passed to the m_mballoc_wait function,
363 * allowing us to determine whether the call came from an MGETHDR or
364 * an MGET.
365 */
366#define MGETHDR_C 1
367#define MGET_C 2
368
369/*
12496bdf 370 * mbuf allocation/deallocation macros (YYY deprecated, too big):
984263bc
MD
371 *
372 * MGET(struct mbuf *m, int how, int type)
373 * allocates an mbuf and initializes it to contain internal data.
374 *
375 * MGETHDR(struct mbuf *m, int how, int type)
376 * allocates an mbuf and initializes it to contain a packet header
377 * and internal data.
378 */
379#define MGET(m, how, type) do { \
12496bdf 380 (m) = m_get((how), (type)); \
984263bc
MD
381} while (0)
382
383#define MGETHDR(m, how, type) do { \
12496bdf 384 (m) = m_gethdr((how), (type)); \
984263bc
MD
385} while (0)
386
387/*
90775e29
MD
388 * MCLGET adds such clusters to a normal mbuf. The flag M_EXT is set upon
389 * success.
50503f0f 390 * Deprecated. Use m_getcl() or m_getl() instead.
984263bc 391 */
b6650ec0
MD
392#define MCLGET(m, how) do { \
393 m_mclget((m), (how)); \
984263bc
MD
394} while (0)
395
984263bc
MD
396/*
397 * NB: M_COPY_PKTHDR is deprecated; use either M_MOVE_PKTHDR
398 * or m_dup_pkthdr.
399 */
400/*
401 * Move mbuf pkthdr from "from" to "to".
402 * from should have M_PKTHDR set, and to must be empty.
403 * from no longer has a pkthdr after this operation.
404 */
405#define M_MOVE_PKTHDR(_to, _from) m_move_pkthdr((_to), (_from))
406
407/*
408 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
409 * an object of the specified size at the end of the mbuf, longword aligned.
410 */
411#define M_ALIGN(m, len) do { \
412 (m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1); \
413} while (0)
414
415/*
416 * As above, for mbufs allocated with m_gethdr/MGETHDR
417 * or initialized by M_COPY_PKTHDR.
418 */
419#define MH_ALIGN(m, len) do { \
420 (m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1); \
421} while (0)
422
423/*
424 * Check if we can write to an mbuf.
425 */
90775e29
MD
426#define M_EXT_WRITABLE(m) (m_sharecount(m) == 1)
427#define M_WRITABLE(m) (!((m)->m_flags & M_EXT) || M_EXT_WRITABLE(m))
984263bc
MD
428
429/*
84633371
JS
430 * Check if the supplied mbuf has a packet header, or else panic.
431 */
432#define M_ASSERTPKTHDR(m) \
433 KASSERT(m != NULL && m->m_flags & M_PKTHDR, \
434 ("%s: invalid mbuf or no mbuf packet header!", __func__))
435
436/*
7b6f875f
JH
437 * Compute the amount of space available before the current start of data.
438 * The M_EXT_WRITABLE() is a temporary, conservative safety measure: the burden
984263bc
MD
439 * of checking writability of the mbuf data area rests solely with the caller.
440 */
441#define M_LEADINGSPACE(m) \
442 ((m)->m_flags & M_EXT ? \
443 (M_EXT_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0): \
444 (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
445 (m)->m_data - (m)->m_dat)
446
447/*
7b6f875f 448 * Compute the amount of space available after the end of data in an mbuf.
984263bc
MD
449 * The M_WRITABLE() is a temporary, conservative safety measure: the burden
450 * of checking writability of the mbuf data area rests solely with the caller.
451 */
452#define M_TRAILINGSPACE(m) \
453 ((m)->m_flags & M_EXT ? \
454 (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \
455 - ((m)->m_data + (m)->m_len) : 0) : \
456 &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
457
458/*
459 * Arrange to prepend space of size plen to mbuf m.
460 * If a new mbuf must be allocated, how specifies whether to wait.
74f1caca 461 * If how is MB_DONTWAIT and allocation fails, the original mbuf chain
984263bc
MD
462 * is freed and m is set to NULL.
463 */
464#define M_PREPEND(m, plen, how) do { \
465 struct mbuf **_mmp = &(m); \
466 struct mbuf *_mm = *_mmp; \
467 int _mplen = (plen); \
468 int __mhow = (how); \
469 \
470 if (M_LEADINGSPACE(_mm) >= _mplen) { \
471 _mm->m_data -= _mplen; \
472 _mm->m_len += _mplen; \
473 } else \
474 _mm = m_prepend(_mm, _mplen, __mhow); \
2d23a8be 475 if (_mm != NULL && (_mm->m_flags & M_PKTHDR)) \
984263bc
MD
476 _mm->m_pkthdr.len += _mplen; \
477 *_mmp = _mm; \
478} while (0)
479
984263bc
MD
480/* Length to m_copy to copy all. */
481#define M_COPYALL 1000000000
482
483/* Compatibility with 4.3 */
74f1caca 484#define m_copy(m, o, l) m_copym((m), (o), (l), MB_DONTWAIT)
984263bc
MD
485
486#ifdef _KERNEL
487extern u_int m_clalloc_wid; /* mbuf cluster wait count */
488extern u_int m_mballoc_wid; /* mbuf wait count */
489extern int max_linkhdr; /* largest link-level header */
490extern int max_protohdr; /* largest protocol header */
491extern int max_hdr; /* largest link+protocol header */
492extern int max_datalen; /* MHLEN - max_hdr */
984263bc 493extern int mbuf_wait; /* mbuf sleep time */
984263bc
MD
494extern int nmbclusters;
495extern int nmbufs;
984263bc 496
0c33f36d
JH
497struct uio;
498
984263bc 499void m_adj(struct mbuf *, int);
b40798b4 500void m_align(struct mbuf *, int);
920c9f10
AH
501int m_apply(struct mbuf *, int, int,
502 int (*)(void *, void *, u_int), void *);
bf2cc98c 503int m_append(struct mbuf *, int, c_caddr_t);
984263bc 504void m_cat(struct mbuf *, struct mbuf *);
df80f2ea 505u_int m_countm(struct mbuf *m, struct mbuf **lastm, u_int *mbcnt);
984263bc 506void m_copyback(struct mbuf *, int, int, caddr_t);
f15db79e
MD
507void m_copydata(const struct mbuf *, int, int, caddr_t);
508struct mbuf *m_copym(const struct mbuf *, int, int, int);
984263bc
MD
509struct mbuf *m_copypacket(struct mbuf *, int);
510struct mbuf *m_defrag(struct mbuf *, int);
c8f5127a 511struct mbuf *m_defrag_nofree(struct mbuf *, int);
984263bc 512struct mbuf *m_devget(char *, int, int, struct ifnet *,
50503f0f 513 void (*copy)(volatile const void *, volatile void *, size_t));
984263bc 514struct mbuf *m_dup(struct mbuf *, int);
3bf6fec3 515struct mbuf *m_dup_data(struct mbuf *, int);
f15db79e 516int m_dup_pkthdr(struct mbuf *, const struct mbuf *, int);
7c85e8ac
SW
517void m_extadd(struct mbuf *, caddr_t, u_int, void (*)(void *),
518 void (*)(void *), void *);
1d9e900b
MD
519#ifdef MBUF_DEBUG
520struct mbuf *_m_free(struct mbuf *, const char *name);
521void _m_freem(struct mbuf *, const char *name);
522#else
984263bc
MD
523struct mbuf *m_free(struct mbuf *);
524void m_freem(struct mbuf *);
1d9e900b 525#endif
984263bc 526struct mbuf *m_get(int, int);
7b6f875f
JH
527struct mbuf *m_getc(int len, int how, int type);
528struct mbuf *m_getcl(int how, short type, int flags);
1a228695 529struct mbuf *m_getjcl(int how, short type, int flags, size_t size);
984263bc
MD
530struct mbuf *m_getclr(int, int);
531struct mbuf *m_gethdr(int, int);
532struct mbuf *m_getm(struct mbuf *, int, int, int);
920c9f10 533struct mbuf *m_getptr(struct mbuf *, int, int *);
50503f0f 534struct mbuf *m_last(struct mbuf *m);
df80f2ea 535u_int m_lengthm(struct mbuf *m, struct mbuf **lastm);
984263bc
MD
536void m_move_pkthdr(struct mbuf *, struct mbuf *);
537struct mbuf *m_prepend(struct mbuf *, int, int);
538void m_print(const struct mbuf *m);
539struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
540struct mbuf *m_pullup(struct mbuf *, int);
984263bc 541struct mbuf *m_split(struct mbuf *, int, int);
e12241e1 542struct mbuf *m_uiomove(struct uio *);
0909f798 543struct mbuf *m_unshare(struct mbuf *, int);
b6650ec0 544void m_mclget(struct mbuf *m, int how);
90775e29
MD
545int m_sharecount(struct mbuf *m);
546void m_chtype(struct mbuf *m, int type);
cf12ba3c 547int m_devpad(struct mbuf *m, int padto);
90775e29 548
e9fa4b60 549#ifdef MBUF_DEBUG
1d9e900b 550
e9fa4b60 551void mbuftrackid(struct mbuf *, int);
1d9e900b
MD
552
553#define m_free(m) _m_free(m, __func__)
554#define m_freem(m) _m_freem(m, __func__)
555
e9fa4b60 556#else
1d9e900b 557
e9fa4b60 558#define mbuftrackid(m, id) /* empty */
1d9e900b 559
e9fa4b60
MD
560#endif
561
50503f0f
JH
562/*
563 * Allocate the right type of mbuf for the desired total length.
42947373
JH
564 * The mbuf returned does not necessarily cover the entire requested length.
565 * This function follows mbuf chaining policy of allowing MINCLSIZE
566 * amount of chained mbufs.
50503f0f
JH
567 */
568static __inline struct mbuf *
569m_getl(int len, int how, int type, int flags, int *psize)
570{
571 struct mbuf *m;
572 int size;
573
574 if (len >= MINCLSIZE) {
575 m = m_getcl(how, type, flags);
576 size = MCLBYTES;
577 } else if (flags & M_PKTHDR) {
578 m = m_gethdr(how, type);
579 size = MHLEN;
580 } else {
581 m = m_get(how, type);
582 size = MLEN;
583 }
584 if (psize != NULL)
585 *psize = size;
586 return (m);
587}
984263bc
MD
588
589/*
42947373
JH
590 * Get a single mbuf that covers the requested number of bytes.
591 * This function does not create mbuf chains. It explicitly marks
592 * places in the code that abuse mbufs for contiguous data buffers.
593 */
594static __inline struct mbuf *
595m_getb(int len, int how, int type, int flags)
596{
597 struct mbuf *m;
598 int mbufsize = (flags & M_PKTHDR) ? MHLEN : MLEN;
599
600 if (len > mbufsize)
601 m = m_getcl(how, type, flags);
602 else if (flags & M_PKTHDR)
603 m = m_gethdr(how, type);
604 else
605 m = m_get(how, type);
606 return (m);
607}
608
609/*
984263bc
MD
610 * Packets may have annotations attached by affixing a list
611 * of "packet tags" to the pkthdr structure. Packet tags are
612 * dynamically allocated semi-opaque data structures that have
613 * a fixed header (struct m_tag) that specifies the size of the
614 * memory block and a <cookie,type> pair that identifies it.
615 * The cookie is a 32-bit unique unsigned value used to identify
616 * a module or ABI. By convention this value is chose as the
617 * date+time that the module is created, expressed as the number of
618 * seconds since the epoch (e.g. using date -u +'%s'). The type value
619 * is an ABI/module-specific value that identifies a particular annotation
620 * and is private to the module. For compatibility with systems
621 * like openbsd that define packet tags w/o an ABI/module cookie,
622 * the value PACKET_ABI_COMPAT is used to implement m_tag_get and
623 * m_tag_find compatibility shim functions and several tag types are
624 * defined below. Users that do not require compatibility should use
625 * a private cookie value so that packet tag-related definitions
626 * can be maintained privately.
627 *
4c7020ad
SZ
628 * Note that the packet tag returned by m_tag_alloc has the default
629 * memory alignment implemented by kmalloc. To reference private data
984263bc
MD
630 * one can use a construct like:
631 *
4c7020ad
SZ
632 * struct m_tag *mtag = m_tag_alloc(...);
633 * struct foo *p = m_tag_data(mtag);
984263bc
MD
634 *
635 * if the alignment of struct m_tag is sufficient for referencing members
636 * of struct foo. Otherwise it is necessary to embed struct m_tag within
637 * the private data structure to insure proper alignment; e.g.
638 *
639 * struct foo {
640 * struct m_tag tag;
641 * ...
642 * };
4c7020ad 643 * struct foo *p = (struct foo *)m_tag_alloc(...);
984263bc
MD
644 * struct m_tag *mtag = &p->tag;
645 */
646
647#define PACKET_TAG_NONE 0 /* Nadda */
648
649/* Packet tag for use with PACKET_ABI_COMPAT */
650#define PACKET_TAG_IPSEC_IN_DONE 1 /* IPsec applied, in */
821819dc 651/* struct tdb_indent */
984263bc 652#define PACKET_TAG_IPSEC_OUT_DONE 2 /* IPsec applied, out */
821819dc 653/* struct tdb_indent */
984263bc 654#define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 3 /* NIC IPsec crypto done */
821819dc 655/* struct tdb_indent, never added */
984263bc 656#define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 4 /* NIC IPsec crypto req'ed */
821819dc 657/* struct tdb_indent, never added */
ba3a125b 658#define PACKET_TAG_IPSEC_PENDING_TDB 5 /* Reminder to do IPsec */
821819dc 659/* struct tdb_indent, never added */
ba3a125b 660#define PACKET_TAG_ENCAP 6 /* Encap. processing */
821819dc 661/* struct ifnet *, the GIF interface */
ba3a125b 662#define PACKET_TAG_IPSEC_HISTORY 7 /* IPSEC history */
821819dc 663/* struct ipsec_history */
ba3a125b 664#define PACKET_TAG_IPV6_INPUT 8 /* IPV6 input processing */
821819dc 665/* struct ip6aux */
e5ecc832 666#define PACKET_TAG_IPFW_DIVERT 9 /* divert info */
68edaf54 667/* struct divert_info */
4c7020ad
SZ
668#define PACKET_TAG_DUMMYNET 15 /* dummynet info */
669/* struct dn_pkt */
984263bc 670#define PACKET_TAG_IPFORWARD 18 /* ipforward info */
5de23090 671/* struct sockaddr_in */
7e31206a
SZ
672#define PACKET_TAG_IPSRCRT 27 /* IP srcrt opts */
673/* struct ip_srcrt_opt */
5de23090 674#define PACKET_TAG_CARP 28 /* CARP info */
70224baa
JL
675/* struct pf_mtag */
676#define PACKET_TAG_PF 29 /* PF info */
984263bc 677
ed1f0be2
JL
678#define PACKET_TAG_PF_DIVERT 0x0200 /* pf(4) diverted packet */
679
680
984263bc 681/* Packet tag routines */
8344f18f 682struct m_tag *m_tag_alloc(uint32_t, int, int, int);
984263bc
MD
683void m_tag_free(struct m_tag *);
684void m_tag_prepend(struct mbuf *, struct m_tag *);
685void m_tag_unlink(struct mbuf *, struct m_tag *);
686void m_tag_delete(struct mbuf *, struct m_tag *);
7b6f875f 687void m_tag_delete_chain(struct mbuf *);
8344f18f 688struct m_tag *m_tag_locate(struct mbuf *, uint32_t, int, struct m_tag *);
984263bc 689struct m_tag *m_tag_copy(struct m_tag *, int);
f15db79e 690int m_tag_copy_chain(struct mbuf *, const struct mbuf *, int);
984263bc
MD
691void m_tag_init(struct mbuf *);
692struct m_tag *m_tag_first(struct mbuf *);
693struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
694
695/* these are for openbsd compatibility */
696#define MTAG_ABI_COMPAT 0 /* compatibility ABI */
697
d031aa80
MD
698static __inline void *
699m_tag_data(struct m_tag *tag)
700{
701 return ((void *)(tag + 1));
702}
703
984263bc
MD
704static __inline struct m_tag *
705m_tag_get(int type, int length, int wait)
706{
707 return m_tag_alloc(MTAG_ABI_COMPAT, type, length, wait);
708}
709
710static __inline struct m_tag *
711m_tag_find(struct mbuf *m, int type, struct m_tag *start)
712{
713 return m_tag_locate(m, MTAG_ABI_COMPAT, type, start);
714}
984263bc 715
03d6a592
MD
716#endif /* _KERNEL */
717
718#endif /* _KERNEL || _KERNEL_STRUCTURES */
719#endif /* !_SYS_MBUF_H_ */