code:
/*-
 * Copyright (c) 2008-2009 Stacey Son <sson@FreeBSD.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/lockstat.h 192853 2009-05-26 20:28:22Z sson $
 */

/*
 * DTrace lockstat provider definitions
 *
 */

#ifndef	_SYS_LOCKSTAT_H
#define	_SYS_LOCKSTAT_H

#ifdef	_KERNEL

/*
 * Spin Locks
 */
#define	LS_MTX_SPIN_LOCK_ACQUIRE	0
#define	LS_MTX_SPIN_UNLOCK_RELEASE	1
#define	LS_MTX_SPIN_LOCK_SPIN		2

/*
 * Adaptive Locks
 */
#define	LS_MTX_LOCK_ACQUIRE		3
#define	LS_MTX_UNLOCK_RELEASE		4
#define	LS_MTX_LOCK_SPIN		5
#define	LS_MTX_LOCK_BLOCK		6
#define	LS_MTX_TRYLOCK_ACQUIRE		7

/*
 * Reader/Writer Locks
 */
#define	LS_RW_RLOCK_ACQUIRE		8
#define	LS_RW_RUNLOCK_RELEASE		9
#define	LS_RW_WLOCK_ACQUIRE		10
#define	LS_RW_WUNLOCK_RELEASE		11
#define	LS_RW_RLOCK_SPIN		12
#define	LS_RW_RLOCK_BLOCK		13
#define	LS_RW_WLOCK_SPIN		14
#define	LS_RW_WLOCK_BLOCK		15
#define	LS_RW_TRYUPGRADE_UPGRADE	16
#define	LS_RW_DOWNGRADE_DOWNGRADE	17

/*
 * Shared/Exclusive Locks
 */
#define	LS_SX_SLOCK_ACQUIRE		18
#define	LS_SX_SUNLOCK_RELEASE		19
#define	LS_SX_XLOCK_ACQUIRE		20
#define	LS_SX_XUNLOCK_RELEASE		21
#define	LS_SX_SLOCK_SPIN		22
#define	LS_SX_SLOCK_BLOCK		23
#define	LS_SX_XLOCK_SPIN		24
#define	LS_SX_XLOCK_BLOCK		25
#define	LS_SX_TRYUPGRADE_UPGRADE	26
#define	LS_SX_DOWNGRADE_DOWNGRADE	27

/*
 * Thread Locks
 */
#define	LS_THREAD_LOCK_SPIN		28

/*
 * Lockmanager Locks
 *  According to locking(9) Lockmgr locks are "Largely deprecated"
 *  so no support for these have been added in the lockstat provider.
 */

#define	LS_NPROBES			29

#define	LS_MTX_LOCK			"mtx_lock"
#define	LS_MTX_UNLOCK			"mtx_unlock"
#define	LS_MTX_SPIN_LOCK		"mtx_lock_spin"
#define	LS_MTX_SPIN_UNLOCK		"mtx_unlock_spin"
#define	LS_MTX_TRYLOCK			"mtx_trylock"
#define	LS_RW_RLOCK			"rw_rlock"
#define	LS_RW_WLOCK			"rw_wlock"
#define	LS_RW_RUNLOCK			"rw_runlock"
#define	LS_RW_WUNLOCK			"rw_wunlock"
#define	LS_RW_TRYUPGRADE		"rw_try_upgrade"
#define	LS_RW_DOWNGRADE			"rw_downgrade"
#define	LS_SX_SLOCK			"sx_slock"
#define	LS_SX_XLOCK			"sx_xlock"
#define	LS_SX_SUNLOCK			"sx_sunlock"
#define	LS_SX_XUNLOCK			"sx_xunlock"
#define	LS_SX_TRYUPGRADE		"sx_try_upgrade"
#define	LS_SX_DOWNGRADE			"sx_downgrade"
#define	LS_THREAD_LOCK			"thread_lock"

#define	LS_ACQUIRE			"acquire"
#define	LS_RELEASE			"release"
#define	LS_SPIN				"spin"
#define	LS_BLOCK			"block"
#define	LS_UPGRADE			"upgrade"
#define	LS_DOWNGRADE			"downgrade"

#define	LS_TYPE_ADAPTIVE		"adaptive"
#define	LS_TYPE_SPIN			"spin"
#define	LS_TYPE_THREAD			"thread"
#define	LS_TYPE_RW			"rw"
#define	LS_TYPE_SX			"sx"

#define	LSA_ACQUIRE			(LS_TYPE_ADAPTIVE "-" LS_ACQUIRE)
#define	LSA_RELEASE			(LS_TYPE_ADAPTIVE "-" LS_RELEASE)
#define	LSA_SPIN			(LS_TYPE_ADAPTIVE "-" LS_SPIN)
#define	LSA_BLOCK			(LS_TYPE_ADAPTIVE "-" LS_BLOCK)
#define	LSS_ACQUIRE			(LS_TYPE_SPIN "-" LS_ACQUIRE)
#define	LSS_RELEASE			(LS_TYPE_SPIN "-" LS_RELEASE)
#define	LSS_SPIN			(LS_TYPE_SPIN "-" LS_SPIN)
#define	LSR_ACQUIRE			(LS_TYPE_RW "-" LS_ACQUIRE)
#define	LSR_RELEASE			(LS_TYPE_RW "-" LS_RELEASE)
#define	LSR_BLOCK			(LS_TYPE_RW "-" LS_BLOCK)
#define	LSR_SPIN			(LS_TYPE_RW "-" LS_SPIN)
#define	LSR_UPGRADE			(LS_TYPE_RW "-" LS_UPGRADE)
#define	LSR_DOWNGRADE			(LS_TYPE_RW "-" LS_DOWNGRADE)
#define	LSX_ACQUIRE			(LS_TYPE_SX "-" LS_ACQUIRE)
#define	LSX_RELEASE			(LS_TYPE_SX "-" LS_RELEASE)
#define	LSX_BLOCK			(LS_TYPE_SX "-" LS_BLOCK)
#define	LSX_SPIN			(LS_TYPE_SX "-" LS_SPIN)
#define	LSX_UPGRADE			(LS_TYPE_SX "-" LS_UPGRADE)
#define	LSX_DOWNGRADE			(LS_TYPE_SX "-" LS_DOWNGRADE)
#define	LST_SPIN			(LS_TYPE_THREAD "-" LS_SPIN)

/*
 * The following must match the type definition of dtrace_probe.  It is
 * defined this way to avoid having to rely on CDDL code.
 */
extern uint32_t lockstat_probemap[LS_NPROBES];
typedef void (*lockstat_probe_func_t)(uint32_t, uintptr_t arg0, uintptr_t arg1,
    uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
extern lockstat_probe_func_t lockstat_probe_func;
extern uint64_t lockstat_nsecs(void);

#ifdef	KDTRACE_HOOKS
/*
 * Macros to record lockstat probes.
 */
#define	LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, arg4)  do {	\
	uint32_t id;							\
									\
	if ((id = lockstat_probemap[(probe)])) 				\
	    (*lockstat_probe_func)(id, (uintptr_t)(lp), (arg1),	(arg2),	\
		(arg3), (arg4));					\
} while (0)

#define	LOCKSTAT_RECORD(probe, lp, arg1) \
	LOCKSTAT_RECORD4(probe, lp, arg1, 0, 0, 0)

#define	LOCKSTAT_RECORD0(probe, lp)     \
	LOCKSTAT_RECORD4(probe, lp, 0, 0, 0, 0)

#define	LOCKSTAT_RECORD1(probe, lp, arg1) \
	LOCKSTAT_RECORD4(probe, lp, arg1, 0, 0, 0)

#define	LOCKSTAT_RECORD2(probe, lp, arg1, arg2) \
	LOCKSTAT_RECORD4(probe, lp, arg1, arg2, 0, 0)

#define	LOCKSTAT_RECORD3(probe, lp, arg1, arg2, arg3) \
	LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, 0)

#define	LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l)  do {   \
	uint32_t id;							     \
									     \
    	lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l);   \
	if ((id = lockstat_probemap[(probe)])) 			     	     \
		(*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0);     \
} while (0)

#define	LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp)  do {			     \
	uint32_t id;							     \
									     \
	lock_profile_release_lock(&(lp)->lock_object);			     \
	if ((id = lockstat_probemap[(probe)])) 			     	     \
		(*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0);     \
} while (0)

#else	/* !KDTRACE_HOOKS */

#define	LOCKSTAT_RECORD(probe, lp, arg1)
#define	LOCKSTAT_RECORD0(probe, lp)
#define	LOCKSTAT_RECORD1(probe, lp, arg1)
#define	LOCKSTAT_RECORD2(probe, lp, arg1, arg2)
#define	LOCKSTAT_RECORD3(probe, lp, arg1, arg2, arg3)
#define	LOCKSTAT_RECORD4(probe, lp, arg1, arg2, arg3, arg4)

#define	LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(probe, lp, c, wt, f, l)	\
	lock_profile_obtain_lock_success(&(lp)->lock_object, c, wt, f, l)

#define	LOCKSTAT_PROFILE_RELEASE_LOCK(probe, lp)  			\
	lock_profile_release_lock(&(lp)->lock_object)

#endif	/* !KDTRACE_HOOKS */

#endif	/* _KERNEL */

#endif	/* _SYS_LOCKSTAT_H */


code:
/*-
 * Copyright (c) 2011 The FreeBSD Foundation
 * All rights reserved.
 *
 * This software was developed by Edward Tomasz Napierala under sponsorship
 * from the FreeBSD Foundation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/loginclass.h 220137 2011-03-29 17:47:25Z trasz $
 */

#ifndef _SYS_LOGINCLASS_H_
#define	_SYS_LOGINCLASS_H_

struct racct;

/*
 * Exactly one of these structures exists per login class.
 */
struct loginclass {
	LIST_ENTRY(loginclass)	lc_next;
	char			lc_name[MAXLOGNAME];
	u_int			lc_refcount;
	struct racct		*lc_racct;
};

void	loginclass_hold(struct loginclass *lc);
void	loginclass_free(struct loginclass *lc);
struct loginclass	*loginclass_find(const char *name);
void	loginclass_racct_foreach(void (*callback)(struct racct *racct,
	    void *arg2, void *arg3), void *arg2, void *arg3);

#endif /* !_SYS_LOGINCLASS_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 1999-2002 Robert N. M. Watson
 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
 * Copyright (c) 2005-2006 SPARTA, Inc.
 * All rights reserved.
 *
 * This software was developed by Robert Watson for the TrustedBSD Project.
 *
 * This software was developed for the FreeBSD Project in part by Network
 * Associates Laboratories, the Security Research Division of Network
 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
 * as part of the DARPA CHATS research program.
 *
 * This software was enhanced by SPARTA ISSO under SPAWAR contract
 * N66001-04-C-6019 ("SEFOS").
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/mac.h 166537 2007-02-06 16:24:57Z rwatson $
 */
/*
 * Userland interface for Mandatory Access Control.  Loosely based on the
 * POSIX.1e API.  More information may be found at:
 *
 * http://www.TrustedBSD.org/
 */

#ifndef _SYS_MAC_H_
#define	_SYS_MAC_H_

#ifndef _POSIX_MAC
#define	_POSIX_MAC
#endif

/*
 * MAC framework-related constants and limits.
 */
#define	MAC_MAX_POLICY_NAME		32
#define	MAC_MAX_LABEL_ELEMENT_NAME	32
#define	MAC_MAX_LABEL_ELEMENT_DATA	4096
#define	MAC_MAX_LABEL_BUF_LEN		8192

