1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #ifndef _SYS_MALLOC_H_
36 #include <sys/malloc.h>
37 #endif
38 #include <sys/pool.h>
39 #include <sys/queue.h>
40
41
42
43
44
45
46
47
48
49 #define MLEN (MSIZE - sizeof(struct m_hdr))
50 #define MHLEN (MLEN - sizeof(struct pkthdr))
51
52 #define MINCLSIZE (MHLEN + 1)
53 #define M_MAXCOMPRESS (MHLEN / 2)
54
55
56 struct m_tag {
57 SLIST_ENTRY(m_tag) m_tag_link;
58 u_int16_t m_tag_id;
59 u_int16_t m_tag_len;
60 };
61
62
63
64
65
66 #define mtod(m,t) ((t)((m)->m_data))
67
68
69 struct m_hdr {
70 struct mbuf *mh_next;
71 struct mbuf *mh_nextpkt;
72 caddr_t mh_data;
73 u_int mh_len;
74 short mh_type;
75 u_short mh_flags;
76 };
77
78
79 struct pkthdr_pf {
80 void *hdr;
81 u_int rtableid;
82 u_int32_t qid;
83 u_int16_t tag;
84 u_int8_t flags;
85 u_int8_t routed;
86 };
87
88
89 #define PF_TAG_GENERATED 0x01
90 #define PF_TAG_FRAGCACHE 0x02
91 #define PF_TAG_TRANSLATE_LOCALHOST 0x04
92
93
94 struct pkthdr {
95 struct ifnet *rcvif;
96 SLIST_HEAD(packet_tags, m_tag) tags;
97 int len;
98 int csum_flags;
99 struct pkthdr_pf pf;
100 };
101
102
103 struct m_ext {
104 caddr_t ext_buf;
105
106 void (*ext_free)(caddr_t, u_int, void *);
107 void *ext_arg;
108 u_int ext_size;
109 int ext_type;
110 struct mbuf *ext_nextref;
111 struct mbuf *ext_prevref;
112 #ifdef DEBUG
113 const char *ext_ofile;
114 const char *ext_nfile;
115 int ext_oline;
116 int ext_nline;
117 #endif
118 };
119
120 struct mbuf {
121 struct m_hdr m_hdr;
122 union {
123 struct {
124 struct pkthdr MH_pkthdr;
125 union {
126 struct m_ext MH_ext;
127 char MH_databuf[MHLEN];
128 } MH_dat;
129 } MH;
130 char M_databuf[MLEN];
131 } M_dat;
132 };
133 #define m_next m_hdr.mh_next
134 #define m_len m_hdr.mh_len
135 #define m_data m_hdr.mh_data
136 #define m_type m_hdr.mh_type
137 #define m_flags m_hdr.mh_flags
138 #define m_nextpkt m_hdr.mh_nextpkt
139 #define m_act m_nextpkt
140 #define m_pkthdr M_dat.MH.MH_pkthdr
141 #define m_ext M_dat.MH.MH_dat.MH_ext
142 #define m_pktdat M_dat.MH.MH_dat.MH_databuf
143 #define m_dat M_dat.M_databuf
144
145
146 #define M_EXT 0x0001
147 #define M_PKTHDR 0x0002
148 #define M_EOR 0x0004
149 #define M_CLUSTER 0x0008
150 #define M_PROTO1 0x0010
151
152
153 #define M_BCAST 0x0100
154 #define M_MCAST 0x0200
155 #define M_CONF 0x0400
156 #define M_AUTH 0x0800
157 #define M_AUTH_AH 0x2000
158 #define M_TUNNEL 0x1000
159 #define M_ANYCAST6 0x4000
160 #define M_LINK0 0x8000
161 #define M_LOOP 0x0040
162 #define M_FILDROP 0x0080
163
164
165 #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_PROTO1|M_BCAST|M_MCAST|M_CONF|\
166 M_AUTH|M_ANYCAST6|M_LOOP|M_TUNNEL|M_LINK0|M_FILDROP)
167
168
169 #define M_IPV4_CSUM_OUT 0x0001
170 #define M_TCPV4_CSUM_OUT 0x0002
171 #define M_UDPV4_CSUM_OUT 0x0004
172 #define M_IPV4_CSUM_IN_OK 0x0008
173 #define M_IPV4_CSUM_IN_BAD 0x0010
174 #define M_TCP_CSUM_IN_OK 0x0020
175 #define M_TCP_CSUM_IN_BAD 0x0040
176 #define M_UDP_CSUM_IN_OK 0x0080
177 #define M_UDP_CSUM_IN_BAD 0x0100
178
179
180 #define MT_FREE 0
181 #define MT_DATA 1
182 #define MT_HEADER 2
183 #define MT_SONAME 3
184 #define MT_SOOPTS 4
185 #define MT_FTABLE 5
186 #define MT_CONTROL 6
187 #define MT_OOBDATA 7
188
189
190 #define M_DONTWAIT M_NOWAIT
191 #define M_WAIT M_WAITOK
192
193
194
195
196
197
198
199
200 #define MBUFLOCK(code) do {\
201 int ms = splvm(); \
202 { code } \
203 splx(ms); \
204 } while( 0)
205
206
207
208
209
210
211
212
213
214
215
216 #define MGET(m, how, type) m = m_get((how), (type))
217
218 #define MGETHDR(m, how, type) m = m_gethdr((how), (type))
219
220
221
222
223
224
225 #ifdef DEBUG
226 #define MCLREFDEBUGN(m, file, line) do { \
227 (m)->m_ext.ext_nfile = (file); \
228 (m)->m_ext.ext_nline = (line); \
229 } while ( 0)
230 #define MCLREFDEBUGO(m, file, line) do { \
231 (m)->m_ext.ext_ofile = (file); \
232 (m)->m_ext.ext_oline = (line); \
233 } while ( 0)
234 #else
235 #define MCLREFDEBUGN(m, file, line)
236 #define MCLREFDEBUGO(m, file, line)
237 #endif
238
239 #define MCLBUFREF(p)
240 #define MCLISREFERENCED(m) ((m)->m_ext.ext_nextref != (m))
241 #define _MCLDEREFERENCE(m) do { \
242 (m)->m_ext.ext_nextref->m_ext.ext_prevref = \
243 (m)->m_ext.ext_prevref; \
244 (m)->m_ext.ext_prevref->m_ext.ext_nextref = \
245 (m)->m_ext.ext_nextref; \
246 } while ( 0)
247 #define _MCLADDREFERENCE(o, n) do { \
248 (n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER)); \
249 (n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref; \
250 (n)->m_ext.ext_prevref = (o); \
251 (o)->m_ext.ext_nextref = (n); \
252 (n)->m_ext.ext_nextref->m_ext.ext_prevref = (n); \
253 MCLREFDEBUGN((n), __FILE__, __LINE__); \
254 } while ( 0)
255 #define MCLINITREFERENCE(m) do { \
256 (m)->m_ext.ext_prevref = (m); \
257 (m)->m_ext.ext_nextref = (m); \
258 MCLREFDEBUGO((m), __FILE__, __LINE__); \
259 MCLREFDEBUGN((m), NULL, 0); \
260 } while ( 0)
261
262 #define MCLADDREFERENCE(o, n) MBUFLOCK(_MCLADDREFERENCE((o), (n));)
263
264
265
266
267
268
269
270
271
272
273
274
275
276 #define MEXTMALLOC(m, size, how) do { \
277 (m)->m_ext.ext_buf = \
278 (caddr_t)malloc((size), mbtypes[(m)->m_type], (how)); \
279 if ((m)->m_ext.ext_buf != NULL) { \
280 (m)->m_data = (m)->m_ext.ext_buf; \
281 (m)->m_flags |= M_EXT; \
282 (m)->m_flags &= ~M_CLUSTER; \
283 (m)->m_ext.ext_size = (size); \
284 (m)->m_ext.ext_free = NULL; \
285 (m)->m_ext.ext_arg = NULL; \
286 (m)->m_ext.ext_type = mbtypes[(m)->m_type]; \
287 MCLINITREFERENCE(m); \
288 } \
289 } while ( 0)
290
291 #define MEXTADD(m, buf, size, type, free, arg) do { \
292 (m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf); \
293 (m)->m_flags |= M_EXT; \
294 (m)->m_flags &= ~M_CLUSTER; \
295 (m)->m_ext.ext_size = (size); \
296 (m)->m_ext.ext_free = (free); \
297 (m)->m_ext.ext_arg = (arg); \
298 (m)->m_ext.ext_type = (type); \
299 MCLINITREFERENCE(m); \
300 } while ( 0)
301
302
303
304
305 #define MRESETDATA(m) \
306 do { \
307 if ((m)->m_flags & M_EXT) \
308 (m)->m_data = (m)->m_ext.ext_buf; \
309 else if ((m)->m_flags & M_PKTHDR) \
310 (m)->m_data = (m)->m_pktdat; \
311 else \
312 (m)->m_data = (m)->m_dat; \
313 } while ( 0)
314
315 #define MCLGET(m, how) m_clget(m, how)
316
317
318
319
320
321
322 #define MFREE(m, n) n = m_free((m))
323
324
325
326
327
328 #define M_MOVE_HDR(to, from) { \
329 (to)->m_pkthdr = (from)->m_pkthdr; \
330 (from)->m_flags &= ~M_PKTHDR; \
331 SLIST_INIT(&(from)->m_pkthdr.tags); \
332 }
333
334
335
336
337 #define M_DUP_HDR(to, from) { \
338 (to)->m_pkthdr = (from)->m_pkthdr; \
339 SLIST_INIT(&(to)->m_pkthdr.tags); \
340 m_tag_copy_chain((to), (from)); \
341 }
342
343
344
345
346
347 #define M_DUP_PKTHDR(to, from) { \
348 (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
349 M_DUP_HDR((to), (from)); \
350 (to)->m_data = (to)->m_pktdat; \
351 }
352
353
354
355
356
357 #define M_MOVE_PKTHDR(to, from) { \
358 (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
359 M_MOVE_HDR((to), (from)); \
360 (to)->m_data = (to)->m_pktdat; \
361 }
362
363
364
365
366
367 #define M_ALIGN(m, len) \
368 { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); }
369
370
371
372
373 #define MH_ALIGN(m, len) \
374 { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); }
375
376
377
378
379
380
381 #define M_READONLY(m) \
382 (((m)->m_flags & M_EXT) != 0 && \
383 (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m)))
384
385
386
387
388
389 #define _M_LEADINGSPACE(m) \
390 ((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf : \
391 (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
392 (m)->m_data - (m)->m_dat)
393
394 #define M_LEADINGSPACE(m) \
395 (M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m)))
396
397
398
399
400
401 #define _M_TRAILINGSPACE(m) \
402 ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
403 ((m)->m_data + (m)->m_len) : \
404 &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
405
406 #define M_TRAILINGSPACE(m) \
407 (M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m)))
408
409
410
411
412
413
414
415 #define M_PREPEND(m, plen, how) { \
416 if (M_LEADINGSPACE(m) >= (plen)) { \
417 (m)->m_data -= (plen); \
418 (m)->m_len += (plen); \
419 } else \
420 (m) = m_prepend((m), (plen), (how)); \
421 if ((m) && (m)->m_flags & M_PKTHDR) \
422 (m)->m_pkthdr.len += (plen); \
423 }
424
425
426 #define MCHTYPE(m, t) { \
427 MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;); \
428 (m)->m_type = t;\
429 }
430
431
432 #define M_COPYALL 1000000000
433
434
435 #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
436
437
438
439
440
441
442 struct mbstat {
443 u_long _m_spare;
444 u_long _m_spare1;
445 u_long _m_spare2;
446 u_long _m_spare3;
447 u_long m_drops;
448 u_long m_wait;
449 u_long m_drain;
450 u_short m_mtypes[256];
451 };
452
453 #ifdef _KERNEL
454 extern struct mbstat mbstat;
455 extern int nmbclust;
456 extern int mblowat;
457 extern int mcllowat;
458 extern int max_linkhdr;
459 extern int max_protohdr;
460 extern int max_hdr;
461 extern int max_datalen;
462 extern int mbtypes[];
463 extern struct pool mbpool;
464 extern struct pool mclpool;
465
466 void mbinit(void);
467 struct mbuf *m_copym2(struct mbuf *, int, int, int);
468 struct mbuf *m_copym(struct mbuf *, int, int, int);
469 struct mbuf *m_free(struct mbuf *);
470 struct mbuf *m_get(int, int);
471 struct mbuf *m_getclr(int, int);
472 struct mbuf *m_gethdr(int, int);
473 struct mbuf *m_prepend(struct mbuf *, int, int);
474 struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
475 struct mbuf *m_pullup(struct mbuf *, int);
476 struct mbuf *m_pullup2(struct mbuf *, int);
477 struct mbuf *m_split(struct mbuf *, int, int);
478 struct mbuf *m_inject(struct mbuf *, int, int, int);
479 struct mbuf *m_getptr(struct mbuf *, int, int *);
480 void m_clget(struct mbuf *, int);
481 void m_adj(struct mbuf *, int);
482 int m_clalloc(int, int);
483 void m_copyback(struct mbuf *, int, int, const void *);
484 void m_freem(struct mbuf *);
485 void m_reclaim(void *, int);
486 void m_copydata(struct mbuf *, int, int, caddr_t);
487 void m_cat(struct mbuf *, struct mbuf *);
488 struct mbuf *m_devget(char *, int, int, struct ifnet *,
489 void (*)(const void *, void *, size_t));
490 void m_zero(struct mbuf *);
491 int m_apply(struct mbuf *, int, int,
492 int (*)(caddr_t, caddr_t, unsigned int), caddr_t);
493
494
495 struct m_tag *m_tag_get(int, int, int);
496 void m_tag_prepend(struct mbuf *, struct m_tag *);
497 void m_tag_delete(struct mbuf *, struct m_tag *);
498 void m_tag_delete_chain(struct mbuf *);
499 struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
500 struct m_tag *m_tag_copy(struct m_tag *);
501 int m_tag_copy_chain(struct mbuf *, struct mbuf *);
502 void m_tag_init(struct mbuf *);
503 struct m_tag *m_tag_first(struct mbuf *);
504 struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
505
506
507 #define PACKET_TAG_NONE 0
508 #define PACKET_TAG_IPSEC_IN_DONE 1
509 #define PACKET_TAG_IPSEC_OUT_DONE 2
510 #define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 3
511 #define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 4
512 #define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO 5
513 #define PACKET_TAG_IPSEC_PENDING_TDB 6
514 #define PACKET_TAG_BRIDGE 7
515 #define PACKET_TAG_GIF 8
516 #define PACKET_TAG_GRE 9
517 #define PACKET_TAG_IN_PACKET_CHECKSUM 10
518 #define PACKET_TAG_DLT 17
519
520 #ifdef MBTYPES
521 int mbtypes[] = {
522 M_FREE,
523 M_MBUF,
524 M_MBUF,
525 M_MBUF,
526 M_SOOPTS,
527 M_FTABLE,
528 M_MBUF,
529 M_MBUF,
530 };
531 #endif
532 #endif