#include <sys/sysctl.h>

sys/sysctl.h Kernel.framework

41 macros · 20 functions · 10 variables · 4 structs · 1 typedef

macroSYSCTL_HANDLER_ARGS

#define SYSCTL_HANDLER_ARGS (struct sysctl_oid *oidp __unused, void *arg1 __unused, int arg2 __unused,
	struct sysctl_req *req)

structsysctl_req

This describes the access space for a sysctl request. This is needed so that we can use the interface from the kernel or from user-space.
size 80, align 8
struct proc *p
intlock
user_addr_toldptrpointer to user supplied buffer
size_toldlenuser buffer length (also returned)
size_toldidxtotal data iteratively copied out
int (*)(struct sysctl_req *, const void *, size_t)oldfunc
user_addr_tnewptrbuffer containing new value
size_tnewlenlength of new value
size_tnewidxtotal data iteratively copied in
int (*)(struct sysctl_req *, void *, size_t)newfunc

structsysctl_oid_list

size 8, align 8
struct sysctl_oid *slh_firstfirst element

macroSYSCTL_OID_VERSION

#define SYSCTL_OID_VERSION 1
current OID structure version

structsysctl_oid

This describes one "oid" in the MIB tree. Potentially more nodes can be hidden behind it, expanded by the handler. NOTES: We implement binary comparibility between CTLFLAG_OID2 and pre-CTLFLAG_OID2 structure in sysctl_register_oid() and in sysctl_unregister_oid() using the fact that the fields up to oid_fmt are unchanged, and that the field immediately following is on an alignment boundary following a pointer type and is also a pointer. This lets us get the previous size of the structure, and the copy-cut-off point, using the offsetof() language primitive, and these values are used in conjunction with the fact that earlier and future statically compiled sysctl_oid structures are declared via macros. This lets us overload the macros so that the addition of the CTLFLAG_OID2 in newly compiled code containing sysctl node declarations, subsequently allowing us to to avoid changing the KPI used for non-static (un)registration in KEXTs. Non CTLFLAG_OID2 based sysctls are deprecated and unavailable to non Intel platforms. This depends on the fact that people declare SYSCTLs, rather than declaring sysctl_oid structures. All new code should avoid declaring struct sysctl_oid's directly without the macros; the current risk for this is limited to losing your description field and ending up with a malloc'ed copy, as if it were a legacy binary static declaration via SYSCTL; in the future, we may deprecate access to a named structure type in third party code. Use the macros, or our code will end up with compile errors when that happens. Please try to include a long description of the field in any new sysctl declarations (all the macros support this). This field may be the only human readable documentation your users get for your sysctl.
size 80, align 8
struct sysctl_oid_list *oid_parent
unnamed struct at Kernel/sys/sysctl.h:246:2oid_link
struct sysctl_oid *sle_nextnext element
intoid_number
intoid_kind
void *oid_arg1
intoid_arg2
const char *oid_name
int (*)(struct sysctl_oid *, void *, int, struct sysctl_req *)oid_handler
const char *oid_fmt
const char *oid_descroffsetof() field / long description
intoid_version
intoid_refcnt

macroSYSCTL_IN

#define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l)

macroSYSCTL_OUT

#define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l)

typedefsysctl_handler_t

typedef int (* sysctl_handler_t) SYSCTL_HANDLER_ARGS

functionsysctl_handle_int

int sysctl_handle_int SYSCTL_HANDLER_ARGS
old interface

functionsysctl_handle_long

int sysctl_handle_long SYSCTL_HANDLER_ARGS
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Sysctl handler for a long (signed or unsigned) variable pointed to by arg1; arg2 is unused. Copies the value out to the request and, for writable OIDs, copies a new value in via sysctl_io_number. Used by SYSCTL_LONG/SYSCTL_ULONG. Returns EINVAL if arg1 is NULL, otherwise 0 or an error from the data transfer.

functionsysctl_handle_quad