/*
 * struct mac is the data structure used to carry MAC labels in system calls
 * and ioctls between userspace and the kernel.
 */
struct mac {
	size_t		 m_buflen;
	char		*m_string;
};

typedef struct mac	*mac_t;

#ifndef _KERNEL

/*
 * Location of the userland MAC framework configuration file.  mac.conf
 * set defaults for MAC-aware applications.
 */
#define	MAC_CONFFILE	"/etc/mac.conf"

/*
 * Extended non-POSIX.1e interfaces that offer additional services available
 * from the userland and kernel MAC frameworks.
 */
__BEGIN_DECLS
int	 mac_execve(char *fname, char **argv, char **envv, mac_t _label);
int	 mac_free(mac_t _label);
int	 mac_from_text(mac_t *_label, const char *_text);
int	 mac_get_fd(int _fd, mac_t _label);
int	 mac_get_file(const char *_path, mac_t _label);
int	 mac_get_link(const char *_path, mac_t _label);
int	 mac_get_peer(int _fd, mac_t _label);
int	 mac_get_pid(pid_t _pid, mac_t _label);
int	 mac_get_proc(mac_t _label);
int	 mac_is_present(const char *_policyname);
int	 mac_prepare(mac_t *_label, const char *_elements);
int	 mac_prepare_file_label(mac_t *_label);
int	 mac_prepare_ifnet_label(mac_t *_label);
int	 mac_prepare_process_label(mac_t *_label);
int	 mac_prepare_type(mac_t *_label, const char *_type);
int	 mac_set_fd(int _fildes, const mac_t _label);
int	 mac_set_file(const char *_path, mac_t _label);
int	 mac_set_link(const char *_path, mac_t _label);
int	 mac_set_proc(const mac_t _label);
int	 mac_syscall(const char *_policyname, int _call, void *_arg);
int	 mac_to_text(mac_t mac, char **_text);
__END_DECLS

#endif /* !_KERNEL */

#endif /* !_SYS_MAC_H_ */


code:
/*-
 * Copyright (c) 1987, 1993
 *	The Regents of the University of California.
 * Copyright (c) 2005, 2009 Robert N. M. Watson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)malloc.h	8.5 (Berkeley) 5/3/95
 * $FreeBSD: release/9.0.0/sys/sys/malloc.h 210564 2010-07-28 15:36:12Z mdf $
 */

#ifndef _SYS_MALLOC_H_
#define	_SYS_MALLOC_H_

#include <sys/param.h>
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>

#define	MINALLOCSIZE	UMA_SMALLEST_UNIT

/*
 * flags to malloc.
 */
#define	M_NOWAIT	0x0001		/* do not block */
#define	M_WAITOK	0x0002		/* ok to block */
#define	M_ZERO		0x0100		/* bzero the allocation */
#define	M_NOVM		0x0200		/* don't ask VM for pages */
#define	M_EXEC	0x4000	/* allocate executable space */
#define	M_USE_RESERVE	0x0400		/* can alloc out of reserve memory */
#define	M_NODUMP	0x0800

#define	M_MAGIC		877983977	/* time when first defined :-) */

/*
 * Two malloc type structures are present: malloc_type, which is used by a
 * type owner to declare the type, and malloc_type_internal, which holds
 * malloc-owned statistics and other ABI-sensitive fields, such as the set of
 * malloc statistics indexed by the compile-time MAXCPU constant.
 * Applications should avoid introducing dependence on the allocator private
 * data layout and size.
 *
 * The malloc_type ks_next field is protected by malloc_mtx.  Other fields in
 * malloc_type are static after initialization so unsynchronized.
 *
 * Statistics in malloc_type_stats are written only when holding a critical
 * section and running on the CPU associated with the index into the stat
 * array, but read lock-free resulting in possible (minor) races, which the
 * monitoring app should take into account.
 */
struct malloc_type_stats {
	uint64_t	mts_memalloced;	/* Bytes allocated on CPU. */
	uint64_t	mts_memfreed;	/* Bytes freed on CPU. */
	uint64_t	mts_numallocs;	/* Number of allocates on CPU. */
	uint64_t	mts_numfrees;	/* number of frees on CPU. */
	uint64_t	mts_size;	/* Bitmask of sizes allocated on CPU. */
	uint64_t	_mts_reserved1;	/* Reserved field. */
	uint64_t	_mts_reserved2;	/* Reserved field. */
	uint64_t	_mts_reserved3;	/* Reserved field. */
};

/*
 * Index definitions for the mti_probes[] array.
 */
#define DTMALLOC_PROBE_MALLOC		0
#define DTMALLOC_PROBE_FREE		1
#define DTMALLOC_PROBE_MAX		2

struct malloc_type_internal {
	uint32_t	mti_probes[DTMALLOC_PROBE_MAX];
					/* DTrace probe ID array. */
	u_char		mti_zone;
	struct malloc_type_stats	mti_stats[MAXCPU];
};

/*
 * Public data structure describing a malloc type.  Private data is hung off
 * of ks_handle to avoid encoding internal malloc(9) data structures in
 * modules, which will statically allocate struct malloc_type.
 */
struct malloc_type {
	struct malloc_type *ks_next;	/* Next in global chain. */
	u_long		 ks_magic;	/* Detect programmer error. */
	const char	*ks_shortdesc;	/* Printable type name. */
	void		*ks_handle;	/* Priv. data, was lo_class. */
};

/*
 * Statistics structure headers for user space.  The kern.malloc sysctl
 * exposes a structure stream consisting of a stream header, then a series of
 * malloc type headers and statistics structures (quantity maxcpus).  For
 * convenience, the kernel will provide the current value of maxcpus at the
 * head of the stream.
 */
#define	MALLOC_TYPE_STREAM_VERSION	0x00000001
struct malloc_type_stream_header {
	uint32_t	mtsh_version;	/* Stream format version. */
	uint32_t	mtsh_maxcpus;	/* Value of MAXCPU for stream. */
	uint32_t	mtsh_count;	/* Number of records. */
	uint32_t	_mtsh_pad;	/* Pad/reserved field. */
};

#define	MALLOC_MAX_NAME	32
struct malloc_type_header {
	char				mth_name[MALLOC_MAX_NAME];
};

#ifdef _KERNEL
#define	MALLOC_DEFINE(type, shortdesc, longdesc)			\
	struct malloc_type type[1] = {					\
		{ NULL, M_MAGIC, shortdesc, NULL }			\
	};								\
	SYSINIT(type##_init, SI_SUB_KMEM, SI_ORDER_SECOND, malloc_init,	\
	    type);							\
	SYSUNINIT(type##_uninit, SI_SUB_KMEM, SI_ORDER_ANY,		\
	    malloc_uninit, type)

#define	MALLOC_DECLARE(type) \
	extern struct malloc_type type[1]

MALLOC_DECLARE(M_CACHE);
MALLOC_DECLARE(M_DEVBUF);
MALLOC_DECLARE(M_TEMP);

MALLOC_DECLARE(M_IP6OPT); /* for INET6 */
MALLOC_DECLARE(M_IP6NDP); /* for INET6 */

/*
 * Deprecated macro versions of not-quite-malloc() and free().
 */
#define	MALLOC(space, cast, size, type, flags) \
	((space) = (cast)malloc((u_long)(size), (type), (flags)))
#define	FREE(addr, type) free((addr), (type))

/*
 * XXX this should be declared in <sys/uio.h>, but that tends to fail
 * because <sys/uio.h> is included in a header before the source file
 * has a chance to include <sys/malloc.h> to get MALLOC_DECLARE() defined.
 */
MALLOC_DECLARE(M_IOV);

extern struct mtx malloc_mtx;

/*
 * Function type used when iterating over the list of malloc types.
 */
typedef void malloc_type_list_func_t(struct malloc_type *, void *);

void	contigfree(void *addr, unsigned long size, struct malloc_type *type);
void	*contigmalloc(unsigned long size, struct malloc_type *type, int flags,
	    vm_paddr_t low, vm_paddr_t high, unsigned long alignment,
	    unsigned long boundary) __malloc_like;
void	free(void *addr, struct malloc_type *type);
void	*malloc(unsigned long size, struct malloc_type *type, int flags) __malloc_like;
void	malloc_init(void *);
int	malloc_last_fail(void);
void	malloc_type_allocated(struct malloc_type *type, unsigned long size);
void	malloc_type_freed(struct malloc_type *type, unsigned long size);
void	malloc_type_list(malloc_type_list_func_t *, void *);
void	malloc_uninit(void *);
void	*realloc(void *addr, unsigned long size, struct malloc_type *type,
	    int flags);
void	*reallocf(void *addr, unsigned long size, struct malloc_type *type,
	    int flags);

struct malloc_type *malloc_desc2type(const char *desc);
#endif /* _KERNEL */

#endif /* !_SYS_MALLOC_H_ */


code:
/*-
 * Copyright (c) 2003
 *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
 * 	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Author: Hartmut Brandt <harti@freebsd.org>
 */

/*
 * This implements pools of DMA-able buffers that conserve DMA address space
 * by putting several buffers into one page and that allow to map between
 * 32-bit handles for the buffer and buffer addresses (to use 32-bit network
 * interfaces on 64bit machines). This assists network interfaces that may need
 * huge numbers of mbufs.
 *
 * $FreeBSD: release/9.0.0/sys/sys/mbpool.h 139825 2005-01-07 02:29:27Z imp $
 */
#ifndef _SYS_MBPOOL_H_
#define	_SYS_MBPOOL_H_

#ifdef _KERNEL

#include <sys/queue.h>

/* opaque */
struct mbpool;

/* size of reserved area at end of each chunk */
#define	MBPOOL_TRAILER_SIZE	4

/* maximum value of max_pages */
#define	MBPOOL_MAX_MAXPAGES	((1 << 14) - 1)

/* maximum number of chunks per page */
#define	MBPOOL_MAX_CHUNKS	(1 << 9)

/* initialize a pool */
int mbp_create(struct mbpool **, const char *, bus_dma_tag_t, u_int,
	size_t, size_t);

/* destroy a pool */
void mbp_destroy(struct mbpool *);

/* allocate a chunk and set used and on card */
void *mbp_alloc(struct mbpool *, bus_addr_t *, uint32_t *);

/* free a chunk */
void mbp_free(struct mbpool *, void *);

/* free a chunk that is an external mbuf */
void mbp_ext_free(void *, void *);

/* free all buffers that are marked to be on the card */
void mbp_card_free(struct mbpool *);

/* count used buffers and buffers on card */
void mbp_count(struct mbpool *, u_int *, u_int *, u_int *);

/* get the buffer from a handle and clear card bit */
void *mbp_get(struct mbpool *, uint32_t);

/* get the buffer from a handle and don't clear card bit */
void *mbp_get_keep(struct mbpool *, uint32_t);

/* sync the chunk */
void mbp_sync(struct mbpool *, uint32_t, bus_addr_t, bus_size_t, u_int);

#endif	/* _KERNEL */
#endif	/* _SYS_MBPOOL_H_ */


code:
/*-
 * Copyright (c) 1982, 1986, 1988, 1993
 *	The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
 * $FreeBSD: release/9.0.0/sys/sys/mbuf.h 223637 2011-06-28 11:57:25Z bz $
 */

#ifndef _SYS_MBUF_H_
#define	_SYS_MBUF_H_

/* XXX: These includes suck. Sorry! */
#include <sys/queue.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <vm/uma.h>
#ifdef WITNESS
#include <sys/lock.h>
#endif
#endif

