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: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 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: #ifndef T2EX
76: #include <sys/queue.h>
77: #else
78: #include <sys/_queue.h>
79: #endif
80: #if defined(_KERNEL)
81: #include <sys/percpu_types.h>
82: #endif
83:
84:
85: #if defined(_KERNEL) || defined(_STANDALONE)
86: #include <sys/systm.h>
87: #else
88: #include <stddef.h>
89: #endif
90: #ifndef T2EX
91: #include <uvm/uvm_param.h>
92: #endif
93: 94: 95: 96: 97: 98: 99:
100:
101:
102: struct m_tag {
103: SLIST_ENTRY(m_tag) m_tag_link;
104: uint16_t m_tag_id;
105: uint16_t m_tag_len;
106: };
107:
108:
109: struct mowner {
110: char mo_name[16];
111: char mo_descr[16];
112: LIST_ENTRY(mowner) mo_link;
113: struct percpu *mo_counters;
114: };
115:
116: #define MOWNER_INIT(x, y) { .mo_name = x, .mo_descr = y }
117:
118: enum mowner_counter_index {
119: MOWNER_COUNTER_CLAIMS,
120: MOWNER_COUNTER_RELEASES,
121: MOWNER_COUNTER_CLUSTER_CLAIMS,
122: MOWNER_COUNTER_CLUSTER_RELEASES,
123: MOWNER_COUNTER_EXT_CLAIMS,
124: MOWNER_COUNTER_EXT_RELEASES,
125:
126: MOWNER_COUNTER_NCOUNTERS,
127: };
128:
129: #if defined(_KERNEL)
130: struct mowner_counter {
131: u_long mc_counter[MOWNER_COUNTER_NCOUNTERS];
132: };
133: #endif
134:
135:
136: struct mowner_user {
137: char mo_name[16];
138: char mo_descr[16];
139: LIST_ENTRY(mowner) mo_link;
140: u_long mo_counter[MOWNER_COUNTER_NCOUNTERS];
141: };
142:
143: 144: 145: 146:
147: #define mtod(m, t) ((t)((m)->m_data))
148:
149:
150: struct m_hdr {
151: struct mbuf *mh_next;
152: struct mbuf *mh_nextpkt;
153: char *mh_data;
154: struct mowner *mh_owner;
155: int mh_len;
156: int mh_flags;
157: paddr_t mh_paddr;
158: short mh_type;
159: };
160:
161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176:
177: struct pkthdr {
178: struct ifnet *rcvif;
179: SLIST_HEAD(packet_tags, m_tag) tags;
180: int len;
181: int csum_flags;
182: uint32_t csum_data;
183: u_int segsz;
184: };
185:
186: 187: 188: 189:
190: #define M_CSUM_TCPv4 0x00000001
191: #define M_CSUM_UDPv4 0x00000002
192: #define M_CSUM_TCP_UDP_BAD 0x00000004
193: #define M_CSUM_DATA 0x00000008
194: #define M_CSUM_TCPv6 0x00000010
195: #define M_CSUM_UDPv6 0x00000020
196: #define M_CSUM_IPv4 0x00000040
197: #define M_CSUM_IPv4_BAD 0x00000080
198: #define M_CSUM_TSOv4 0x00000100
199: #define M_CSUM_TSOv6 0x00000200
200:
201:
202: #define M_CSUM_NO_PSEUDOHDR 0x80000000 203: 204: 205:
206:
207: #define M_CSUM_BITS \
208: "\20\1TCPv4\2UDPv4\3TCP_UDP_BAD\4DATA\5TCPv6\6UDPv6\7IPv4\10IPv4_BAD" \
209: "\11TSOv4\12TSOv6\40NO_PSEUDOHDR"
210:
211: 212: 213: 214:
215: #define M_CSUM_DATA_IPv4_IPHL(x) ((x) >> 16)
216: #define M_CSUM_DATA_IPv4_OFFSET(x) ((x) & 0xffff)
217:
218: 219: 220: 221: 222: 223: 224: 225:
226:
227: #define M_CSUM_DATA_IPv6_HL(x) ((x) >> 16)
228: #define M_CSUM_DATA_IPv6_HL_SET(x, v) (x) = ((x) & 0xffff) | ((v) << 16)
229: #define M_CSUM_DATA_IPv6_OFFSET(x) ((x) & 0xffff)
230:
231: 232: 233: 234:
235: #ifdef MIN_PAGE_SIZE
236: #define M_EXT_MAXPAGES ((65536 / MIN_PAGE_SIZE) + 1)
237: #endif
238:
239:
240: struct _m_ext_storage {
241: unsigned int ext_refcnt;
242: int ext_flags;
243: char *ext_buf;
244: void (*ext_free)
245: (struct mbuf *, void *, size_t, void *);
246: void *ext_arg;
247: size_t ext_size;
248: #ifndef T2EX
249: struct malloc_type *ext_type;
250: #endif
251: union {
252: paddr_t extun_paddr;
253:
254: 255: 256: 257:
258: #ifdef M_EXT_MAXPAGES
259: struct vm_page *extun_pgs[M_EXT_MAXPAGES];
260: #endif
261: } ext_un;
262: #define ext_paddr ext_un.extun_paddr
263: #define ext_pgs ext_un.extun_pgs
264: #ifdef DEBUG
265: const char *ext_ofile;
266: const char *ext_nfile;
267: int ext_oline;
268: int ext_nline;
269: #endif
270: };
271:
272: struct _m_ext {
273: struct mbuf *ext_ref;
274: struct _m_ext_storage ext_storage;
275: };
276:
277: #define M_PADDR_INVALID POOL_PADDR_INVALID
278:
279: 280: 281: 282:
283: #define MBUF_DEFINE(name, mhlen, mlen) \
284: struct name { \
285: struct m_hdr m_hdr; \
286: union { \
287: struct { \
288: struct pkthdr MH_pkthdr; \
289: union { \
290: struct _m_ext MH_ext; \
291: char MH_databuf[(mhlen)]; \
292: } MH_dat; \
293: } MH; \
294: char M_databuf[(mlen)]; \
295: } M_dat; \
296: }
297: #define m_next m_hdr.mh_next
298: #define m_len m_hdr.mh_len
299: #define m_data m_hdr.mh_data
300: #define m_owner m_hdr.mh_owner
301: #define m_type m_hdr.mh_type
302: #define m_flags m_hdr.mh_flags
303: #define m_nextpkt m_hdr.mh_nextpkt
304: #define m_paddr m_hdr.mh_paddr
305: #define m_pkthdr M_dat.MH.MH_pkthdr
306: #define m_ext_storage M_dat.MH.MH_dat.MH_ext.ext_storage
307: #define m_ext_ref M_dat.MH.MH_dat.MH_ext.ext_ref
308: #define m_ext m_ext_ref->m_ext_storage
309: #define m_pktdat M_dat.MH.MH_dat.MH_databuf
310: #define m_dat M_dat.M_databuf
311:
312: 313: 314: 315:
316: MBUF_DEFINE(_mbuf_dummy, 1, 1);
317:
318:
319: #define MLEN (MSIZE - offsetof(struct _mbuf_dummy, m_dat))
320:
321: #define MHLEN (MSIZE - offsetof(struct _mbuf_dummy, m_pktdat))
322:
323: #define MINCLSIZE (MHLEN+MLEN+1)
324: #define M_MAXCOMPRESS (MHLEN / 2)
325:
326: 327: 328:
329: MBUF_DEFINE(mbuf, MHLEN, MLEN);
330:
331:
332: #define M_EXT 0x00001
333: #define M_PKTHDR 0x00002
334: #define M_EOR 0x00004
335: #define M_PROTO1 0x00008
336:
337:
338: #define M_AUTHIPHDR 0x00010
339: #define M_DECRYPTED 0x00020
340: #define M_LOOP 0x00040
341: #define M_AUTHIPDGM 0x00080
342: #define M_BCAST 0x00100
343: #define M_MCAST 0x00200
344: #define M_CANFASTFWD 0x00400 345:
346: #define M_ANYCAST6 0x00800
347: #define M_LINK0 0x01000
348: #define M_LINK1 0x02000
349: #define M_LINK2 0x04000
350: #define M_LINK3 0x08000
351: #define M_LINK4 0x10000
352: #define M_LINK5 0x20000
353: #define M_LINK6 0x40000
354: #define M_LINK7 0x80000
355:
356:
357: #define M_EXT_FLAGS 0xff000000
358: #define M_EXT_CLUSTER 0x01000000
359: #define M_EXT_PAGES 0x02000000
360: #define M_EXT_ROMAP 0x04000000
361: #define M_EXT_RW 0x08000000
362:
363:
364: #define M_CLUSTER M_EXT_CLUSTER
365:
366: #define M_FLAGS_BITS \
367: "\20\1EXT\2PKTHDR\3EOR\4PROTO1\5AUTHIPHDR\6DECRYPTED\7LOOP\10AUTHIPDGM" \
368: "\11BCAST\12MCAST\13CANFASTFWD\14ANYCAST6\15LINK0\16LINK1\17LINK2\20LINK3" \
369: "\21LINK4\22LINK5\23LINK6\24LINK7" \
370: "\31EXT_CLUSTER\32EXT_PAGES\33EXT_ROMAP\34EXT_RW"
371:
372:
373: #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)
374:
375:
376: #define M_EXTCOPYFLAGS (M_EXT|M_EXT_FLAGS)
377:
378:
379: #define MT_FREE 0
380: #define MT_DATA 1
381: #define MT_HEADER 2
382: #define MT_SONAME 3
383: #define MT_SOOPTS 4
384: #define MT_FTABLE 5
385: #define MT_CONTROL 6
386: #define MT_OOBDATA 7
387:
388:
389: #define M_DONTWAIT M_NOWAIT
390: #define M_WAIT M_WAITOK
391:
392: #ifdef MBUFTRACE
393: 394: 395:
396: void mowner_init(struct mbuf *, int);
397: void mowner_ref(struct mbuf *, int);
398: void m_claim(struct mbuf *, struct mowner *);
399: void mowner_revoke(struct mbuf *, bool, int);
400: #ifndef T2EX
401: void mowner_attach(struct mowner *);
402: #else
403: int mowner_attach(struct mowner *);
404: #endif
405: void mowner_detach(struct mowner *);
406: void m_claimm(struct mbuf *, struct mowner *);
407: #else
408: #define mowner_init(m, type) do { } while ( 0)
409: #define mowner_ref(m, flags) do { } while ( 0)
410: #define mowner_revoke(m, all, flags) do { } while ( 0)
411: #define m_claim(m, mowner) do { } while ( 0)
412: #ifndef T2EX
413: #define mowner_attach(mo) do { } while ( 0)
414: #else
415: #define mowner_attach(mo) 0
416: #endif
417: #define mowner_detach(mo) do { } while ( 0)
418: #define m_claimm(m, mo) do { } while ( 0)
419: #endif
420:
421: #define MCLAIM(m, mo) m_claim((m), (mo))
422: #define MOWNER_ATTACH(mo) mowner_attach(mo)
423: #define MOWNER_DETACH(mo) mowner_detach(mo)
424:
425: 426: 427: 428: 429: 430: 431: 432: 433: 434: 435: 436: 437:
438: #define MGET(m, how, type) m = m_get((how), (type))
439: #define MGETHDR(m, how, type) m = m_gethdr((how), (type))
440:
441: #if defined(_KERNEL)
442: #define _M_
443: 444: 445:
446: #ifdef DEBUG
447: #define MCLREFDEBUGN(m, file, line) \
448: do { \
449: (m)->m_ext.ext_nfile = (file); \
450: (m)->m_ext.ext_nline = (line); \
451: } while ( 0)
452:
453: #define MCLREFDEBUGO(m, file, line) \
454: do { \
455: (m)->m_ext.ext_ofile = (file); \
456: (m)->m_ext.ext_oline = (line); \
457: } while ( 0)
458: #else
459: #define MCLREFDEBUGN(m, file, line)
460: #define MCLREFDEBUGO(m, file, line)
461: #endif
462:
463: #define MCLINITREFERENCE(m) \
464: do { \
465: KDASSERT(((m)->m_flags & M_EXT) == 0); \
466: (m)->m_ext_ref = (m); \
467: (m)->m_ext.ext_refcnt = 1; \
468: MCLREFDEBUGO((m), __FILE__, __LINE__); \
469: MCLREFDEBUGN((m), NULL, 0); \
470: } while ( 0)
471:
472: 473: 474: 475: 476: 477: 478: 479: 480: 481: 482: 483:
484:
485: #define _MCLGET(m, pool_cache, size, how) \
486: do { \
487: (m)->m_ext_storage.ext_buf = \
488: pool_cache_get_paddr((pool_cache), \
489: (how) == M_WAIT ? (PR_WAITOK|PR_LIMITFAIL) : 0, \
490: &(m)->m_ext_storage.ext_paddr); \
491: if ((m)->m_ext_storage.ext_buf != NULL) { \
492: MCLINITREFERENCE(m); \
493: (m)->m_data = (m)->m_ext.ext_buf; \
494: (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | \
495: M_EXT|M_CLUSTER|M_EXT_RW; \
496: (m)->m_ext.ext_flags = 0; \
497: (m)->m_ext.ext_size = (size); \
498: (m)->m_ext.ext_free = NULL; \
499: (m)->m_ext.ext_arg = (pool_cache); \
500: \
501: mowner_ref((m), M_EXT|M_CLUSTER); \
502: } \
503: } while ( 0)
504:
505: 506: 507:
508: #define MCLGET(m, how) _MCLGET((m), mcl_cache, MCLBYTES, (how))
509:
510: #ifndef T2EX
511:
512: #define MEXTMALLOC(m, size, how) \
513: do { \
514: (m)->m_ext_storage.ext_buf = \
515: (void *)malloc((size), mbtypes[(m)->m_type], (how)); \
516: if ((m)->m_ext_storage.ext_buf != NULL) { \
517: MCLINITREFERENCE(m); \
518: (m)->m_data = (m)->m_ext.ext_buf; \
519: (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | \
520: M_EXT|M_EXT_RW; \
521: (m)->m_ext.ext_flags = 0; \
522: (m)->m_ext.ext_size = (size); \
523: (m)->m_ext.ext_free = NULL; \
524: (m)->m_ext.ext_arg = NULL; \
525: (m)->m_ext.ext_type = mbtypes[(m)->m_type]; \
526: mowner_ref((m), M_EXT); \
527: } \
528: } while ( 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 = (void *)(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 = (void (*)(struct mbuf *, void *, size_t, void *))(free); \
538: (m)->m_ext.ext_arg = (arg); \
539: (m)->m_ext.ext_type = (type); \
540: mowner_ref((m), M_EXT); \
541: } while ( 0)
542:
543: #else
544:
545: #define MEXTMALLOC(m, size, how) \
546: do { \
547: (m)->m_ext_storage.ext_buf = \
548: (void *)malloc((size), mbtypes[(m)->m_type], (how)); \
549: if ((m)->m_ext_storage.ext_buf != NULL) { \
550: MCLINITREFERENCE(m); \
551: (m)->m_data = (m)->m_ext.ext_buf; \
552: (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | \
553: M_EXT|M_EXT_RW; \
554: (m)->m_ext.ext_flags = 0; \
555: (m)->m_ext.ext_size = (size); \
556: (m)->m_ext.ext_free = NULL; \
557: (m)->m_ext.ext_arg = NULL; \
558: mowner_ref((m), M_EXT); \
559: } \
560: } while ( 0)
561:
562: #define MEXTADD(m, buf, size, type, free, arg) \
563: do { \
564: MCLINITREFERENCE(m); \
565: (m)->m_data = (m)->m_ext.ext_buf = (void *)(buf); \
566: (m)->m_flags = ((m)->m_flags & ~M_EXTCOPYFLAGS) | M_EXT; \
567: (m)->m_ext.ext_flags = 0; \
568: (m)->m_ext.ext_size = (size); \
569: (m)->m_ext.ext_free = (void (*)(struct mbuf *, void *, size_t, void *))(free); \
570: (m)->m_ext.ext_arg = (arg); \
571: mowner_ref((m), M_EXT); \
572: } while ( 0)
573:
574: #endif
575:
576: 577: 578:
579: #define MRESETDATA(m) \
580: do { \
581: if ((m)->m_flags & M_EXT) \
582: (m)->m_data = (m)->m_ext.ext_buf; \
583: else if ((m)->m_flags & M_PKTHDR) \
584: (m)->m_data = (m)->m_pktdat; \
585: else \
586: (m)->m_data = (m)->m_dat; \
587: } while ( 0)
588:
589: 590: 591: 592: 593:
594: #define MFREE(m, n) \
595: mowner_revoke((m), 1, (m)->m_flags); \
596: mbstat_type_add((m)->m_type, -1); \
597: if ((m)->m_flags & M_PKTHDR) \
598: m_tag_delete_chain((m), NULL); \
599: (n) = (m)->m_next; \
600: if ((m)->m_flags & M_EXT) { \
601: m_ext_free(m); \
602: } else { \
603: pool_cache_put(mb_cache, (m)); \
604: } \
605:
606: 607: 608: 609:
610: #define M_COPY_PKTHDR(to, from) \
611: do { \
612: (to)->m_pkthdr = (from)->m_pkthdr; \
613: (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
614: SLIST_INIT(&(to)->m_pkthdr.tags); \
615: m_tag_copy_chain((to), (from)); \
616: (to)->m_data = (to)->m_pktdat; \
617: } while ( 0)
618:
619: 620: 621: 622:
623: #define M_MOVE_PKTHDR(to, from) m_move_pkthdr(to, from)
624:
625: 626: 627: 628:
629: #define M_ALIGN(m, len) \
630: do { \
631: (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); \
632: } while ( 0)
633:
634: 635: 636: 637:
638: #define MH_ALIGN(m, len) \
639: do { \
640: (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); \
641: } while ( 0)
642:
643: 644: 645: 646: 647:
648: #define M_READONLY(m) \
649: (((m)->m_flags & M_EXT) != 0 && \
650: (((m)->m_flags & (M_EXT_ROMAP|M_EXT_RW)) != M_EXT_RW || \
651: (m)->m_ext.ext_refcnt > 1))
652:
653: #define M_UNWRITABLE(__m, __len) \
654: ((__m)->m_len < (__len) || M_READONLY((__m)))
655: 656: 657:
658: #define M_ROMAP(m) \
659: (((m)->m_flags & (M_EXT|M_EXT_ROMAP)) == (M_EXT|M_EXT_ROMAP))
660:
661: 662: 663: 664:
665: #define _M_LEADINGSPACE(m) \
666: (size_t)(((m)->m_flags & M_EXT ? (m)->m_data - (m)->m_ext.ext_buf : \
667: (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
668: (m)->m_data - (m)->m_dat))
669:
670: #define M_LEADINGSPACE(m) \
671: (M_READONLY((m)) ? 0 : _M_LEADINGSPACE((m)))
672:
673: 674: 675: 676:
677: #define _M_TRAILINGSPACE(m) \
678: ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
679: ((m)->m_data + (m)->m_len) : \
680: &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
681:
682: #define M_TRAILINGSPACE(m) \
683: (M_READONLY((m)) ? 0 : _M_TRAILINGSPACE((m)))
684:
685: 686: 687:
688: #define M_BUFADDR(m) \
689: (((m)->m_flags & M_PKTHDR) ? (m)->m_pktdat : (m)->m_dat)
690:
691: 692: 693: 694:
695: #define M_BUFOFFSET(m) \
696: (((m)->m_flags & M_PKTHDR) ? \
697: offsetof(struct mbuf, m_pktdat) : offsetof(struct mbuf, m_dat))
698:
699: 700: 701: 702: 703: 704:
705: #define M_PREPEND(m, plen, how) \
706: do { \
707: if (M_LEADINGSPACE(m) >= (plen)) { \
708: (m)->m_data -= (plen); \
709: (m)->m_len += (plen); \
710: } else \
711: (m) = m_prepend((m), (plen), (how)); \
712: if ((m) && ((m)->m_flags & M_PKTHDR)) \
713: (m)->m_pkthdr.len += (plen); \
714: } while ( 0)
715:
716:
717: #define MCHTYPE(m, t) \
718: do { \
719: mbstat_type_add((m)->m_type, -1); \
720: mbstat_type_add(t, 1); \
721: (m)->m_type = t; \
722: } while ( 0)
723:
724:
725: #define M_COPYALL 1000000000
726:
727:
728: #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT)
729:
730: 731: 732: 733:
734: #define M_GETCTX(m, t) ((t)(m)->m_pkthdr.rcvif)
735: #define M_SETCTX(m, c) ((void)((m)->m_pkthdr.rcvif = (void *)(c)))
736:
737: #endif
738:
739: 740: 741: 742: 743: 744: 745: 746:
747: #define MBUFQ_HEAD(name) \
748: struct name { \
749: struct mbuf *mq_first; \
750: struct mbuf **mq_last; \
751: }
752:
753: #define MBUFQ_INIT(q) do { \
754: (q)->mq_first = NULL; \
755: (q)->mq_last = &(q)->mq_first; \
756: } while (0)
757:
758: #define MBUFQ_ENQUEUE(q, m) do { \
759: (m)->m_nextpkt = NULL; \
760: *(q)->mq_last = (m); \
761: (q)->mq_last = &(m)->m_nextpkt; \
762: } while (0)
763:
764: #define MBUFQ_PREPEND(q, m) do { \
765: if (((m)->m_nextpkt = (q)->mq_first) == NULL) \
766: (q)->mq_last = &(m)->m_nextpkt; \
767: (q)->mq_first = (m); \
768: } while (0)
769:
770: #define MBUFQ_DEQUEUE(q, m) do { \
771: if (((m) = (q)->mq_first) != NULL) { \
772: if (((q)->mq_first = (m)->m_nextpkt) == NULL) \
773: (q)->mq_last = &(q)->mq_first; \
774: else \
775: (m)->m_nextpkt = NULL; \
776: } \
777: } while (0)
778:
779: #define MBUFQ_DRAIN(q) do { \
780: struct mbuf *__m0; \
781: while ((__m0 = (q)->mq_first) != NULL) { \
782: (q)->mq_first = __m0->m_nextpkt; \
783: m_freem(__m0); \
784: } \
785: (q)->mq_last = &(q)->mq_first; \
786: } while (0)
787:
788: #define MBUFQ_FIRST(q) ((q)->mq_first)
789: #define MBUFQ_NEXT(m) ((m)->m_nextpkt)
790: #define MBUFQ_LAST(q) (*(q)->mq_last)
791:
792: 793: 794: 795: 796:
797: struct mbstat {
798: u_long _m_spare;
799: u_long _m_spare1;
800: u_long _m_spare2;
801: u_long _m_spare3;
802: u_long m_drops;
803: u_long m_wait;
804: u_long m_drain;
805: u_short m_mtypes[256];
806: };
807:
808: struct mbstat_cpu {
809: u_int m_mtypes[256];
810: };
811:
812: 813: 814:
815: #define MBUF_MSIZE 1
816: #define MBUF_MCLBYTES 2
817: #define MBUF_NMBCLUSTERS 3
818: #define MBUF_MBLOWAT 4
819: #define MBUF_MCLLOWAT 5
820: #define MBUF_STATS 6
821: #define MBUF_MOWNERS 7
822: #define MBUF_MAXID 8
823:
824: #define CTL_MBUF_NAMES { \
825: { 0, 0 }, \
826: { "msize", CTLTYPE_INT }, \
827: { "mclbytes", CTLTYPE_INT }, \
828: { "nmbclusters", CTLTYPE_INT }, \
829: { "mblowat", CTLTYPE_INT }, \
830: { "mcllowat", CTLTYPE_INT }, \
831: { 0 , CTLTYPE_STRUCT }, \
832: { 0 , CTLTYPE_STRUCT }, \
833: }
834:
835: #ifdef _KERNEL
836: extern struct mbstat mbstat;
837: extern int nmbclusters;
838: extern int mblowat;
839: extern int mcllowat;
840: extern int max_linkhdr;
841: extern int max_protohdr;
842: extern int max_hdr;
843: extern int max_datalen;
844: extern const int msize;
845: extern const int mclbytes;
846: extern pool_cache_t mb_cache;
847: extern pool_cache_t mcl_cache;
848: #ifdef MBUFTRACE
849: LIST_HEAD(mownerhead, mowner);
850: extern struct mownerhead mowners;
851: extern struct mowner unknown_mowners[];
852: extern struct mowner revoked_mowner;
853: #endif
854:
855: MALLOC_DECLARE(M_MBUF);
856: MALLOC_DECLARE(M_SONAME);
857: MALLOC_DECLARE(M_SOOPTS);
858:
859: struct mbuf *m_copym(struct mbuf *, int, int, int);
860: struct mbuf *m_copypacket(struct mbuf *, int);
861: struct mbuf *m_devget(char *, int, int, struct ifnet *,
862: void (*copy)(const void *, void *, size_t));
863: struct mbuf *m_dup(struct mbuf *, int, int, int);
864: struct mbuf *m_free(struct mbuf *);
865: struct mbuf *m_get(int, int);
866: struct mbuf *m_getclr(int, int);
867: struct mbuf *m_gethdr(int, int);
868: struct mbuf *m_prepend(struct mbuf *,int, int);
869: struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
870: struct mbuf *m_pullup(struct mbuf *, int);
871: struct mbuf *m_copyup(struct mbuf *, int, int);
872: struct mbuf *m_split(struct mbuf *,int, int);
873: struct mbuf *m_getptr(struct mbuf *, int, int *);
874: void m_adj(struct mbuf *, int);
875: int m_apply(struct mbuf *, int, int,
876: int (*)(void *, void *, unsigned int), void *);
877: void m_cat(struct mbuf *,struct mbuf *);
878: void m_clget(struct mbuf *, int);
879: int m_mballoc(int, int);
880: void m_copyback(struct mbuf *, int, int, const void *);
881: struct mbuf *m_copyback_cow(struct mbuf *, int, int, const void *, int);
882: int m_makewritable(struct mbuf **, int, int, int);
883: struct mbuf *m_getcl(int, int, int);
884: void m_copydata(struct mbuf *, int, int, void *);
885: void m_freem(struct mbuf *);
886: void m_reclaim(void *, int);
887: #ifndef T2EX
888: void mbinit(void);
889: #else
890: int mbinit(void);
891: int mbfinish(void);
892: #endif
893: void m_ext_free(struct mbuf *);
894: char * m_mapin(struct mbuf *);
895: void m_move_pkthdr(struct mbuf *to, struct mbuf *from);
896:
897:
898: static __inline u_int m_length(const struct mbuf *) __unused;
899:
900:
901: void mbstat_type_add(int, int);
902:
903:
904: struct m_tag *m_tag_get(int, int, int);
905: void m_tag_free(struct m_tag *);
906: void m_tag_prepend(struct mbuf *, struct m_tag *);
907: void m_tag_unlink(struct mbuf *, struct m_tag *);
908: void m_tag_delete(struct mbuf *, struct m_tag *);
909: void m_tag_delete_chain(struct mbuf *, struct m_tag *);
910: void m_tag_delete_nonpersistent(struct mbuf *);
911: struct m_tag *m_tag_find(struct mbuf *, int, struct m_tag *);
912: struct m_tag *m_tag_copy(struct m_tag *);
913: int m_tag_copy_chain(struct mbuf *, struct mbuf *);
914: void m_tag_init(struct mbuf *);
915: struct m_tag *m_tag_first(struct mbuf *);
916: struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
917:
918:
919: #define PACKET_TAG_NONE 0
920: #define PACKET_TAG_VLAN 1
921: #define PACKET_TAG_ENCAP 2
922: #define PACKET_TAG_ESP 3
923: #define PACKET_TAG_PF 11
924: #define PACKET_TAG_ALTQ_QID 12
925:
926: #define PACKET_TAG_IPSEC_IN_CRYPTO_DONE 16
927: #define PACKET_TAG_IPSEC_IN_DONE 17
928: #define PACKET_TAG_IPSEC_OUT_DONE 18
929: #define PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED 19
930: #define PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO 20
931: #define PACKET_TAG_IPSEC_PENDING_TDB 21
932:
933: #define PACKET_TAG_IPSEC_SOCKET 22
934: #define PACKET_TAG_IPSEC_HISTORY 23
935:
936: #define PACKET_TAG_IPSEC_NAT_T_PORTS 25
937:
938: #define PACKET_TAG_INET6 26
939:
940: #define PACKET_TAG_ECO_RETRYPARMS 27
941:
942: #define PACKET_TAG_TUNNEL_INFO 28 943: 944: 945:
946:
947: 948: 949:
950: static __inline u_int
951: m_length(const struct mbuf *m)
952: {
953: const struct mbuf *m0;
954: u_int pktlen;
955:
956: if ((m->m_flags & M_PKTHDR) != 0)
957: return m->m_pkthdr.len;
958:
959: pktlen = 0;
960: for (m0 = m; m0 != NULL; m0 = m0->m_next)
961: pktlen += m0->m_len;
962: return pktlen;
963: }
964:
965: void m_print(const struct mbuf *, const char *, void (*)(const char *, ...));
966:
967: #endif
968: #endif
969:
970: #if defined(_KERNEL) && !defined(T2EX)
971: #ifdef MBTYPES
972: struct malloc_type *mbtypes[] = {
973: M_FREE,
974: M_MBUF,
975: M_MBUF,
976: M_SONAME,
977: M_SOOPTS,
978: M_FTABLE,
979: M_MBUF,
980: M_MBUF,
981: };
982: #undef MBTYPES
983: #else
984: extern struct malloc_type *mbtypes[];
985: #endif
986: #endif