int sysctl_handle_quad SYSCTL_HANDLER_ARGS
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Sysctl handler for a 64-bit (long long) variable pointed to by arg1; arg2 is unused. Copies the value out to the request and, for writable OIDs, copies a new value in via sysctl_io_number. Used by SYSCTL_QUAD. Returns EINVAL if arg1 is NULL, otherwise 0 or an error from the data transfer.

functionsysctl_handle_int2quad

int sysctl_handle_int2quad SYSCTL_HANDLER_ARGS
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Sysctl handler that exposes an int variable, pointed to by arg1, as a 64-bit quad; supports interfaces defined as quad-sized while the implementation still uses an int. Reads return the int widened to 64 bits; writes accept a 64-bit value and store it back as an int, returning ERANGE if the value is not representable. Returns EINVAL if arg1 is NULL.

functionsysctl_handle_string

int sysctl_handle_string SYSCTL_HANDLER_ARGS
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Sysctl handler for a NUL-terminated C string: arg1 points to the string, arg2 is the buffer size for a variable string or 0 for a read-only constant. Implemented via sysctl_io_string without truncation: reads copy the string including its NUL; writes require arg2 nonzero (else EPERM), reject new data of arg2 bytes or more with EINVAL, and NUL-terminate the stored value. Used by SYSCTL_STRING.

functionsysctl_handle_opaque

int sysctl_handle_opaque SYSCTL_HANDLER_ARGS
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Sysctl handler for opaque data: arg1 points to the object, arg2 is its size in bytes. Copies the bytes out to the request and, for writable OIDs, copies exactly the same number of bytes back in, via sysctl_io_opaque. Used by SYSCTL_OPAQUE and SYSCTL_STRUCT.

functionsysctl_io_number

int sysctl_io_number(
	struct sysctl_req *req,
	long long bigValue,
	size_t valueSize,
	void *pValue,
	int *changed
)
new interface

functionsysctl_io_string

int sysctl_io_string(
	struct sysctl_req *req,
	char *pValue,
	size_t valueSize,
	int trunc,
	int *changed
)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Performs the data transfer for a string-valued sysctl request. Copies the NUL-terminated string pValue out to the caller; if trunc is nonzero and the caller's buffer is smaller than the string, the result is truncated and NUL-terminated instead of failing with ENOMEM (preserving the semantics of library routines that truncate). If the request supplies a new value: returns EPERM if valueSize is 0 (read-only value), EINVAL if the new data does not fit (newlen >= valueSize); otherwise copies it in, forces NUL termination, and sets *changed to 1 if changed is non-NULL. Returns 0 or an error from the transfer.

functionsysctl_io_opaque

int sysctl_io_opaque(struct sysctl_req *req, void *pValue, size_t valueSize, int *changed)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Performs the data transfer for an opaque sysctl request: copies valueSize bytes from pValue out to the caller and, if the request supplies new data, copies valueSize bytes back into pValue and sets *changed to 1 if changed is non-NULL. Returns 0 or an error from the transfer (e.g. ENOMEM if the caller's buffer is too small).

functionsysctl_register_oid

void sysctl_register_oid(struct sysctl_oid *oidp)
These functions are used to add/remove an oid from the mib.

functionsysctl_unregister_oid

void sysctl_unregister_oid(struct sysctl_oid *oidp)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c
Removes a sysctl OID previously registered with sysctl_register_oid from the sysctl tree. Blocks until all in-flight references to the OID's handler have drained, so no handler invocation is in progress when it returns; new requests started after removal cannot find the node. Panics if the OID is marked CTLFLAG_PERMANENT. Kexts must unregister their OIDs before unloading.

macronvram_osenvironment

#define nvram_osenvironment "osenvironment"

functionsysctl_set_osenvironment

void sysctl_set_osenvironment(unsigned int size, const void* value)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_mib.c
Records the system's "osenvironment" value, copying the given bytes into a permanent kernel allocation backing the kern.osenvironment sysctl. Only the first call with a nonzero size takes effect; later calls are ignored. Called during boot from the device tree /chosen entry, or by IOKit on Intel systems.

functionsysctl_unblock_osenvironment

void sysctl_unblock_osenvironment(void)
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_mib.c
Marks the osenvironment value as initialized and wakes any threads blocked reading the kern.osenvironment sysctl before the value became available. Called once early boot has determined the value (or that none exists).

functionsysctl_register_fixed

__deprecated
void sysctl_register_fixed(void)
deprecated
Deprecated

macroSYSCTL_DECL

Declare an oid to allow child oids to be added to it.
#define SYSCTL_DECL(name) extern struct sysctl_oid_list sysctl_##name##_children

macroSYSCTL_STRUCT_INIT

This constructs a "raw" MIB oid.
#define SYSCTL_STRUCT_INIT(parent, nbr, name, kind, a1, a2, fn, fmt, desc) {
	    .oid_parent     = &sysctl_##parent##_children,
	    .oid_number     = nbr,
	    .oid_kind       = (int)(kind | CTLFLAG_OID2),
	    .oid_arg1       = a1,
	    .oid_arg2       = (int)(a2),
	    .oid_name       = #name,
	    .oid_handler    = fn,
	    .oid_fmt        = fmt,
	    .oid_descr      = desc,
	    .oid_version    = SYSCTL_OID_VERSION,
	}