/*
 * Mbufs are of a single size, MSIZE (sys/param.h), which includes overhead.
 * An mbuf may add a single "mbuf cluster" of size MCLBYTES (also in
 * sys/param.h), which has no additional overhead and is used instead of the
 * internal data area; this is done when at least MINCLSIZE of data must be
 * stored.  Additionally, it is possible to allocate a separate buffer
 * externally and attach it to the mbuf in a way similar to that of mbuf
 * clusters.
 */
#define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
#define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
#define	MINCLSIZE	(MHLEN + 1)	/* smallest amount to put in cluster */
#define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */

#ifdef _KERNEL
/*-
 * Macro for type conversion: convert mbuf pointer to data pointer of correct
 * type:
 *
 * mtod(m, t)	-- Convert mbuf pointer to data pointer of correct type.
 */
#define	mtod(m, t)	((t)((m)->m_data))

/*
 * Argument structure passed to UMA routines during mbuf and packet
 * allocations.
 */
struct mb_args {
	int	flags;	/* Flags for mbuf being allocated */
	short	type;	/* Type of mbuf being allocated */
};
#endif /* _KERNEL */

#if defined(__LP64__)
#define M_HDR_PAD    6
#else
#define M_HDR_PAD    2
#endif

/*
 * Header present at the beginning of every mbuf.
 */
struct m_hdr {
	struct mbuf	*mh_next;	/* next buffer in chain */
	struct mbuf	*mh_nextpkt;	/* next chain in queue/record */
	caddr_t		 mh_data;	/* location of data */
	int		 mh_len;	/* amount of data in this mbuf */
	int		 mh_flags;	/* flags; see below */
	short		 mh_type;	/* type of data in this mbuf */
	uint8_t          pad[M_HDR_PAD];/* word align                  */
};

/*
 * Packet tag structure (see below for details).
 */
struct m_tag {
	SLIST_ENTRY(m_tag)	m_tag_link;	/* List of packet tags */
	u_int16_t		m_tag_id;	/* Tag ID */
	u_int16_t		m_tag_len;	/* Length of data */
	u_int32_t		m_tag_cookie;	/* ABI/Module ID */
	void			(*m_tag_free)(struct m_tag *);
};

/*
 * Record/packet header in first mbuf of chain; valid only if M_PKTHDR is set.
 */
struct pkthdr {
	struct ifnet	*rcvif;		/* rcv interface */
	/* variables for ip and tcp reassembly */
	void		*header;	/* pointer to packet header */
	int		 len;		/* total packet length */
	uint32_t	 flowid;	/* packet's 4-tuple system
					 * flow identifier
					 */
	/* variables for hardware checksum */
	int		 csum_flags;	/* flags regarding checksum */
	int		 csum_data;	/* data field used by csum routines */
	u_int16_t	 tso_segsz;	/* TSO segment size */
	union {
		u_int16_t vt_vtag;	/* Ethernet 802.1p+q vlan tag */
		u_int16_t vt_nrecs;	/* # of IGMPv3 records in this chain */
	} PH_vt;
	SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
};
#define ether_vtag	PH_vt.vt_vtag

/*
 * Description of external storage mapped into mbuf; valid only if M_EXT is
 * set.
 */
struct m_ext {
	caddr_t		 ext_buf;	/* start of buffer */
	void		(*ext_free)	/* free routine if not the usual */
			    (void *, void *);
	void		*ext_arg1;	/* optional argument pointer */
	void		*ext_arg2;	/* optional argument pointer */
	u_int		 ext_size;	/* size of buffer, for ext_free */
	volatile u_int	*ref_cnt;	/* pointer to ref count info */
	int		 ext_type;	/* type of external storage */
};

/*
 * The core of the mbuf object along with some shortcut defines for practical
 * purposes.
 */
struct mbuf {
	struct m_hdr	m_hdr;
	union {
		struct {
			struct pkthdr	MH_pkthdr;	/* M_PKTHDR set */
			union {
				struct m_ext	MH_ext;	/* M_EXT set */
				char		MH_databuf[MHLEN];
			} MH_dat;
		} MH;
		char	M_databuf[MLEN];		/* !M_PKTHDR, !M_EXT */
	} M_dat;
};
#define	m_next		m_hdr.mh_next
#define	m_len		m_hdr.mh_len
#define	m_data		m_hdr.mh_data
#define	m_type		m_hdr.mh_type
#define	m_flags		m_hdr.mh_flags
#define	m_nextpkt	m_hdr.mh_nextpkt
#define	m_act		m_nextpkt
#define	m_pkthdr	M_dat.MH.MH_pkthdr
#define	m_ext		M_dat.MH.MH_dat.MH_ext
#define	m_pktdat	M_dat.MH.MH_dat.MH_databuf
#define	m_dat		M_dat.M_databuf

/*
 * mbuf flags.
 */
#define	M_EXT		0x00000001 /* has associated external storage */
#define	M_PKTHDR	0x00000002 /* start of record */
#define	M_EOR		0x00000004 /* end of record */
#define	M_RDONLY	0x00000008 /* associated data is marked read-only */
#define	M_PROTO1	0x00000010 /* protocol-specific */
#define	M_PROTO2	0x00000020 /* protocol-specific */
#define	M_PROTO3	0x00000040 /* protocol-specific */
#define	M_PROTO4	0x00000080 /* protocol-specific */
#define	M_PROTO5	0x00000100 /* protocol-specific */
#define	M_BCAST		0x00000200 /* send/received as link-level broadcast */
#define	M_MCAST		0x00000400 /* send/received as link-level multicast */
#define	M_FRAG		0x00000800 /* packet is a fragment of a larger packet */
#define	M_FIRSTFRAG	0x00001000 /* packet is first fragment */
#define	M_LASTFRAG	0x00002000 /* packet is last fragment */
#define	M_SKIP_FIREWALL	0x00004000 /* skip firewall processing */
#define	M_FREELIST	0x00008000 /* mbuf is on the free list */
#define	M_VLANTAG	0x00010000 /* ether_vtag is valid */
#define	M_PROMISC	0x00020000 /* packet was not for us */
#define	M_NOFREE	0x00040000 /* do not free mbuf, embedded in cluster */
#define	M_PROTO6	0x00080000 /* protocol-specific */
#define	M_PROTO7	0x00100000 /* protocol-specific */
#define	M_PROTO8	0x00200000 /* protocol-specific */
#define	M_FLOWID	0x00400000 /* deprecated: flowid is valid */
#define	M_HASHTYPEBITS	0x0F000000 /* mask of bits holding flowid hash type */

/*
 * For RELENG_{6,7} steal these flags for limited multiple routing table
 * support. In RELENG_8 and beyond, use just one flag and a tag.
 */
#define	M_FIB		0xF0000000 /* steal some bits to store fib number. */

#define	M_NOTIFICATION	M_PROTO5    /* SCTP notification */

/*
 * Flags to purge when crossing layers.
 */
#define	M_PROTOFLAGS \
    (M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8)

/*
 * Network interface cards are able to hash protocol fields (such as IPv4
 * addresses and TCP port numbers) classify packets into flows.  These flows
 * can then be used to maintain ordering while delivering packets to the OS
 * via parallel input queues, as well as to provide a stateless affinity
 * model.  NIC drivers can pass up the hash via m->m_pkthdr.flowid, and set
 * m_flag fields to indicate how the hash should be interpreted by the
 * network stack.
 *
 * Most NICs support RSS, which provides ordering and explicit affinity, and
 * use the hash m_flag bits to indicate what header fields were covered by
 * the hash.  M_HASHTYPE_OPAQUE can be set by non-RSS cards or configurations
 * that provide an opaque flow identifier, allowing for ordering and
 * distribution without explicit affinity.
 */
#define	M_HASHTYPE_SHIFT		24
#define	M_HASHTYPE_NONE			0x0
#define	M_HASHTYPE_RSS_IPV4		0x1	/* IPv4 2-tuple */
#define	M_HASHTYPE_RSS_TCP_IPV4		0x2	/* TCPv4 4-tuple */
#define	M_HASHTYPE_RSS_IPV6		0x3	/* IPv6 2-tuple */
#define	M_HASHTYPE_RSS_TCP_IPV6		0x4	/* TCPv6 4-tuple */
#define	M_HASHTYPE_RSS_IPV6_EX		0x5	/* IPv6 2-tuple + ext hdrs */
#define	M_HASHTYPE_RSS_TCP_IPV6_EX	0x6	/* TCPv6 4-tiple + ext hdrs */
#define	M_HASHTYPE_OPAQUE		0xf	/* ordering, not affinity */

#define	M_HASHTYPE_CLEAR(m)	(m)->m_flags &= ~(M_HASHTYPEBITS)
#define	M_HASHTYPE_GET(m)	(((m)->m_flags & M_HASHTYPEBITS) >> \
				    M_HASHTYPE_SHIFT)
#define	M_HASHTYPE_SET(m, v)	do {					\
	(m)->m_flags &= ~M_HASHTYPEBITS;				\
	(m)->m_flags |= ((v) << M_HASHTYPE_SHIFT);			\
} while (0)
#define	M_HASHTYPE_TEST(m, v)	(M_HASHTYPE_GET(m) == (v))

/*
 * Flags preserved when copying m_pkthdr.
 */
#define	M_COPYFLAGS \
    (M_PKTHDR|M_EOR|M_RDONLY|M_PROTOFLAGS|M_SKIP_FIREWALL|M_BCAST|M_MCAST|\
     M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_VLANTAG|M_PROMISC|M_FIB|M_HASHTYPEBITS)

/*
 * External buffer types: identify ext_buf type.
 */
#define	EXT_CLUSTER	1	/* mbuf cluster */
#define	EXT_SFBUF	2	/* sendfile(2)'s sf_bufs */
#define	EXT_JUMBOP	3	/* jumbo cluster 4096 bytes */
#define	EXT_JUMBO9	4	/* jumbo cluster 9216 bytes */
#define	EXT_JUMBO16	5	/* jumbo cluster 16184 bytes */
#define	EXT_PACKET	6	/* mbuf+cluster from packet zone */
#define	EXT_MBUF	7	/* external mbuf reference (M_IOVEC) */
#define	EXT_NET_DRV	100	/* custom ext_buf provided by net driver(s) */
#define	EXT_MOD_TYPE	200	/* custom module's ext_buf type */
#define	EXT_DISPOSABLE	300	/* can throw this buffer away w/page flipping */
#define	EXT_EXTREF	400	/* has externally maintained ref_cnt ptr */

/*
 * Flags indicating hw checksum support and sw checksum requirements.  This
 * field can be directly tested against if_data.ifi_hwassist.
 */
#define	CSUM_IP			0x0001		/* will csum IP */
#define	CSUM_TCP		0x0002		/* will csum TCP */
#define	CSUM_UDP		0x0004		/* will csum UDP */
#define	CSUM_IP_FRAGS		0x0008		/* will csum IP fragments */
#define	CSUM_FRAGMENT		0x0010		/* will do IP fragmentation */
#define	CSUM_TSO		0x0020		/* will do TSO */
#define	CSUM_SCTP		0x0040		/* will csum SCTP */

#define	CSUM_IP_CHECKED		0x0100		/* did csum IP */
#define	CSUM_IP_VALID		0x0200		/*   ... the csum is valid */
#define	CSUM_DATA_VALID		0x0400		/* csum_data field is valid */
#define	CSUM_PSEUDO_HDR		0x0800		/* csum_data has pseudo hdr */
#define	CSUM_SCTP_VALID		0x1000		/* SCTP checksum is valid */

