+#ifdef KERNEL_PRIVATE
+__BEGIN_DECLS
+
+/*
+ * Exported (private)
+ */
+
+extern struct mbstat mbstat; /* statistics */
+
+__END_DECLS
+#endif /* KERNEL_PRIVATE */
+
+#ifdef XNU_KERNEL_PRIVATE
+__BEGIN_DECLS
+
+/*
+ * Not exported (xnu private)
+ */
+
+/* flags to m_get/MGET */
+/* Need to include malloc.h to get right options for malloc */
+#include <sys/malloc.h>
+
+struct mbuf;
+
+/* length to m_copy to copy all */
+#define M_COPYALL 1000000000
+
+#define M_DONTWAIT M_NOWAIT
+#define M_WAIT M_WAITOK
+
+/* modes for m_copym and variants */
+#define M_COPYM_NOOP_HDR 0 /* don't copy/move pkthdr contents */
+#define M_COPYM_COPY_HDR 1 /* copy pkthdr from old to new */
+#define M_COPYM_MOVE_HDR 2 /* move pkthdr from old to new */
+
+/*
+ * These macros are mapped to the appropriate KPIs, so that private code
+ * can be simply recompiled in order to be forward-compatible with future
+ * changes toward the struture sizes.
+ */
+#define MLEN mbuf_get_mlen() /* normal data len */
+#define MHLEN mbuf_get_mhlen() /* data len w/pkthdr */
+
+#define MINCLSIZE mbuf_get_minclsize() /* cluster usage threshold */
+
+extern void m_freem(struct mbuf *);
+extern u_int64_t mcl_to_paddr(char *);
+extern void m_adj(struct mbuf *, int);
+extern void m_cat(struct mbuf *, struct mbuf *);
+extern void m_copydata(struct mbuf *, int, int, void *);
+extern struct mbuf *m_copym(struct mbuf *, int, int, int);
+extern struct mbuf *m_copym_mode(struct mbuf *, int, int, int, uint32_t);
+extern struct mbuf *m_get(int, int);
+extern struct mbuf *m_gethdr(int, int);
+extern struct mbuf *m_getpacket(void);
+extern struct mbuf *m_getpackets(int, int, int);
+extern struct mbuf *m_mclget(struct mbuf *, int);
+extern void *m_mtod(struct mbuf *);
+extern struct mbuf *m_prepend_2(struct mbuf *, int, int);
+extern struct mbuf *m_pullup(struct mbuf *, int);
+extern struct mbuf *m_split(struct mbuf *, int, int);
+extern void m_mclfree(caddr_t p);
+
+/*
+ * On platforms which require strict alignment (currently for anything but
+ * i386 or x86_64), this macro checks whether the data pointer of an mbuf
+ * is 32-bit aligned (this is the expected minimum alignment for protocol
+ * headers), and assert otherwise.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+#define MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(_m)
+#else /* !__i386__ && !__x86_64__ */
+#define MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(_m) do { \
+ if (!IS_P2ALIGNED((_m)->m_data, sizeof (u_int32_t))) { \
+ if (((_m)->m_flags & M_PKTHDR) && \
+ (_m)->m_pkthdr.rcvif != NULL) { \
+ panic_plain("\n%s: mbuf %p data ptr %p is not " \
+ "32-bit aligned [%s: alignerrs=%lld]\n", \
+ __func__, (_m), (_m)->m_data, \
+ if_name((_m)->m_pkthdr.rcvif), \
+ (_m)->m_pkthdr.rcvif->if_alignerrs); \
+ } else { \
+ panic_plain("\n%s: mbuf %p data ptr %p is not " \
+ "32-bit aligned\n", \
+ __func__, (_m), (_m)->m_data); \
+ } \
+ } \
+} while (0)
+#endif /* !__i386__ && !__x86_64__ */
+
+/* Maximum number of MBUF_SC values (excluding MBUF_SC_UNSPEC) */
+#define MBUF_SC_MAX_CLASSES 10
+
+/*
+ * These conversion macros rely on the corresponding MBUF_SC and
+ * MBUF_TC values in order to establish the following mapping:
+ *
+ * MBUF_SC_BK_SYS ] ==> MBUF_TC_BK
+ * MBUF_SC_BK ]
+ *
+ * MBUF_SC_BE ] ==> MBUF_TC_BE
+ * MBUF_SC_RD ]
+ * MBUF_SC_OAM ]
+ *
+ * MBUF_SC_AV ] ==> MBUF_TC_VI
+ * MBUF_SC_RV ]
+ * MBUF_SC_VI ]
+ *
+ * MBUF_SC_VO ] ==> MBUF_TC_VO
+ * MBUF_SC_CTL ]
+ *
+ * The values assigned to each service class allows for a fast mapping to
+ * the corresponding MBUF_TC traffic class values, as well as to retrieve the
+ * assigned index; therefore care must be taken when comparing against these
+ * values. Use the corresponding class and index macros to retrieve the
+ * corresponding portion, and never assume that a higher class corresponds
+ * to a higher index.
+ */
+#define MBUF_SCVAL(x) ((x) & 0xffff)
+#define MBUF_SCIDX(x) ((((x) >> 16) & 0xff) >> 3)
+#define MBUF_SC2TC(_sc) (MBUF_SCVAL(_sc) >> 7)
+#define MBUF_TC2SCVAL(_tc) ((_tc) << 7)
+#define IS_MBUF_SC_BACKGROUND(_sc) (((_sc) == MBUF_SC_BK_SYS) || \
+ ((_sc) == MBUF_SC_BK))
+
+#define SCIDX_BK_SYS MBUF_SCIDX(MBUF_SC_BK_SYS)
+#define SCIDX_BK MBUF_SCIDX(MBUF_SC_BK)
+#define SCIDX_BE MBUF_SCIDX(MBUF_SC_BE)
+#define SCIDX_RD MBUF_SCIDX(MBUF_SC_RD)
+#define SCIDX_OAM MBUF_SCIDX(MBUF_SC_OAM)
+#define SCIDX_AV MBUF_SCIDX(MBUF_SC_AV)
+#define SCIDX_RV MBUF_SCIDX(MBUF_SC_RV)
+#define SCIDX_VI MBUF_SCIDX(MBUF_SC_VI)
+#define SCIDX_VO MBUF_SCIDX(MBUF_SC_VO)
+#define SCIDX_CTL MBUF_SCIDX(MBUF_SC_CTL)
+
+#define SCVAL_BK_SYS MBUF_SCVAL(MBUF_SC_BK_SYS)
+#define SCVAL_BK MBUF_SCVAL(MBUF_SC_BK)
+#define SCVAL_BE MBUF_SCVAL(MBUF_SC_BE)
+#define SCVAL_RD MBUF_SCVAL(MBUF_SC_RD)
+#define SCVAL_OAM MBUF_SCVAL(MBUF_SC_OAM)
+#define SCVAL_AV MBUF_SCVAL(MBUF_SC_AV)
+#define SCVAL_RV MBUF_SCVAL(MBUF_SC_RV)
+#define SCVAL_VI MBUF_SCVAL(MBUF_SC_VI)
+#define SCVAL_VO MBUF_SCVAL(MBUF_SC_VO)
+#define SCVAL_CTL MBUF_SCVAL(MBUF_SC_CTL)
+
+#define MBUF_VALID_SC(c) \
+ (c == MBUF_SC_BK_SYS || c == MBUF_SC_BK || c == MBUF_SC_BE || \
+ c == MBUF_SC_RD || c == MBUF_SC_OAM || c == MBUF_SC_AV || \
+ c == MBUF_SC_RV || c == MBUF_SC_VI || c == MBUF_SC_VO || \
+ c == MBUF_SC_CTL)
+
+#define MBUF_VALID_SCIDX(c) \
+ (c == SCIDX_BK_SYS || c == SCIDX_BK || c == SCIDX_BE || \
+ c == SCIDX_RD || c == SCIDX_OAM || c == SCIDX_AV || \
+ c == SCIDX_RV || c == SCIDX_VI || c == SCIDX_VO || \
+ c == SCIDX_CTL)
+
+#define MBUF_VALID_SCVAL(c) \
+ (c == SCVAL_BK_SYS || c == SCVAL_BK || c == SCVAL_BE || \
+ c == SCVAL_RD || c == SCVAL_OAM || c == SCVAL_AV || \
+ c == SCVAL_RV || c == SCVAL_VI || c == SCVAL_VO || \
+ c == SCVAL_CTL)
+
+extern union mbigcluster *mbutl; /* start VA of mbuf pool */
+extern union mbigcluster *embutl; /* end VA of mbuf pool */
+extern unsigned int nmbclusters; /* number of mapped clusters */
+extern int njcl; /* # of jumbo clusters */
+extern int njclbytes; /* size of a jumbo cluster */
+extern int max_hdr; /* largest link+protocol header */
+extern int max_datalen; /* MHLEN - max_hdr */
+
+/* Use max_linkhdr instead of _max_linkhdr */
+extern int _max_linkhdr; /* largest link-level header */
+
+/* Use max_protohdr instead of _max_protohdr */
+extern int _max_protohdr; /* largest protocol header */
+
+__private_extern__ unsigned int mbuf_default_ncl(int, u_int64_t);
+__private_extern__ void mbinit(void);
+__private_extern__ struct mbuf *m_clattach(struct mbuf *, int, caddr_t,
+ void (*)(caddr_t, u_int, caddr_t), u_int, caddr_t, int);
+__private_extern__ caddr_t m_bigalloc(int);
+__private_extern__ void m_bigfree(caddr_t, u_int, caddr_t);
+__private_extern__ struct mbuf *m_mbigget(struct mbuf *, int);
+__private_extern__ caddr_t m_16kalloc(int);
+__private_extern__ void m_16kfree(caddr_t, u_int, caddr_t);
+__private_extern__ struct mbuf *m_m16kget(struct mbuf *, int);
+__private_extern__ int m_reinit(struct mbuf *, int);
+__private_extern__ struct mbuf *m_free(struct mbuf *);
+__private_extern__ struct mbuf *m_getclr(int, int);
+__private_extern__ struct mbuf *m_getptr(struct mbuf *, int, int *);
+__private_extern__ unsigned int m_length(struct mbuf *);
+__private_extern__ unsigned int m_length2(struct mbuf *, struct mbuf **);
+__private_extern__ unsigned int m_fixhdr(struct mbuf *);
+__private_extern__ struct mbuf *m_defrag(struct mbuf *, int);
+__private_extern__ struct mbuf *m_defrag_offset(struct mbuf *, u_int32_t, int);
+__private_extern__ struct mbuf *m_prepend(struct mbuf *, int, int);
+__private_extern__ struct mbuf *m_copyup(struct mbuf *, int, int);
+__private_extern__ struct mbuf *m_retry(int, int);
+__private_extern__ struct mbuf *m_retryhdr(int, int);
+__private_extern__ int m_freem_list(struct mbuf *);
+__private_extern__ int m_append(struct mbuf *, int, caddr_t);
+__private_extern__ struct mbuf *m_last(struct mbuf *);
+__private_extern__ struct mbuf *m_devget(char *, int, int, struct ifnet *,
+ void (*)(const void *, void *, size_t));
+__private_extern__ struct mbuf *m_pulldown(struct mbuf *, int, int, int *);
+
+__private_extern__ struct mbuf *m_getcl(int, int, int);
+__private_extern__ caddr_t m_mclalloc(int);
+__private_extern__ int m_mclhasreference(struct mbuf *);
+__private_extern__ void m_copy_pkthdr(struct mbuf *, struct mbuf *);
+__private_extern__ void m_copy_pftag(struct mbuf *, struct mbuf *);
+__private_extern__ void m_copy_classifier(struct mbuf *, struct mbuf *);
+
+__private_extern__ struct mbuf *m_dtom(void *);
+__private_extern__ int m_mtocl(void *);
+__private_extern__ union mcluster *m_cltom(int);
+
+__private_extern__ int m_trailingspace(struct mbuf *);
+__private_extern__ int m_leadingspace(struct mbuf *);
+
+__private_extern__ struct mbuf *m_normalize(struct mbuf *m);
+__private_extern__ void m_mchtype(struct mbuf *m, int t);
+__private_extern__ void m_mcheck(struct mbuf *);
+
+__private_extern__ void m_copyback(struct mbuf *, int, int, const void *);
+__private_extern__ struct mbuf *m_copyback_cow(struct mbuf *, int, int,
+ const void *, int);
+__private_extern__ int m_makewritable(struct mbuf **, int, int, int);
+__private_extern__ struct mbuf *m_dup(struct mbuf *m, int how);
+__private_extern__ struct mbuf *m_copym_with_hdrs(struct mbuf *, int, int, int,
+ struct mbuf **, int *, uint32_t);
+__private_extern__ struct mbuf *m_getpackethdrs(int, int);
+__private_extern__ struct mbuf *m_getpacket_how(int);
+__private_extern__ struct mbuf *m_getpackets_internal(unsigned int *, int,
+ int, int, size_t);
+__private_extern__ struct mbuf *m_allocpacket_internal(unsigned int *, size_t,
+ unsigned int *, int, int, size_t);
+
+/*
+ * Packets may have annotations attached by affixing a list of "packet
+ * tags" to the pkthdr structure. Packet tags are dynamically allocated
+ * semi-opaque data structures that have a fixed header (struct m_tag)
+ * that specifies the size of the memory block and an <id,type> pair that
+ * identifies it. The id identifies the module and the type identifies the
+ * type of data for that module. The id of zero is reserved for the kernel.
+ *
+ * Note that the packet tag returned by m_tag_allocate has the default
+ * memory alignment implemented by malloc. To reference private data one
+ * can use a construct like:
+ *
+ * struct m_tag *mtag = m_tag_allocate(...);
+ * struct foo *p = (struct foo *)(mtag+1);
+ *
+ * if the alignment of struct m_tag is sufficient for referencing members
+ * of struct foo. Otherwise it is necessary to embed struct m_tag within
+ * the private data structure to insure proper alignment; e.g.
+ *
+ * struct foo {
+ * struct m_tag tag;
+ * ...
+ * };
+ * struct foo *p = (struct foo *) m_tag_allocate(...);
+ * struct m_tag *mtag = &p->tag;
+ */
+
+#define KERNEL_MODULE_TAG_ID 0
+
+enum {
+ KERNEL_TAG_TYPE_NONE = 0,
+ KERNEL_TAG_TYPE_DUMMYNET = 1,
+ KERNEL_TAG_TYPE_DIVERT = 2,
+ KERNEL_TAG_TYPE_IPFORWARD = 3,
+ KERNEL_TAG_TYPE_IPFILT = 4,
+ KERNEL_TAG_TYPE_MACLABEL = 5,
+ KERNEL_TAG_TYPE_MAC_POLICY_LABEL = 6,
+ KERNEL_TAG_TYPE_ENCAP = 8,
+ KERNEL_TAG_TYPE_INET6 = 9,
+ KERNEL_TAG_TYPE_IPSEC = 10,
+ KERNEL_TAG_TYPE_DRVAUX = 11
+};
+
+/* Packet tag routines */
+__private_extern__ struct m_tag *m_tag_alloc(u_int32_t, u_int16_t, int, int);
+__private_extern__ struct m_tag *m_tag_create(u_int32_t, u_int16_t, int, int,
+ struct mbuf *);
+__private_extern__ void m_tag_free(struct m_tag *);
+__private_extern__ void m_tag_prepend(struct mbuf *, struct m_tag *);
+__private_extern__ void m_tag_unlink(struct mbuf *, struct m_tag *);
+__private_extern__ void m_tag_delete(struct mbuf *, struct m_tag *);
+__private_extern__ void m_tag_delete_chain(struct mbuf *, struct m_tag *);
+__private_extern__ struct m_tag *m_tag_locate(struct mbuf *, u_int32_t,
+ u_int16_t, struct m_tag *);
+__private_extern__ struct m_tag *m_tag_copy(struct m_tag *, int);
+__private_extern__ int m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
+__private_extern__ void m_tag_init(struct mbuf *, int);
+__private_extern__ struct m_tag *m_tag_first(struct mbuf *);
+__private_extern__ struct m_tag *m_tag_next(struct mbuf *, struct m_tag *);
+
+__END_DECLS
+#endif /* XNU_KERNEL_PRIVATE */
+#ifdef KERNEL
+#include <sys/kpi_mbuf.h>
+#ifdef XNU_KERNEL_PRIVATE
+__BEGIN_DECLS
+
+__private_extern__ void m_scratch_init(struct mbuf *);
+__private_extern__ u_int32_t m_scratch_get(struct mbuf *, u_int8_t **);
+
+__private_extern__ void m_classifier_init(struct mbuf *, uint32_t);
+
+__private_extern__ int m_set_service_class(struct mbuf *, mbuf_svc_class_t);
+__private_extern__ mbuf_svc_class_t m_get_service_class(struct mbuf *);
+__private_extern__ mbuf_svc_class_t m_service_class_from_idx(u_int32_t);
+__private_extern__ mbuf_svc_class_t m_service_class_from_val(u_int32_t);
+__private_extern__ int m_set_traffic_class(struct mbuf *, mbuf_traffic_class_t);
+__private_extern__ mbuf_traffic_class_t m_get_traffic_class(struct mbuf *);
+
+#define ADDCARRY(_x) do { \
+ while (((_x) >> 16) != 0) \
+ (_x) = ((_x) >> 16) + ((_x) & 0xffff); \
+} while (0)
+
+__private_extern__ u_int16_t m_adj_sum16(struct mbuf *, u_int32_t,
+ u_int32_t, u_int32_t);
+__private_extern__ u_int16_t m_sum16(struct mbuf *, u_int32_t, u_int32_t);
+
+__END_DECLS
+#endif /* XNU_KERNEL_PRIVATE */
+#endif /* KERNEL */