macroSYSCTL_OID

#define SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr) __SYSCTL_OID(parent, nbr, name, kind, a1, a2, handler, fmt, descr)

macroSYSCTL_NODE

This constructs a node from which other oids can hang.
#define SYSCTL_NODE(parent, nbr, name, access, handler, descr) struct sysctl_oid_list sysctl_##parent##_##name##_children;
	SYSCTL_OID(parent, nbr, name, CTLTYPE_NODE|access,
	    &sysctl_##parent##_##name##_children, 0, handler, "N", descr)

macroSYSCTL_STRING

Oid for a string. len can be 0 to indicate '\0' termination.
#define SYSCTL_STRING(parent, nbr, name, access, arg, len, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|access,
	    arg, len, sysctl_handle_string, "A", descr)

macroSYSCTL_COMPAT_INT

#define SYSCTL_COMPAT_INT(parent, nbr, name, access, ptr, val, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, val, sysctl_handle_int, "I", descr)

macroSYSCTL_COMPAT_UINT

#define SYSCTL_COMPAT_UINT(parent, nbr, name, access, ptr, val, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, val, sysctl_handle_int, "IU", descr)

macroSYSCTL_INT

Oid for an int. If ptr is NULL, val is returned.
#define SYSCTL_INT(parent, nbr, name, access, ptr, val, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, val, sysctl_handle_int, "I", descr);
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(int),
	    "must be integer sized");

macroSYSCTL_UINT

Oid for an unsigned int. If ptr is NULL, val is returned.
#define SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, val, sysctl_handle_int, "IU", descr);
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(unsigned int),
	    "must be integer sized");

macroSYSCTL_LONG

Oid for a long. The pointer must be non NULL.
#define SYSCTL_LONG(parent, nbr, name, access, ptr, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, 0, sysctl_handle_long, "L", descr);
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(long),
	    "must be long sized");

macroSYSCTL_ULONG

Oid for a unsigned long. The pointer must be non NULL.
#define SYSCTL_ULONG(parent, nbr, name, access, ptr, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access,
	    ptr, 0, sysctl_handle_long, "LU", descr);
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(unsigned long),
	    "must be long sized");

macroSYSCTL_QUAD

Oid for a quad. The pointer must be non NULL.
#define SYSCTL_QUAD(parent, nbr, name, access, ptr, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_QUAD|access,
	    ptr, 0, sysctl_handle_quad, "Q", descr);
	_Static_assert(__builtin_constant_p(ptr) || sizeof(*(ptr)) == sizeof(long long),
	    "must be long long sized");

macroSYSCTL_OPAQUE

Oid for an opaque object. Specified by a pointer and a length.
#define SYSCTL_OPAQUE(parent, nbr, name, access, ptr, len, fmt, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access,
	        ptr, len, sysctl_handle_opaque, fmt, descr)