#define	CSUM_DELAY_DATA		(CSUM_TCP | CSUM_UDP)
#define	CSUM_DELAY_IP		(CSUM_IP)	/* XXX add ipv6 here too? */

/*
 * mbuf types.
 */
#define	MT_NOTMBUF	0	/* USED INTERNALLY ONLY! Object is not mbuf */
#define	MT_DATA		1	/* dynamic (data) allocation */
#define	MT_HEADER	MT_DATA	/* packet header, use M_PKTHDR instead */
#define	MT_SONAME	8	/* socket name */
#define	MT_CONTROL	14	/* extra-data protocol message */
#define	MT_OOBDATA	15	/* expedited data  */
#define	MT_NTYPES	16	/* number of mbuf types for mbtypes[] */

#define	MT_NOINIT	255	/* Not a type but a flag to allocate
				   a non-initialized mbuf */

#define MB_NOTAGS	0x1UL	/* no tags attached to mbuf */

/*
 * General mbuf allocator statistics structure.
 *
 * Many of these statistics are no longer used; we instead track many
 * allocator statistics through UMA's built in statistics mechanism.
 */
struct mbstat {
	u_long	m_mbufs;	/* XXX */
	u_long	m_mclusts;	/* XXX */

	u_long	m_drain;	/* times drained protocols for space */
	u_long	m_mcfail;	/* XXX: times m_copym failed */
	u_long	m_mpfail;	/* XXX: times m_pullup failed */
	u_long	m_msize;	/* length of an mbuf */
	u_long	m_mclbytes;	/* length of an mbuf cluster */
	u_long	m_minclsize;	/* min length of data to allocate a cluster */
	u_long	m_mlen;		/* length of data in an mbuf */
	u_long	m_mhlen;	/* length of data in a header mbuf */

	/* Number of mbtypes (gives # elems in mbtypes[] array) */
	short	m_numtypes;

	/* XXX: Sendfile stats should eventually move to their own struct */
	u_long	sf_iocnt;	/* times sendfile had to do disk I/O */
	u_long	sf_allocfail;	/* times sfbuf allocation failed */
	u_long	sf_allocwait;	/* times sfbuf allocation had to wait */
};

/*
 * Flags specifying how an allocation should be made.
 *
 * The flag to use is as follows:
 * - M_DONTWAIT or M_NOWAIT from an interrupt handler to not block allocation.
 * - M_WAIT or M_WAITOK from wherever it is safe to block.
 *
 * M_DONTWAIT/M_NOWAIT means that we will not block the thread explicitly and
 * if we cannot allocate immediately we may return NULL, whereas
 * M_WAIT/M_WAITOK means that if we cannot allocate resources we
 * will block until they are available, and thus never return NULL.
 *
 * XXX Eventually just phase this out to use M_WAITOK/M_NOWAIT.
 */
#define	MBTOM(how)	(how)
#define	M_DONTWAIT	M_NOWAIT
#define	M_TRYWAIT	M_WAITOK
#define	M_WAIT		M_WAITOK

/*
 * String names of mbuf-related UMA(9) and malloc(9) types.  Exposed to
 * !_KERNEL so that monitoring tools can look up the zones with
 * libmemstat(3).
 */
#define	MBUF_MEM_NAME		"mbuf"
#define	MBUF_CLUSTER_MEM_NAME	"mbuf_cluster"
#define	MBUF_PACKET_MEM_NAME	"mbuf_packet"
#define	MBUF_JUMBOP_MEM_NAME	"mbuf_jumbo_page"
#define	MBUF_JUMBO9_MEM_NAME	"mbuf_jumbo_9k"
#define	MBUF_JUMBO16_MEM_NAME	"mbuf_jumbo_16k"
#define	MBUF_TAG_MEM_NAME	"mbuf_tag"
#define	MBUF_EXTREFCNT_MEM_NAME	"mbuf_ext_refcnt"

#ifdef _KERNEL

#ifdef WITNESS
#define	MBUF_CHECKSLEEP(how) do {					\
	if (how == M_WAITOK)						\
		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,		\
		    "Sleeping in \"%s\"", __func__);			\
} while (0)
#else
#define	MBUF_CHECKSLEEP(how)
#endif

/*
 * Network buffer allocation API
 *
 * The rest of it is defined in kern/kern_mbuf.c
 */

extern uma_zone_t	zone_mbuf;
extern uma_zone_t	zone_clust;
extern uma_zone_t	zone_pack;
extern uma_zone_t	zone_jumbop;
extern uma_zone_t	zone_jumbo9;
extern uma_zone_t	zone_jumbo16;
extern uma_zone_t	zone_ext_refcnt;

static __inline struct mbuf	*m_getcl(int how, short type, int flags);
static __inline struct mbuf	*m_get(int how, short type);
static __inline struct mbuf	*m_gethdr(int how, short type);
static __inline struct mbuf	*m_getjcl(int how, short type, int flags,
				    int size);
static __inline struct mbuf	*m_getclr(int how, short type);	/* XXX */
static __inline int		 m_init(struct mbuf *m, uma_zone_t zone,
				    int size, int how, short type, int flags);
static __inline struct mbuf	*m_free(struct mbuf *m);
static __inline void		 m_clget(struct mbuf *m, int how);
static __inline void		*m_cljget(struct mbuf *m, int how, int size);
static __inline void		 m_chtype(struct mbuf *m, short new_type);
void				 mb_free_ext(struct mbuf *);
static __inline struct mbuf	*m_last(struct mbuf *m);
int				 m_pkthdr_init(struct mbuf *m, int how);

static __inline int
m_gettype(int size)
{
	int type;

	switch (size) {
	case MSIZE:
		type = EXT_MBUF;
		break;
	case MCLBYTES:
		type = EXT_CLUSTER;
		break;
#if MJUMPAGESIZE != MCLBYTES
	case MJUMPAGESIZE:
		type = EXT_JUMBOP;
		break;
#endif
	case MJUM9BYTES:
		type = EXT_JUMBO9;
		break;
	case MJUM16BYTES:
		type = EXT_JUMBO16;
		break;
	default:
		panic("%s: m_getjcl: invalid cluster size", __func__);
	}

	return (type);
}

static __inline uma_zone_t
m_getzone(int size)
{
	uma_zone_t zone;

	switch (size) {
	case MSIZE:
		zone = zone_mbuf;
		break;
	case MCLBYTES:
		zone = zone_clust;
		break;
#if MJUMPAGESIZE != MCLBYTES
	case MJUMPAGESIZE:
		zone = zone_jumbop;
		break;
#endif
	case MJUM9BYTES:
		zone = zone_jumbo9;
		break;
	case MJUM16BYTES:
		zone = zone_jumbo16;
		break;
	default:
		panic("%s: m_getjcl: invalid cluster type", __func__);
	}

	return (zone);
}

/*
 * Initialize an mbuf with linear storage.
 *
 * Inline because the consumer text overhead will be roughly the same to
 * initialize or call a function with this many parameters and M_PKTHDR
 * should go away with constant propagation for !MGETHDR.
 */
static __inline int
m_init(struct mbuf *m, uma_zone_t zone, int size, int how, short type,
    int flags)
{
	int error;

	m->m_next = NULL;
	m->m_nextpkt = NULL;
	m->m_data = m->m_dat;
	m->m_len = 0;
	m->m_flags = flags;
	m->m_type = type;
	if (flags & M_PKTHDR) {
		if ((error = m_pkthdr_init(m, how)) != 0)
			return (error);
	}

	return (0);
}

static __inline struct mbuf *
m_get(int how, short type)
{
	struct mb_args args;

	args.flags = 0;
	args.type = type;
	return ((struct mbuf *)(uma_zalloc_arg(zone_mbuf, &args, how)));
}

/*
 * XXX This should be deprecated, very little use.
 */
static __inline struct mbuf *
m_getclr(int how, short type)
{
	struct mbuf *m;
	struct mb_args args;

	args.flags = 0;
	args.type = type;
	m = uma_zalloc_arg(zone_mbuf, &args, how);
	if (m != NULL)
		bzero(m->m_data, MLEN);
	return (m);
}

static __inline struct mbuf *
m_gethdr(int how, short type)
{
	struct mb_args args;

	args.flags = M_PKTHDR;
	args.type = type;
	return ((struct mbuf *)(uma_zalloc_arg(zone_mbuf, &args, how)));
}

static __inline struct mbuf *
m_getcl(int how, short type, int flags)
{
	struct mb_args args;

	args.flags = flags;
	args.type = type;
	return ((struct mbuf *)(uma_zalloc_arg(zone_pack, &args, how)));
}

/*
 * m_getjcl() returns an mbuf with a cluster of the specified size attached.
 * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
 *
 * XXX: This is rather large, should be real function maybe.
 */
static __inline struct mbuf *
m_getjcl(int how, short type, int flags, int size)
{
	struct mb_args args;
	struct mbuf *m, *n;
	uma_zone_t zone;

	if (size == MCLBYTES)
		return m_getcl(how, type, flags);

	args.flags = flags;
	args.type = type;

	m = uma_zalloc_arg(zone_mbuf, &args, how);
	if (m == NULL)
		return (NULL);

	zone = m_getzone(size);
	n = uma_zalloc_arg(zone, m, how);
	if (n == NULL) {
		uma_zfree(zone_mbuf, m);
		return (NULL);
	}
	return (m);
}

static __inline void
m_free_fast(struct mbuf *m)
{
#ifdef INVARIANTS
	if (m->m_flags & M_PKTHDR)
		KASSERT(SLIST_EMPTY(&m->m_pkthdr.tags), ("doing fast free of mbuf with tags"));
#endif

	uma_zfree_arg(zone_mbuf, m, (void *)MB_NOTAGS);
}

static __inline struct mbuf *
m_free(struct mbuf *m)
{
	struct mbuf *n = m->m_next;

	if (m->m_flags & M_EXT)
		mb_free_ext(m);
	else if ((m->m_flags & M_NOFREE) == 0)
		uma_zfree(zone_mbuf, m);
	return (n);
}

static __inline void
m_clget(struct mbuf *m, int how)
{

	if (m->m_flags & M_EXT)
		printf("%s: %p mbuf already has cluster\n", __func__, m);
	m->m_ext.ext_buf = (char *)NULL;
	uma_zalloc_arg(zone_clust, m, how);
	/*
	 * On a cluster allocation failure, drain the packet zone and retry,
	 * we might be able to loosen a few clusters up on the drain.
	 */
	if ((how & M_NOWAIT) && (m->m_ext.ext_buf == NULL)) {
		zone_drain(zone_pack);
		uma_zalloc_arg(zone_clust, m, how);
	}
}

/*
 * m_cljget() is different from m_clget() as it can allocate clusters without
 * attaching them to an mbuf.  In that case the return value is the pointer
 * to the cluster of the requested size.  If an mbuf was specified, it gets
 * the cluster attached to it and the return value can be safely ignored.
 * For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
 */
static __inline void *
m_cljget(struct mbuf *m, int how, int size)
{
	uma_zone_t zone;

	if (m && m->m_flags & M_EXT)
		printf("%s: %p mbuf already has cluster\n", __func__, m);
	if (m != NULL)
		m->m_ext.ext_buf = NULL;

	zone = m_getzone(size);
	return (uma_zalloc_arg(zone, m, how));
}

static __inline void
m_cljset(struct mbuf *m, void *cl, int type)
{
	uma_zone_t zone;
	int size;

	switch (type) {
	case EXT_CLUSTER:
		size = MCLBYTES;
		zone = zone_clust;
		break;
#if MJUMPAGESIZE != MCLBYTES
	case EXT_JUMBOP:
		size = MJUMPAGESIZE;
		zone = zone_jumbop;
		break;
#endif
	case EXT_JUMBO9:
		size = MJUM9BYTES;
		zone = zone_jumbo9;
		break;
	case EXT_JUMBO16:
		size = MJUM16BYTES;
		zone = zone_jumbo16;
		break;
	default:
		panic("unknown cluster type");
		break;
	}

	m->m_data = m->m_ext.ext_buf = cl;
	m->m_ext.ext_free = m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL;
	m->m_ext.ext_size = size;
	m->m_ext.ext_type = type;
	m->m_ext.ref_cnt = uma_find_refcnt(zone, cl);
	m->m_flags |= M_EXT;

}

static __inline void
m_chtype(struct mbuf *m, short new_type)
{

	m->m_type = new_type;
}

static __inline struct mbuf *
m_last(struct mbuf *m)
{

	while (m->m_next)
		m = m->m_next;
	return (m);
}

extern void (*m_addr_chg_pf_p)(struct mbuf *m);

static __inline void
m_addr_changed(struct mbuf *m)
{

	if (m_addr_chg_pf_p)
		m_addr_chg_pf_p(m);
}

/*
 * mbuf, cluster, and external object allocation macros (for compatibility
 * purposes).
 */
#define	M_MOVE_PKTHDR(to, from)	m_move_pkthdr((to), (from))
#define	MGET(m, how, type)	((m) = m_get((how), (type)))
#define	MGETHDR(m, how, type)	((m) = m_gethdr((how), (type)))
#define	MCLGET(m, how)		m_clget((m), (how))
#define	MEXTADD(m, buf, size, free, arg1, arg2, flags, type)		\
    m_extadd((m), (caddr_t)(buf), (size), (free),(arg1),(arg2),(flags), (type))
#define	m_getm(m, len, how, type)					\
    m_getm2((m), (len), (how), (type), M_PKTHDR)

/*
 * Evaluate TRUE if it's safe to write to the mbuf m's data region (this can
 * be both the local data payload, or an external buffer area, depending on
 * whether M_EXT is set).
 */
#define	M_WRITABLE(m)	(!((m)->m_flags & M_RDONLY) &&			\
			 (!(((m)->m_flags & M_EXT)) ||			\
			 (*((m)->m_ext.ref_cnt) == 1)) )		\

/* Check if the supplied mbuf has a packet header, or else panic. */
#define	M_ASSERTPKTHDR(m)						\
	KASSERT((m) != NULL && (m)->m_flags & M_PKTHDR,			\
	    ("%s: no mbuf packet header!", __func__))

/*
 * Ensure that the supplied mbuf is a valid, non-free mbuf.
 *
 * XXX: Broken at the moment.  Need some UMA magic to make it work again.
 */
#define	M_ASSERTVALID(m)						\
	KASSERT((((struct mbuf *)m)->m_flags & 0) == 0,			\
	    ("%s: attempted use of a free mbuf!", __func__))

/*
 * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place an
 * object of the specified size at the end of the mbuf, longword aligned.
 */
#define	M_ALIGN(m, len) do {						\
	KASSERT(!((m)->m_flags & (M_PKTHDR|M_EXT)),			\
		("%s: M_ALIGN not normal mbuf", __func__));		\
	KASSERT((m)->m_data == (m)->m_dat,				\
		("%s: M_ALIGN not a virgin mbuf", __func__));		\
	(m)->m_data += (MLEN - (len)) & ~(sizeof(long) - 1);		\
} while (0)

/*
 * As above, for mbufs allocated with m_gethdr/MGETHDR or initialized by
 * M_DUP/MOVE_PKTHDR.
 */
#define	MH_ALIGN(m, len) do {						\
	KASSERT((m)->m_flags & M_PKTHDR && !((m)->m_flags & M_EXT),	\
		("%s: MH_ALIGN not PKTHDR mbuf", __func__));		\
	KASSERT((m)->m_data == (m)->m_pktdat,				\
		("%s: MH_ALIGN not a virgin mbuf", __func__));		\
	(m)->m_data += (MHLEN - (len)) & ~(sizeof(long) - 1);		\
} while (0)

/*
 * Compute the amount of space available before the current start of data in
 * an mbuf.
 *
 * The M_WRITABLE() is a temporary, conservative safety measure: the burden
 * of checking writability of the mbuf data area rests solely with the caller.
 */
#define	M_LEADINGSPACE(m)						\
	((m)->m_flags & M_EXT ?						\
	    (M_WRITABLE(m) ? (m)->m_data - (m)->m_ext.ext_buf : 0):	\
	    (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat :	\
	    (m)->m_data - (m)->m_dat)

/*
 * Compute the amount of space available after the end of data in an mbuf.
 *
 * The M_WRITABLE() is a temporary, conservative safety measure: the burden
 * of checking writability of the mbuf data area rests solely with the caller.
 */
#define	M_TRAILINGSPACE(m)						\
	((m)->m_flags & M_EXT ?						\
	    (M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size	\
		- ((m)->m_data + (m)->m_len) : 0) :			\
	    &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))

/*
 * Arrange to prepend space of size plen to mbuf m.  If a new mbuf must be
 * allocated, how specifies whether to wait.  If the allocation fails, the
 * original mbuf chain is freed and m is set to NULL.
 */
#define	M_PREPEND(m, plen, how) do {					\
	struct mbuf **_mmp = &(m);					\
	struct mbuf *_mm = *_mmp;					\
	int _mplen = (plen);						\
	int __mhow = (how);						\
									\
	MBUF_CHECKSLEEP(how);						\
	if (M_LEADINGSPACE(_mm) >= _mplen) {				\
		_mm->m_data -= _mplen;					\
		_mm->m_len += _mplen;					\
	} else								\
		_mm = m_prepend(_mm, _mplen, __mhow);			\
	if (_mm != NULL && _mm->m_flags & M_PKTHDR)			\
		_mm->m_pkthdr.len += _mplen;				\
	*_mmp = _mm;							\
} while (0)

/*
 * Change mbuf to new type.  This is a relatively expensive operation and
 * should be avoided.
 */
#define	MCHTYPE(m, t)	m_chtype((m), (t))

/* Length to m_copy to copy all. */
#define	M_COPYALL	1000000000

/* Compatibility with 4.3. */
#define	m_copy(m, o, l)	m_copym((m), (o), (l), M_DONTWAIT)

extern int		max_datalen;	/* MHLEN - max_hdr */
extern int		max_hdr;	/* Largest link + protocol header */
extern int		max_linkhdr;	/* Largest link-level header */
extern int		max_protohdr;	/* Largest protocol header */
extern struct mbstat	mbstat;		/* General mbuf stats/infos */
extern int		nmbclusters;	/* Maximum number of clusters */

struct uio;

void		 m_adj(struct mbuf *, int);
void		 m_align(struct mbuf *, int);
int		 m_apply(struct mbuf *, int, int,
		    int (*)(void *, void *, u_int), void *);
int		 m_append(struct mbuf *, int, c_caddr_t);
void		 m_cat(struct mbuf *, struct mbuf *);
void		 m_extadd(struct mbuf *, caddr_t, u_int,
		    void (*)(void *, void *), void *, void *, int, int);
struct mbuf	*m_collapse(struct mbuf *, int, int);
void		 m_copyback(struct mbuf *, int, int, c_caddr_t);
void		 m_copydata(const struct mbuf *, int, int, caddr_t);
struct mbuf	*m_copym(struct mbuf *, int, int, int);
struct mbuf	*m_copymdata(struct mbuf *, struct mbuf *,
		    int, int, int, int);
struct mbuf	*m_copypacket(struct mbuf *, int);
void		 m_copy_pkthdr(struct mbuf *, struct mbuf *);
struct mbuf	*m_copyup(struct mbuf *n, int len, int dstoff);
struct mbuf	*m_defrag(struct mbuf *, int);
void		 m_demote(struct mbuf *, int);
struct mbuf	*m_devget(char *, int, int, struct ifnet *,
		    void (*)(char *, caddr_t, u_int));
struct mbuf	*m_dup(struct mbuf *, int);
int		 m_dup_pkthdr(struct mbuf *, struct mbuf *, int);
u_int		 m_fixhdr(struct mbuf *);
struct mbuf	*m_fragment(struct mbuf *, int, int);
void		 m_freem(struct mbuf *);
struct mbuf	*m_getm2(struct mbuf *, int, int, short, int);
struct mbuf	*m_getptr(struct mbuf *, int, int *);
u_int		 m_length(struct mbuf *, struct mbuf **);
int		 m_mbuftouio(struct uio *, struct mbuf *, int);
void		 m_move_pkthdr(struct mbuf *, struct mbuf *);
struct mbuf	*m_prepend(struct mbuf *, int, int);
void		 m_print(const struct mbuf *, int);
struct mbuf	*m_pulldown(struct mbuf *, int, int, int *);
struct mbuf	*m_pullup(struct mbuf *, int);
int		m_sanity(struct mbuf *, int);
struct mbuf	*m_split(struct mbuf *, int, int);
struct mbuf	*m_uiotombuf(struct uio *, int, int, int, int);
struct mbuf	*m_unshare(struct mbuf *, int how);

/*-
 * Network 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 a
 * <cookie,type> pair that identifies it.  The cookie is a 32-bit unique
 * unsigned value used to identify a module or ABI.  By convention this value
 * is chosen as the date+time that the module is created, expressed as the
 * number of seconds since the epoch (e.g., using date -u +'%s').  The type
 * value is an ABI/module-specific value that identifies a particular
 * annotation and is private to the module.  For compatibility with systems
 * like OpenBSD that define packet tags w/o an ABI/module cookie, the value
 * PACKET_ABI_COMPAT is used to implement m_tag_get and m_tag_find
 * compatibility shim functions and several tag types are defined below.
 * Users that do not require compatibility should use a private cookie value
 * so that packet tag-related definitions can be maintained privately.
 *
 * Note that the packet tag returned by m_tag_alloc has the default memory
 * alignment implemented by malloc.  To reference private data one can use a
 * construct like:
 *
 *	struct m_tag *mtag = m_tag_alloc(...);
 *	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_alloc(...);
 *	struct m_tag *mtag = &p->tag;
 */

/*
 * Persistent tags stay with an mbuf until the mbuf is reclaimed.  Otherwise
 * tags are expected to ``vanish'' when they pass through a network
 * interface.  For most interfaces this happens normally as the tags are
 * reclaimed when the mbuf is free'd.  However in some special cases
 * reclaiming must be done manually.  An example is packets that pass through
 * the loopback interface.  Also, one must be careful to do this when
 * ``turning around'' packets (e.g., icmp_reflect).
 *
 * To mark a tag persistent bit-or this flag in when defining the tag id.
 * The tag will then be treated as described above.
 */
#define	MTAG_PERSISTENT				0x800

#define	PACKET_TAG_NONE				0  /* Nadda */