macroSYSCTL_STRUCT

Oid for a struct. Specified by a pointer and a type.
#define SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr) SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|access,
	    ptr, sizeof(struct type), sysctl_handle_opaque,
	    "S," #type, descr)

macroSYSCTL_PROC

Oid for a procedure. Specified by a pointer and an arg. CTLTYPE_* macros can determine how the "sysctl" tool deals with input (e.g. converting to int).
#define SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) SYSCTL_OID(parent, nbr, name, access,
	    ptr, arg, handler, fmt, descr)

structexperiment_spec

size 40, align 8
void *ptrptr to numeric experiment factor.
uint64_tmin_valueMin value that can be set via sysctl(3) (inclusive).
uint64_tmax_valueMax value that can be set via sysctl(3) (inclusive).
uint64_toriginal_valueFirst value that was overwritten via sysctl(3).
_Atomic(bool)modifiedHas this value ever been overwritten via sysctl(3)?

macroexperiment_factor_numeric_types

The handlers for the numeric types can be easily parameterized by type. So they're defined via an X macro.
#define experiment_factor_numeric_types X(uint, unsigned int)
    X(int, int)
    X(ulong, unsigned long)
    X(long, long)
    X(uint64, uint64_t)
    X(int64, int64_t)

macroX

#define X(experiment_factor_typename, _) int experiment_factor_##experiment_factor_typename##_handler SYSCTL_HANDLER_ARGS;

functionexperiment_factor_uint_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type unsigned int, declared with the EXPERIMENT_FACTOR_UINT macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

functionexperiment_factor_int_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type int, declared with the EXPERIMENT_FACTOR_INT macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

functionexperiment_factor_ulong_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type unsigned long, declared with the EXPERIMENT_FACTOR_ULONG macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

functionexperiment_factor_long_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type long, declared with the EXPERIMENT_FACTOR_LONG macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

functionexperiment_factor_uint64_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type uint64_t, declared with the EXPERIMENT_FACTOR_UINT64 macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

functionexperiment_factor_int64_handler

experiment_factor_numeric_types
claude-fable-5, 2026-08-24 · not from Apple sources · verified against xnu bsd/kern/kern_newsysctl.c, bsd/sys/sysctl.h
Sysctl handler backing trial-experiment factor OIDs of type int64_t, declared with the EXPERIMENT_FACTOR_INT64 macros; arg1 points to a struct experiment_spec describing the factor. Reads return the factor's current value. Writes are range-checked against the spec's inclusive min_value and max_value (EINVAL if outside), record the original value on first modification for the showexperiments lldb macro, and store the new value atomically. On release kernels, access requires the com.apple.private.kernel.read-write-trial-experiment-factors entitlement. Returns EINVAL if arg1 is NULL.

macroEXPERIMENT_FACTOR_UINT

#define EXPERIMENT_FACTOR_UINT(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned int), "must be integer sized");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_uint_handler, "IU", descr);

macroEXPERIMENT_FACTOR_INT

#define EXPERIMENT_FACTOR_INT(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(int), "must be integer sized");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_int_handler, "I", descr);

macroEXPERIMENT_FACTOR_ULONG

#define EXPERIMENT_FACTOR_ULONG(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned long), "must be long sized");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_ulong_handler, "LU", descr);

macroEXPERIMENT_FACTOR_LONG

#define EXPERIMENT_FACTOR_LONG(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(long), "must be long sized");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_long_handler, "L", descr);

macroEXPERIMENT_FACTOR_UINT64

#define EXPERIMENT_FACTOR_UINT64(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(uint64_t), "must be 8 bytes");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_uint64_handler, "QU", descr);

macroEXPERIMENT_FACTOR_INT64

#define EXPERIMENT_FACTOR_INT64(name, ptr, min, max, descr) __EXPERIMENT_FACTOR_SPEC(name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(int64_t), "must be 8 bytes");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, &_experiment_##name, 1, &experiment_factor_int64_handler, "Q", descr);