/* Packet tags for use with PACKET_ABI_COMPAT. */
#define	PACKET_TAG_IPSEC_IN_DONE		1  /* IPsec applied, in */
#define	PACKET_TAG_IPSEC_OUT_DONE		2  /* IPsec applied, out */
#define	PACKET_TAG_IPSEC_IN_CRYPTO_DONE		3  /* NIC IPsec crypto done */
#define	PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED	4  /* NIC IPsec crypto req'ed */
#define	PACKET_TAG_IPSEC_IN_COULD_DO_CRYPTO	5  /* NIC notifies IPsec */
#define	PACKET_TAG_IPSEC_PENDING_TDB		6  /* Reminder to do IPsec */
#define	PACKET_TAG_BRIDGE			7  /* Bridge processing done */
#define	PACKET_TAG_GIF				8  /* GIF processing done */
#define	PACKET_TAG_GRE				9  /* GRE processing done */
#define	PACKET_TAG_IN_PACKET_CHECKSUM		10 /* NIC checksumming done */
#define	PACKET_TAG_ENCAP			11 /* Encap.  processing */
#define	PACKET_TAG_IPSEC_SOCKET			12 /* IPSEC socket ref */
#define	PACKET_TAG_IPSEC_HISTORY		13 /* IPSEC history */
#define	PACKET_TAG_IPV6_INPUT			14 /* IPV6 input processing */
#define	PACKET_TAG_DUMMYNET			15 /* dummynet info */
#define	PACKET_TAG_DIVERT			17 /* divert info */
#define	PACKET_TAG_IPFORWARD			18 /* ipforward info */
#define	PACKET_TAG_MACLABEL	(19 | MTAG_PERSISTENT) /* MAC label */
#define	PACKET_TAG_PF				21 /* PF + ALTQ information */
#define	PACKET_TAG_RTSOCKFAM			25 /* rtsock sa family */
#define	PACKET_TAG_IPOPTIONS			27 /* Saved IP options */
#define	PACKET_TAG_CARP				28 /* CARP info */
#define	PACKET_TAG_IPSEC_NAT_T_PORTS		29 /* two uint16_t */
#define	PACKET_TAG_ND_OUTGOING			30 /* ND outgoing */

/* Specific cookies and tags. */

/* Packet tag routines. */
struct m_tag	*m_tag_alloc(u_int32_t, int, int, int);
void		 m_tag_delete(struct mbuf *, struct m_tag *);
void		 m_tag_delete_chain(struct mbuf *, struct m_tag *);
void		 m_tag_free_default(struct m_tag *);
struct m_tag	*m_tag_locate(struct mbuf *, u_int32_t, int, struct m_tag *);
struct m_tag	*m_tag_copy(struct m_tag *, int);
int		 m_tag_copy_chain(struct mbuf *, struct mbuf *, int);
void		 m_tag_delete_nonpersistent(struct mbuf *);

/*
 * Initialize the list of tags associated with an mbuf.
 */
static __inline void
m_tag_init(struct mbuf *m)
{

	SLIST_INIT(&m->m_pkthdr.tags);
}

/*
 * Set up the contents of a tag.  Note that this does not fill in the free
 * method; the caller is expected to do that.
 *
 * XXX probably should be called m_tag_init, but that was already taken.
 */
static __inline void
m_tag_setup(struct m_tag *t, u_int32_t cookie, int type, int len)
{

	t->m_tag_id = type;
	t->m_tag_len = len;
	t->m_tag_cookie = cookie;
}

/*
 * Reclaim resources associated with a tag.
 */
static __inline void
m_tag_free(struct m_tag *t)
{

	(*t->m_tag_free)(t);
}

/*
 * Return the first tag associated with an mbuf.
 */
static __inline struct m_tag *
m_tag_first(struct mbuf *m)
{

	return (SLIST_FIRST(&m->m_pkthdr.tags));
}

/*
 * Return the next tag in the list of tags associated with an mbuf.
 */
static __inline struct m_tag *
m_tag_next(struct mbuf *m, struct m_tag *t)
{

	return (SLIST_NEXT(t, m_tag_link));
}

/*
 * Prepend a tag to the list of tags associated with an mbuf.
 */
static __inline void
m_tag_prepend(struct mbuf *m, struct m_tag *t)
{

	SLIST_INSERT_HEAD(&m->m_pkthdr.tags, t, m_tag_link);
}

/*
 * Unlink a tag from the list of tags associated with an mbuf.
 */
static __inline void
m_tag_unlink(struct mbuf *m, struct m_tag *t)
{

	SLIST_REMOVE(&m->m_pkthdr.tags, t, m_tag, m_tag_link);
}

/* These are for OpenBSD compatibility. */
#define	MTAG_ABI_COMPAT		0		/* compatibility ABI */

static __inline struct m_tag *
m_tag_get(int type, int length, int wait)
{
	return (m_tag_alloc(MTAG_ABI_COMPAT, type, length, wait));
}

static __inline struct m_tag *
m_tag_find(struct mbuf *m, int type, struct m_tag *start)
{
	return (SLIST_EMPTY(&m->m_pkthdr.tags) ? (struct m_tag *)NULL :
	    m_tag_locate(m, MTAG_ABI_COMPAT, type, start));
}

/* XXX temporary FIB methods probably eventually use tags.*/
#define M_FIBSHIFT    28
#define M_FIBMASK	0x0F

/* get the fib from an mbuf and if it is not set, return the default */
#define M_GETFIB(_m) \
    ((((_m)->m_flags & M_FIB) >> M_FIBSHIFT) & M_FIBMASK)

#define M_SETFIB(_m, _fib) do {						\
	_m->m_flags &= ~M_FIB;					   	\
	_m->m_flags |= (((_fib) << M_FIBSHIFT) & M_FIB);  \
} while (0)

#endif /* _KERNEL */

#ifdef MBUF_PROFILING
 void m_profile(struct mbuf *m);
 #define M_PROFILE(m) m_profile(m)
#else
 #define M_PROFILE(m)
#endif

#endif /* !_SYS_MBUF_H_ */


code:
/*-
 * Copyright (c) 2000, 2001 Boris Popov
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/mchain.h 206361 2010-04-07 16:50:38Z joel $
 */
#ifndef _SYS_MCHAIN_H_
#define _SYS_MCHAIN_H_

#ifdef _KERNEL

/*
 * Type of copy for mb_{put|get}_mem()
 */
#define	MB_MSYSTEM	0		/* use bcopy() */
#define	MB_MUSER	1		/* use copyin()/copyout() */
#define	MB_MINLINE	2		/* use an inline copy loop */
#define	MB_MZERO	3		/* bzero(), mb_put_mem only */
#define	MB_MCUSTOM	4		/* use an user defined function */

struct mbuf;
struct mbchain;

typedef int mb_copy_t(struct mbchain *mbp, c_caddr_t src, caddr_t dst,
    size_t *srclen, size_t *dstlen);

struct mbchain {
	struct mbuf *	mb_top;		/* head of mbufs chain */
	struct mbuf * 	mb_cur;		/* current mbuf */
	int		mb_mleft;	/* free space in the current mbuf */
	int		mb_count;	/* total number of bytes */
	mb_copy_t *	mb_copy;	/* user defined copy function */
	void *		mb_udata;	/* user data */
};

struct mdchain {
	struct mbuf *	md_top;		/* head of mbufs chain */
	struct mbuf * 	md_cur;		/* current mbuf */
	u_char *	md_pos;		/* offset in the current mbuf */
};

int  mb_init(struct mbchain *mbp);
void mb_initm(struct mbchain *mbp, struct mbuf *m);
void mb_done(struct mbchain *mbp);
struct mbuf *mb_detach(struct mbchain *mbp);
int  mb_fixhdr(struct mbchain *mbp);
caddr_t mb_reserve(struct mbchain *mbp, int size);

int  mb_put_uint8(struct mbchain *mbp, u_int8_t x);
int  mb_put_uint16be(struct mbchain *mbp, u_int16_t x);
int  mb_put_uint16le(struct mbchain *mbp, u_int16_t x);
int  mb_put_uint32be(struct mbchain *mbp, u_int32_t x);
int  mb_put_uint32le(struct mbchain *mbp, u_int32_t x);
int  mb_put_int64be(struct mbchain *mbp, int64_t x);
int  mb_put_int64le(struct mbchain *mbp, int64_t x);
int  mb_put_mem(struct mbchain *mbp, c_caddr_t source, int size, int type);
int  mb_put_mbuf(struct mbchain *mbp, struct mbuf *m);
int  mb_put_uio(struct mbchain *mbp, struct uio *uiop, int size);

int  md_init(struct mdchain *mdp);
void md_initm(struct mdchain *mbp, struct mbuf *m);
void md_done(struct mdchain *mdp);
void md_append_record(struct mdchain *mdp, struct mbuf *top);
int  md_next_record(struct mdchain *mdp);
int  md_get_uint8(struct mdchain *mdp, u_int8_t *x);
int  md_get_uint16(struct mdchain *mdp, u_int16_t *x);
int  md_get_uint16le(struct mdchain *mdp, u_int16_t *x);
int  md_get_uint16be(struct mdchain *mdp, u_int16_t *x);
int  md_get_uint32(struct mdchain *mdp, u_int32_t *x);
int  md_get_uint32be(struct mdchain *mdp, u_int32_t *x);
int  md_get_uint32le(struct mdchain *mdp, u_int32_t *x);
int  md_get_int64(struct mdchain *mdp, int64_t *x);
int  md_get_int64be(struct mdchain *mdp, int64_t *x);
int  md_get_int64le(struct mdchain *mdp, int64_t *x);
int  md_get_mem(struct mdchain *mdp, caddr_t target, int size, int type);
int  md_get_mbuf(struct mdchain *mdp, int size, struct mbuf **m);
int  md_get_uio(struct mdchain *mdp, struct uio *uiop, int size);

#endif	/* ifdef _KERNEL */

#endif	/* !_SYS_MCHAIN_H_ */


code:
/* MD4.H - header file for MD4C.C
 * $FreeBSD: release/9.0.0/sys/sys/md4.h 139825 2005-01-07 02:29:27Z imp $
 */

/*-
   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD4 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.
   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD4 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.
 */

#ifndef _MD4_H_
#define _MD4_H_
/* MD4 context. */
typedef struct MD4Context {
  u_int32_t state[4];	/* state (ABCD) */
  u_int32_t count[2];	/* number of bits, modulo 2^64 (lsb first) */
  unsigned char buffer[64];	/* input buffer */
} MD4_CTX;

#include <sys/cdefs.h>

__BEGIN_DECLS
void   MD4Init(MD4_CTX *);
void   MD4Update(MD4_CTX *, const unsigned char *, unsigned int);
void   MD4Pad(MD4_CTX *);
void   MD4Final(unsigned char [16], MD4_CTX *);
char * MD4End(MD4_CTX *, char *);
char * MD4File(const char *, char *);
char * MD4Data(const unsigned char *, unsigned int, char *);
__END_DECLS

#endif /* _MD4_H_ */


code:
/* MD5.H - header file for MD5C.C
 * $FreeBSD: release/9.0.0/sys/sys/md5.h 156752 2006-03-15 19:47:12Z andre $
 */

/*-
 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.

License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.

License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.

RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this
documentation and/or software.
 */

#ifndef _SYS_MD5_H_
#define _SYS_MD5_H_

#define MD5_BLOCK_LENGTH		64
#define MD5_DIGEST_LENGTH		16
#define MD5_DIGEST_STRING_LENGTH	(MD5_DIGEST_LENGTH * 2 + 1)

/* MD5 context. */
typedef struct MD5Context {
  u_int32_t state[4];	/* state (ABCD) */
  u_int32_t count[2];	/* number of bits, modulo 2^64 (lsb first) */
  unsigned char buffer[64];	/* input buffer */
} MD5_CTX;

#include <sys/cdefs.h>

__BEGIN_DECLS
void   MD5Init (MD5_CTX *);
void   MD5Update (MD5_CTX *, const void *, unsigned int);
void   MD5Final (unsigned char [16], MD5_CTX *);
char * MD5End(MD5_CTX *, char *);
char * MD5File(const char *, char *);
char * MD5FileChunk(const char *, char *, off_t, off_t);
char * MD5Data(const void *, unsigned int, char *);
__END_DECLS
#endif /* _SYS_MD5_H_ */


code:
/*-
 * Copyright (c) 1988 University of Utah.
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * the Systems Programming Group of the University of Utah Computer
 * Science Department.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * from: Utah $Hdr: fdioctl.h 1.1 90/07/09$
 *
 *	@(#)vnioctl.h	8.1 (Berkeley) 6/10/93
 *
 * From: src/sys/sys/vnioctl.h,v 1.4
 *
 * $FreeBSD: release/9.0.0/sys/sys/mdioctl.h 152309 2005-11-11 11:31:23Z pjd $
 */

#ifndef _SYS_MDIOCTL_H_
#define _SYS_MDIOCTL_H_

enum md_types {MD_MALLOC, MD_PRELOAD, MD_VNODE, MD_SWAP};

/*
 * Ioctl definitions for memory disk pseudo-device.
 */

#define MDNPAD		97
struct md_ioctl {
	unsigned	md_version;	/* Structure layout version */
	unsigned	md_unit;	/* unit number */
	enum md_types	md_type ;	/* type of disk */
	char		*md_file;	/* pathname of file to mount */
	off_t		md_mediasize;	/* size of disk in bytes */
	unsigned	md_sectorsize;	/* sectorsize */
	unsigned	md_options;	/* options */
	u_int64_t	md_base;	/* base address */
	int		md_fwheads;	/* firmware heads */
	int		md_fwsectors;	/* firmware sectors */
	int		md_pad[MDNPAD];	/* padding for future ideas */
};

#define MD_NAME		"md"
#define MDCTL_NAME	"mdctl"
#define MDIOVERSION	0

/*
 * Before you can use a unit, it must be configured with MDIOCSET.
 * The configuration persists across opens and closes of the device;
 * an MDIOCCLR must be used to reset a configuration.  An attempt to
 * MDIOCSET an already active unit will return EBUSY.
 */

#define MDIOCATTACH	_IOWR('m', 0, struct md_ioctl)	/* attach disk */
#define MDIOCDETACH	_IOWR('m', 1, struct md_ioctl)	/* detach disk */
#define MDIOCQUERY	_IOWR('m', 2, struct md_ioctl)	/* query status */
#define MDIOCLIST	_IOWR('m', 3, struct md_ioctl)	/* query status */

#define MD_CLUSTER	0x01	/* Don't cluster */
#define MD_RESERVE	0x02	/* Pre-reserve swap */
#define MD_AUTOUNIT	0x04	/* Assign next free unit */
#define MD_READONLY	0x08	/* Readonly mode */
#define MD_COMPRESS	0x10	/* Compression mode */
#define MD_FORCE	0x20	/* Don't try to prevent foot-shooting */
#define MD_ASYNC	0x40	/* Don't try to prevent foot-shooting */

#endif	/* _SYS_MDIOCTL_H_*/


code:
/*
 * Memory range attribute operations, peformed on /dev/mem
 *
 * $FreeBSD: release/9.0.0/sys/sys/memrange.h 217515 2011-01-17 22:58:28Z jkim $
 */

#ifndef _SYS_MEMRANGE_H_
#define	_SYS_MEMRANGE_H_

/* Memory range attributes */
#define MDF_UNCACHEABLE		(1<<0)	/* region not cached */
#define MDF_WRITECOMBINE	(1<<1)	/* region supports "write combine" action */
#define MDF_WRITETHROUGH	(1<<2)	/* write-through cached */
#define MDF_WRITEBACK		(1<<3)	/* write-back cached */
#define MDF_WRITEPROTECT	(1<<4)	/* read-only region */
#define MDF_UNKNOWN		(1<<5)	/* any state we don't understand */
#define MDF_ATTRMASK		(0x00ffffff)

#define MDF_FIXBASE		(1<<24)	/* fixed base */
#define MDF_FIXLEN		(1<<25)	/* fixed length */
#define MDF_FIRMWARE		(1<<26)	/* set by firmware (XXX not useful?) */
#define MDF_ACTIVE		(1<<27)	/* currently active */
#define MDF_BOGUS		(1<<28)	/* we don't like it */
#define MDF_FIXACTIVE		(1<<29)	/* can't be turned off */
#define MDF_BUSY		(1<<30)	/* range is in use */
#define MDF_FORCE		(1<<31)	/* force risky changes */

struct mem_range_desc
{
	u_int64_t	mr_base;
	u_int64_t	mr_len;
	int		mr_flags;
	char		mr_owner[8];
};

struct mem_range_op
{
	struct mem_range_desc	*mo_desc;
	int			mo_arg[2];
#define MEMRANGE_SET_UPDATE	0
#define MEMRANGE_SET_REMOVE	1
	/* XXX want a flag that says "set and undo when I exit" */
};

#define MEMRANGE_GET	_IOWR('m', 50, struct mem_range_op)
#define MEMRANGE_SET	_IOW('m', 51, struct mem_range_op)

#ifdef _KERNEL

MALLOC_DECLARE(M_MEMDESC);

struct mem_range_softc;
struct mem_range_ops
{
	void	(*init)(struct mem_range_softc *sc);
	int	(*set)(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg);
    	void	(*initAP)(struct mem_range_softc *sc);
    	void	(*reinit)(struct mem_range_softc *sc);
};

struct mem_range_softc
{
	struct mem_range_ops	*mr_op;
	int			mr_cap;
	int			mr_ndesc;
	struct mem_range_desc 	*mr_desc;
};

extern struct mem_range_softc mem_range_softc;

extern void	mem_range_init(void);
extern void	mem_range_destroy(void);

extern int	mem_range_attr_get(struct mem_range_desc *mrd, int *arg);
extern int	mem_range_attr_set(struct mem_range_desc *mrd, int *arg);

#endif /* _KERNEL */

#endif /* _SYS_MEMRANGE_H_ */


code:
/*-
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)mman.h	8.2 (Berkeley) 1/9/95
 * $FreeBSD: release/9.0.0/sys/sys/mman.h 211937 2010-08-28 16:57:07Z alc $
 */

#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_

#include <sys/cdefs.h>
#include <sys/_types.h>

#if __BSD_VISIBLE
/*
 * Inheritance for minherit()
 */
#define INHERIT_SHARE	0
#define INHERIT_COPY	1
#define INHERIT_NONE	2
#endif

/*
 * Protections are chosen from these bits, or-ed together
 */
#define	PROT_NONE	0x00	/* no permissions */
#define	PROT_READ	0x01	/* pages can be read */
#define	PROT_WRITE	0x02	/* pages can be written */
#define	PROT_EXEC	0x04	/* pages can be executed */

/*
 * Flags contain sharing type and options.
 * Sharing types; choose one.
 */
#define	MAP_SHARED	0x0001		/* share changes */
#define	MAP_PRIVATE	0x0002		/* changes are private */
#define	MAP_SELF	0x80000	/* map self */
#if __BSD_VISIBLE
#define	MAP_COPY	MAP_PRIVATE	/* Obsolete */
#endif

/*
 * Other flags
 */
#define	MAP_FIXED	 0x0010	/* map addr must be exactly as requested */

#if __BSD_VISIBLE
#define	MAP_RENAME	 0x0020	/* Sun: rename private pages to file */
#define	MAP_NORESERVE	 0x0040	/* Sun: don't reserve needed swap area */
#define	MAP_RESERVED0080 0x0080	/* previously misimplemented MAP_INHERIT */
#define	MAP_RESERVED0100 0x0100	/* previously unimplemented MAP_NOEXTEND */
#define	MAP_HASSEMAPHORE 0x0200	/* region may contain semaphores */
#define	MAP_STACK	 0x0400	/* region grows down, like a stack */
#define	MAP_NOSYNC	 0x0800 /* page to but do not sync underlying file */

/*
 * Mapping type
 */
#define	MAP_FILE	 0x0000	/* map from file (default) */
#define	MAP_ANON	 0x1000	/* allocated from memory, swap space */
#ifndef _KERNEL
#define	MAP_ANONYMOUS	 MAP_ANON /* For compatibility. */
#endif /* !_KERNEL */

/*
 * Extended flags
 */
#define	MAP_NOCORE	 0x00020000 /* dont include these pages in a coredump */
#define	MAP_PREFAULT_READ 0x00040000 /* prefault mapping for reading */
#endif /* __BSD_VISIBLE */

#if __POSIX_VISIBLE >= 199309
/*
 * Process memory locking
 */
#define MCL_CURRENT	0x0001	/* Lock only current memory */
#define MCL_FUTURE	0x0002	/* Lock all future memory as well */
#endif

/*
 * Error return from mmap()
 */
#define MAP_FAILED	((void *)-1)

/*
 * msync() flags
 */
#define	MS_SYNC		0x0000	/* msync synchronously */
#define MS_ASYNC	0x0001	/* return immediately */
#define MS_INVALIDATE	0x0002	/* invalidate all cached data */

/*
 * Advice to madvise
 */
#define	_MADV_NORMAL	0	/* no further special treatment */
#define	_MADV_RANDOM	1	/* expect random page references */
#define	_MADV_SEQUENTIAL 2	/* expect sequential page references */
#define	_MADV_WILLNEED	3	/* will need these pages */
#define	_MADV_DONTNEED	4	/* dont need these pages */

#if __BSD_VISIBLE
#define	MADV_NORMAL	_MADV_NORMAL
#define	MADV_RANDOM	_MADV_RANDOM
#define	MADV_SEQUENTIAL _MADV_SEQUENTIAL
#define	MADV_WILLNEED	_MADV_WILLNEED
#define	MADV_DONTNEED	_MADV_DONTNEED
#define	MADV_FREE	5	/* dont need these pages, and junk contents */
#define	MADV_NOSYNC	6	/* try to avoid flushes to physical media */
#define	MADV_AUTOSYNC	7	/* revert to default flushing strategy */
#define	MADV_NOCORE	8	/* do not include these pages in a core file */
#define	MADV_CORE	9	/* revert to including pages in a core file */
#define	MADV_PROTECT	10	/* protect process from pageout kill */

/*
 * Return bits from mincore
 */
#define	MINCORE_INCORE	 	 0x1 /* Page is incore */
#define	MINCORE_REFERENCED	 0x2 /* Page has been referenced by us */
#define	MINCORE_MODIFIED	 0x4 /* Page has been modified by us */
#define	MINCORE_REFERENCED_OTHER 0x8 /* Page has been referenced */
#define	MINCORE_MODIFIED_OTHER	0x10 /* Page has been modified */
#define	MINCORE_SUPER		0x20 /* Page is a "super" page */

/*
 * Anonymous object constant for shm_open().
 */
#define	SHM_ANON		((char *)1)
#endif /* __BSD_VISIBLE */

/*
 * XXX missing POSIX_TYPED_MEM_* macros and
 * posix_typed_mem_info structure.
 */
#if __POSIX_VISIBLE >= 200112
#define	POSIX_MADV_NORMAL	_MADV_NORMAL
#define	POSIX_MADV_RANDOM	_MADV_RANDOM
#define	POSIX_MADV_SEQUENTIAL	_MADV_SEQUENTIAL
#define	POSIX_MADV_WILLNEED	_MADV_WILLNEED
#define	POSIX_MADV_DONTNEED	_MADV_DONTNEED
#endif