macroEXPERIMENT_FACTOR_PROC

Calls an user provided handler to read / write this factor. Entitlement checking will still be done by sysctl, but it's the callers responsibility to validate any new values. This factor will not be printed out via the showexperiments lldb macro.
#define EXPERIMENT_FACTOR_PROC(name, access, ptr, arg, handler, fmt, descr) _Static_assert(arg != 1, "arg can not be 1");
	SYSCTL_PROC(_kern_trial, OID_AUTO, name, access | CTLFLAG_ANYBODY | CTLFLAG_EXPERIMENT, ptr, arg, handler, fmt, descr);

macroEXPERIMENT_FACTOR_LEGACY_UINT

#define EXPERIMENT_FACTOR_LEGACY_UINT(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned int), "must be integer sized");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_uint_handler, "IU", descr);

macroEXPERIMENT_FACTOR_LEGACY_INT

#define EXPERIMENT_FACTOR_LEGACY_INT(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(int), "must be integer sized");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_int_handler, "I", descr);

macroEXPERIMENT_FACTOR_LEGACY_ULONG

#define EXPERIMENT_FACTOR_LEGACY_ULONG(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(unsigned long), "must be long sized");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_ulong_handler, "LU", descr);

macroEXPERIMENT_FACTOR_LEGACY_LONG

#define EXPERIMENT_FACTOR_LEGACY_LONG(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(long), "must be long sized");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_long_handler, "L", descr);

macroEXPERIMENT_FACTOR_LEGACY_UINT64

#define EXPERIMENT_FACTOR_LEGACY_UINT64(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(uint64_t), "must be 8 bytes");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_uint64_handler, "QU", descr);

macroEXPERIMENT_FACTOR_LEGACY_INT64

#define EXPERIMENT_FACTOR_LEGACY_INT64(parent, name, ptr, min, max, descr) __EXPERIMENT_FACTOR_LEGACY_SPEC(parent, name, ptr, min, max);
	_Static_assert(sizeof(*(ptr)) == sizeof(int64_t), "must be 8 bytes");
	SYSCTL_PROC(parent, OID_AUTO, name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, &experiment_##parent##_##name, 1, &experiment_factor_int64_handler, "Q", descr);

macroEXPERIMENT_FACTOR_LEGACY_PROC

Calls an user provided handler to read / write this factor. Entitlement checking will still be done by sysctl, but it's the callers responsibility to validate any new values. This factor will not be printed out via the showexperiments lldb macro.
#define EXPERIMENT_FACTOR_LEGACY_PROC(parent, name, access, ptr, arg, handler, fmt, descr) _Static_assert(arg != 1, "arg can not be 1");
	SYSCTL_PROC(parent, OID_AUTO, name, access | CTLFLAG_ANYBODY | CTLFLAG_LEGACY_EXPERIMENT, ptr, arg, handler, fmt, descr);

variablesysctl__children

extern struct sysctl_oid_list sysctl__children

macroSYSCTL_SKMEM

#define SYSCTL_SKMEM 0

macroSYSCTL_SKMEM_UPDATE_FIELD

#define SYSCTL_SKMEM_UPDATE_FIELD(field, value) 

macroSYSCTL_SKMEM_UPDATE_AT_OFFSET

#define SYSCTL_SKMEM_UPDATE_AT_OFFSET(offset, value) 

macroSYSCTL_SKMEM_INT

#define SYSCTL_SKMEM_INT(parent, oid, sysctl_name, access, ptr, offset, descr) SYSCTL_INT(parent, oid, sysctl_name, access, ptr, 0, descr)

macroSYSCTL_SKMEM_TCP_INT

#define SYSCTL_SKMEM_TCP_INT(oid, sysctl_name, access, variable_type, variable_name, initial_value, descr) variable_type variable_name = initial_value;
	SYSCTL_SKMEM_INT(_net_inet_tcp, oid, sysctl_name, access,
	                                 &variable_name, 0, descr)