#ifndef _MODE_T_DECLARED
typedef	__mode_t	mode_t;
#define	_MODE_T_DECLARED
#endif

#ifndef _OFF_T_DECLARED
typedef	__off_t		off_t;
#define	_OFF_T_DECLARED
#endif

#ifndef _SIZE_T_DECLARED
typedef	__size_t	size_t;
#define	_SIZE_T_DECLARED
#endif

#ifdef _KERNEL
#include <vm/vm.h>

struct shmfd {
	size_t		shm_size;
	vm_object_t	shm_object;
	int		shm_refs;
	uid_t		shm_uid;
	gid_t		shm_gid;
	mode_t		shm_mode;

	/*
	 * Values maintained solely to make this a better-behaved file
	 * descriptor for fstat() to run on.
	 */
	struct timespec	shm_atime;
	struct timespec	shm_mtime;
	struct timespec	shm_ctime;
	struct timespec	shm_birthtime;

	struct label	*shm_label;		/* MAC label */
};

int	shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
	    vm_object_t *obj);

#else /* !_KERNEL */

__BEGIN_DECLS
/*
 * XXX not yet implemented: posix_mem_offset(), posix_typed_mem_get_info(),
 * posix_typed_mem_open().
 */
#if __BSD_VISIBLE
int	getpagesizes(size_t *, int);
int	madvise(void *, size_t, int);
int	mincore(const void *, size_t, char *);
int	minherit(void *, size_t, int);
#endif
int	mlock(const void *, size_t);
#ifndef _MMAP_DECLARED
#define	_MMAP_DECLARED
void *	mmap(void *, size_t, int, int, int, off_t);
#endif
int	mprotect(const void *, size_t, int);
int	msync(void *, size_t, int);
int	munlock(const void *, size_t);
int	munmap(void *, size_t);
#if __POSIX_VISIBLE >= 200112
int	posix_madvise(void *, size_t, int);
#endif
#if __POSIX_VISIBLE >= 199309
int	mlockall(int);
int	munlockall(void);
int	shm_open(const char *, int, mode_t);
int	shm_unlink(const char *);
#endif
__END_DECLS

#endif /* !_KERNEL */

#endif /* !_SYS_MMAN_H_ */


code:
/*-
 * Copyright (c) 1997 Doug Rabson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/module.h 213716 2010-10-12 09:18:17Z kib $
 */

#ifndef _SYS_MODULE_H_
#define _SYS_MODULE_H_

/*
 * Module metadata types
 */
#define	MDT_DEPEND	1		/* argument is a module name */
#define	MDT_MODULE	2		/* module declaration */
#define	MDT_VERSION	3		/* module version(s) */

#define	MDT_STRUCT_VERSION	1	/* version of metadata structure */
#define	MDT_SETNAME	"modmetadata_set"

typedef enum modeventtype {
	MOD_LOAD,
	MOD_UNLOAD,
	MOD_SHUTDOWN,
	MOD_QUIESCE
} modeventtype_t;

typedef struct module *module_t;
typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);

/*
 * Struct for registering modules statically via SYSINIT.
 */
typedef struct moduledata {
	const char	*name;		/* module name */
	modeventhand_t  evhand;		/* event handler */
	void		*priv;		/* extra data */
} moduledata_t;

/*
 * A module can use this to report module specific data to the user via
 * kldstat(2).
 */
typedef union modspecific {
	int	intval;
	u_int	uintval;
	long	longval;
	u_long	ulongval;
} modspecific_t;

/*
 * Module dependency declarartion
 */
struct mod_depend {
	int	md_ver_minimum;
	int	md_ver_preferred;
	int	md_ver_maximum;
};

/*
 * Module version declaration
 */
struct mod_version {
	int	mv_version;
};

struct mod_metadata {
	int		md_version;	/* structure version MDTV_* */
	int		md_type;	/* type of entry MDT_* */
	void		*md_data;	/* specific data */
	const char	*md_cval;	/* common string label */
};

#ifdef	_KERNEL

#include <sys/linker_set.h>

#define	MODULE_METADATA(uniquifier, type, data, cval)			\
	static struct mod_metadata _mod_metadata##uniquifier = {	\
		MDT_STRUCT_VERSION,					\
		type,							\
		data,							\
		cval							\
	};								\
	DATA_SET(modmetadata_set, _mod_metadata##uniquifier)

#define	MODULE_DEPEND(module, mdepend, vmin, vpref, vmax)		\
	static struct mod_depend _##module##_depend_on_##mdepend = {	\
		vmin,							\
		vpref,							\
		vmax							\
	};								\
	MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND,	\
	    &_##module##_depend_on_##mdepend, #mdepend)

/*
 * Every kernel has a 'kernel' module with the version set to
 * __FreeBSD_version.  We embed a MODULE_DEPEND() inside every module
 * that depends on the 'kernel' module.  It uses the current value of
 * __FreeBSD_version as the minimum and preferred versions.  For the
 * maximum version it rounds the version up to the end of its branch
 * (i.e. M99999 for M.x).  This allows a module built on M.x to work
 * on M.y systems where y >= x, but fail on M.z systems where z < x.
 */
#define	MODULE_KERNEL_MAXVER	(roundup(__FreeBSD_version, 100000) - 1)

#define	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver)	\
	MODULE_DEPEND(name, kernel, __FreeBSD_version,			\
	    __FreeBSD_version, maxver);			\
	MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name);		\
	SYSINIT(name##module, sub, order, module_register_init, &data);	\
	struct __hack

#define	DECLARE_MODULE(name, data, sub, order)				\
	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)

/*
 * The module declared with DECLARE_MODULE_TIED can only be loaded
 * into the kernel with exactly the same __FreeBSD_version.
 *
 * Use it for modules that use kernel interfaces that are not stable
 * even on STABLE/X branches.
 */
#define	DECLARE_MODULE_TIED(name, data, sub, order)				\
	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)

#define	MODULE_VERSION(module, version)					\
	static struct mod_version _##module##_version = {		\
		version							\
	};								\
	MODULE_METADATA(_##module##_version, MDT_VERSION,		\
	    &_##module##_version, #module)

extern struct sx modules_sx;

#define	MOD_XLOCK	sx_xlock(&modules_sx)
#define	MOD_SLOCK	sx_slock(&modules_sx)
#define	MOD_XUNLOCK	sx_xunlock(&modules_sx)
#define	MOD_SUNLOCK	sx_sunlock(&modules_sx)
#define	MOD_LOCK_ASSERT	sx_assert(&modules_sx, SX_LOCKED)
#define	MOD_XLOCK_ASSERT	sx_assert(&modules_sx, SX_XLOCKED)

struct linker_file;

void	module_register_init(const void *);
int	module_register(const struct moduledata *, struct linker_file *);
module_t	module_lookupbyname(const char *);
module_t	module_lookupbyid(int);
int	module_quiesce(module_t);
void	module_reference(module_t);
void	module_release(module_t);
int	module_unload(module_t);
int	module_getid(module_t);
module_t	module_getfnext(module_t);
const char *	module_getname(module_t);
void	module_setspecific(module_t, modspecific_t *);
struct linker_file *module_file(module_t);

#ifdef	MOD_DEBUG
extern int mod_debug;
#define	MOD_DEBUG_REFS	1

#define	MOD_DPF(cat, args) do {						\
	if (mod_debug & MOD_DEBUG_##cat)				\
		printf(args);						\
} while (0)

#else	/* !MOD_DEBUG */

#define	MOD_DPF(cat, args)
#endif
#endif	/* _KERNEL */

#define	MAXMODNAME	32

struct module_stat {
	int		version;	/* set to sizeof(struct module_stat) */
	char		name[MAXMODNAME];
	int		refs;
	int		id;
	modspecific_t	data;
};

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
int	modnext(int _modid);
int	modfnext(int _modid);
int	modstat(int _modid, struct module_stat *_stat);
int	modfind(const char *_name);
__END_DECLS

#endif

#endif	/* !_SYS_MODULE_H_ */


code:
/*-
 * Copyright (c) 2010 Lawrence Stewart <lstewart@freebsd.org>
 * Copyright (c) 2010 The FreeBSD Foundation
 * All rights reserved.
 *
 * This software was developed by Lawrence Stewart while studying at the Centre
 * for Advanced Internet Architectures, Swinburne University of Technology, made
 * possible in part by grants from the FreeBSD Foundation and Cisco University
 * Research Program Fund at Community Foundation Silicon Valley.
 *
 * Portions of this software were developed at the Centre for Advanced
 * Internet Architectures, Swinburne University of Technology, Melbourne,
 * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/module_khelp.h 220560 2011-04-12 08:13:18Z lstewart $
 */

#ifndef _SYS_MODULE_KHELP_H_
#define _SYS_MODULE_KHELP_H_

/* XXXLAS: Needed for uma related typedefs. */
#include <vm/uma.h>

/* Helper flags. */
#define	HELPER_NEEDS_OSD	0x0001

struct helper {
	int (*mod_init) (void);
	int (*mod_destroy) (void);
#define	HELPER_NAME_MAXLEN 16
	char			h_name[HELPER_NAME_MAXLEN];
	uma_zone_t		h_zone;
	struct hookinfo		*h_hooks;
	uint32_t		h_nhooks;
	uint32_t		h_classes;
	int32_t			h_id;
	volatile uint32_t	h_refcount;
	uint16_t		h_flags;
	TAILQ_ENTRY(helper)	h_next;
};

struct khelp_modevent_data {
	char			name[HELPER_NAME_MAXLEN];
	struct helper		*helper;
	struct hookinfo		*hooks;
	int			nhooks;
	int			uma_zsize;
	uma_ctor		umactor;
	uma_dtor		umadtor;
};

#define	KHELP_DECLARE_MOD(hname, hdata, hhooks, version)		\
	static struct khelp_modevent_data kmd_##hname = {		\
		.name = #hname,						\
		.helper = hdata						\
		.hooks = hhooks,					\
		.nhooks = sizeof(hhooks) / sizeof(hhooks[0]),		\
	};								\
	static moduledata_t h_##hname = {				\
		.name = #hname,						\
		.evhand = khelp_modevent,				\
		.priv = &kmd_##hname					\
	};								\
	DECLARE_MODULE(hname, h_##hname, SI_SUB_PROTO_IFATTACHDOMAIN,	\
	    SI_ORDER_ANY);						\
	MODULE_VERSION(hname, version)

#define	KHELP_DECLARE_MOD_UMA(hname, hdata, hhooks, version, size, ctor, dtor) \
	static struct khelp_modevent_data kmd_##hname = {		\
		.name = #hname,						\
		.helper = hdata,					\
		.hooks = hhooks,					\
		.nhooks = sizeof(hhooks) / sizeof(hhooks[0]),		\
		.uma_zsize = size,					\
		.umactor = ctor,					\
		.umadtor = dtor						\
	};								\
	static moduledata_t h_##hname = {				\
		.name = #hname,						\
		.evhand = khelp_modevent,				\
		.priv = &kmd_##hname					\
	};								\
	DECLARE_MODULE(hname, h_##hname, SI_SUB_PROTO_IFATTACHDOMAIN,	\
	    SI_ORDER_ANY);						\
	MODULE_VERSION(hname, version)

int	khelp_modevent(module_t mod, int type, void *data);

#endif /* _SYS_MODULE_KHELP_H_ */