Changeset View
Changeset View
Standalone View
Standalone View
sys/net/vnet.h
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
* for libkvm so that it can evaluate virtualized global variables. | * for libkvm so that it can evaluate virtualized global variables. | ||||
*/ | */ | ||||
#define VNET_SETNAME "set_vnet" | #define VNET_SETNAME "set_vnet" | ||||
#define VNET_SYMPREFIX "vnet_entry_" | #define VNET_SYMPREFIX "vnet_entry_" | ||||
#endif | #endif | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
/* | |||||
* Indicates whether this kernel was configured with vnet support or not. | |||||
* This will generally be used so that untied modules can do the right thing | |||||
* based on the linked-in kernel. | |||||
*/ | |||||
extern const int vimage_configured; | |||||
#define VNET_PCPUSTAT_DECLARE(type, name) \ | #define VNET_PCPUSTAT_DECLARE(type, name) \ | ||||
VNET_DECLARE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | VNET_DECLARE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | ||||
#define VNET_PCPUSTAT_DEFINE(type, name) \ | #define VNET_PCPUSTAT_DEFINE(type, name) \ | ||||
VNET_DEFINE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | VNET_DEFINE(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | ||||
#define VNET_PCPUSTAT_DEFINE_STATIC(type, name) \ | #define VNET_PCPUSTAT_DEFINE_STATIC(type, name) \ | ||||
VNET_DEFINE_STATIC(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | VNET_DEFINE_STATIC(counter_u64_t, name[sizeof(type) / sizeof(uint64_t)]) | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if (req->newptr) \ | ||||
COUNTER_ARRAY_ZERO(VNET(array), \ | COUNTER_ARRAY_ZERO(VNET(array), \ | ||||
sizeof(type) / sizeof(uint64_t)); \ | sizeof(type) / sizeof(uint64_t)); \ | ||||
return (SYSCTL_OUT(req, &s, sizeof(type))); \ | return (SYSCTL_OUT(req, &s, sizeof(type))); \ | ||||
} \ | } \ | ||||
SYSCTL_PROC(parent, nbr, name, CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RW, \ | SYSCTL_PROC(parent, nbr, name, CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RW, \ | ||||
NULL, 0, array ## _sysctl, "I", desc) | NULL, 0, array ## _sysctl, "I", desc) | ||||
#endif /* SYSCTL_OID */ | #endif /* SYSCTL_OID */ | ||||
/* | |||||
* Virtual sysinit mechanism, allowing network stack components to declare | |||||
* startup and shutdown methods to be run when virtual network stack | |||||
* instances are created and destroyed. | |||||
*/ | |||||
#include <sys/kernel.h> | |||||
/* | |||||
* SYSINIT/SYSUNINIT variants that provide per-vnet constructors and | |||||
* destructors. | |||||
*/ | |||||
struct vnet_sysinit { | |||||
enum sysinit_sub_id subsystem; | |||||
enum sysinit_elem_order order; | |||||
sysinit_cfunc_t func; | |||||
const void *arg; | |||||
TAILQ_ENTRY(vnet_sysinit) link; | |||||
}; | |||||
/* vnet_support shims */ | |||||
void vnet_dynamic_register_sysinit(void *arg); | |||||
void vnet_dynamic_register_sysuninit(void *arg); | |||||
void vnet_dynamic_deregister_sysinit(void *arg); | |||||
void vnet_dynamic_deregister_sysuninit(void *arg); | |||||
/* | |||||
* Virtual network stack allocator interfaces from the kernel linker. | |||||
*/ | |||||
void *vnet_data_alloc(int size); | |||||
void vnet_data_copy(void *start, int size); | |||||
void vnet_data_free(void *start_arg, int size); | |||||
#define VNET_NAME(n) vnet_entry_##n | |||||
#if defined(KLD_MODULE) && !defined(KLD_TIED) && !defined(VIMAGE) | |||||
/* | |||||
* For independent module builds, we trigger a version of VIMAGE macros that | |||||
* resolve safely (but slowly) based on vimage_configured. | |||||
*/ | |||||
#define VIMAGE 1 | |||||
#define VIMAGE_RUNTIME 1 | |||||
#endif | |||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/proc.h> /* for struct thread */ | #include <sys/proc.h> /* for struct thread */ | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
/* | /* | ||||
* Location of the kernel's 'set_vnet' linker set. | * Location of the kernel's 'set_vnet' linker set. | ||||
Show All 27 Lines | #define VNET_ASSERT(exp, msg) do { \ | ||||
if (!(exp)) \ | if (!(exp)) \ | ||||
panic msg; \ | panic msg; \ | ||||
} while (0) | } while (0) | ||||
#else | #else | ||||
#define VNET_ASSERT(exp, msg) do { \ | #define VNET_ASSERT(exp, msg) do { \ | ||||
} while (0) | } while (0) | ||||
#endif | #endif | ||||
#ifdef VIMAGE_RUNTIME | |||||
/* | |||||
* This should be used for things that need VNET_ASSERT that shouldn't panic | |||||
* if the underlying kernel wasn't compiled with VIMAGE. If we're not dealing | |||||
* with a kmod, or if we're unconditionally compiled with VIMAGE, this is a | |||||
* direct VNET_ASSERT. | |||||
*/ | |||||
#define VNET_RUNTIME_ASSERT(exp, msg) do { \ | |||||
if (vimage_configured) \ | |||||
VNET_ASSERT(exp, msg); \ | |||||
} while (0) | |||||
#define _CURVNET_SET_LPUSH(arg) \ | |||||
if (vimage_configured) { \ | |||||
curvnet = arg; \ | |||||
curthread->td_vnet_lpush = __func__; \ | |||||
} | |||||
#define _CURVNET_SET(arg) \ | |||||
if (vimage_configured) \ | |||||
curvnet = arg; | |||||
#define _CURVNET_RESTORE_LPUSH() \ | |||||
if (vimage_configured) { \ | |||||
curvnet = saved_vnet; \ | |||||
curthread->td_vnet_lpush = saved_vnet_lpush; \ | |||||
} | |||||
#define _CURVNET_RESTORE() \ | |||||
if (vimage_configured) \ | |||||
curvnet = saved_vnet; | |||||
#else | |||||
#define VNET_RUNTIME_ASSERT(exp, msg) VNET_ASSERT(exp, msg) | |||||
#define _CURVNET_SET_LPUSH(arg) \ | |||||
curvnet = arg; \ | |||||
curthread->td_vnet_lpush = __func__; | |||||
#define _CURVNET_SET(arg) \ | |||||
curvnet = arg; | |||||
#define _CURVNET_RESTORE_LPUSH() \ | |||||
curvnet = saved_vnet; \ | |||||
curthread->td_vnet_lpush = saved_vnet_lpush; | |||||
#define _CURVNET_RESTORE() \ | |||||
curvnet = saved_vnet; | |||||
#endif | |||||
#ifdef VNET_DEBUG | #ifdef VNET_DEBUG | ||||
void vnet_log_recursion(struct vnet *, const char *, int); | void vnet_log_recursion(struct vnet *, const char *, int); | ||||
#define CURVNET_SET_QUIET(arg) \ | #define CURVNET_SET_QUIET(arg) \ | ||||
VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \ | VNET_RUNTIME_ASSERT((arg) != NULL && \ | ||||
(arg)->vnet_magic_n == VNET_MAGIC_N, \ | |||||
("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p", \ | ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p", \ | ||||
__FILE__, __LINE__, __func__, curvnet, (arg))); \ | __FILE__, __LINE__, __func__, curvnet, (arg))); \ | ||||
struct vnet *saved_vnet = curvnet; \ | struct vnet *saved_vnet = curvnet; \ | ||||
const char *saved_vnet_lpush = curthread->td_vnet_lpush; \ | const char *saved_vnet_lpush = curthread->td_vnet_lpush; \ | ||||
curvnet = arg; \ | _CURVNET_SET_LPUSH(arg); | ||||
curthread->td_vnet_lpush = __func__; | |||||
#define CURVNET_SET_VERBOSE(arg) \ | #define CURVNET_SET_VERBOSE(arg) \ | ||||
CURVNET_SET_QUIET(arg) \ | CURVNET_SET_QUIET(arg) \ | ||||
if (saved_vnet) \ | if (saved_vnet && vimage_configured) \ | ||||
vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__); | vnet_log_recursion(saved_vnet, saved_vnet_lpush, __LINE__); | ||||
#define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) | #define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) | ||||
#define CURVNET_RESTORE() \ | #define CURVNET_RESTORE() \ | ||||
VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL || \ | VNET_RUNTIME_ASSERT(curvnet != NULL && (saved_vnet == NULL || \ | ||||
saved_vnet->vnet_magic_n == VNET_MAGIC_N), \ | saved_vnet->vnet_magic_n == VNET_MAGIC_N), \ | ||||
("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p", \ | ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p", \ | ||||
__FILE__, __LINE__, __func__, curvnet, saved_vnet)); \ | __FILE__, __LINE__, __func__, curvnet, saved_vnet)); \ | ||||
_CURVNET_RESTORE_LPUSH(); | |||||
if (vimage_configured) { \ | |||||
curvnet = saved_vnet; \ | curvnet = saved_vnet; \ | ||||
curthread->td_vnet_lpush = saved_vnet_lpush; | curthread->td_vnet_lpush = saved_vnet_lpush; \ | ||||
} | |||||
#else /* !VNET_DEBUG */ | #else /* !VNET_DEBUG */ | ||||
#define CURVNET_SET_QUIET(arg) \ | #define CURVNET_SET_QUIET(arg) \ | ||||
VNET_ASSERT((arg) != NULL && (arg)->vnet_magic_n == VNET_MAGIC_N, \ | VNET_RUNTIME_ASSERT((arg) != NULL && \ | ||||
(arg)->vnet_magic_n == VNET_MAGIC_N, \ | |||||
("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p", \ | ("CURVNET_SET at %s:%d %s() curvnet=%p vnet=%p", \ | ||||
__FILE__, __LINE__, __func__, curvnet, (arg))); \ | __FILE__, __LINE__, __func__, curvnet, (arg))); \ | ||||
struct vnet *saved_vnet = curvnet; \ | struct vnet *saved_vnet = curvnet; \ | ||||
curvnet = arg; | _CURVNET_SET(arg); | ||||
#define CURVNET_SET_VERBOSE(arg) \ | #define CURVNET_SET_VERBOSE(arg) \ | ||||
CURVNET_SET_QUIET(arg) | CURVNET_SET_QUIET(arg) | ||||
#define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) | #define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) | ||||
#define CURVNET_RESTORE() \ | #define CURVNET_RESTORE() \ | ||||
VNET_ASSERT(curvnet != NULL && (saved_vnet == NULL || \ | VNET_RUNTIME_ASSERT(curvnet != NULL && (saved_vnet == NULL || \ | ||||
saved_vnet->vnet_magic_n == VNET_MAGIC_N), \ | saved_vnet->vnet_magic_n == VNET_MAGIC_N), \ | ||||
("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p", \ | ("CURVNET_RESTORE at %s:%d %s() curvnet=%p saved_vnet=%p", \ | ||||
__FILE__, __LINE__, __func__, curvnet, saved_vnet)); \ | __FILE__, __LINE__, __func__, curvnet, saved_vnet)); \ | ||||
curvnet = saved_vnet; | _CURVNET_RESTORE(); | ||||
#endif /* VNET_DEBUG */ | #endif /* VNET_DEBUG */ | ||||
extern struct vnet *vnet0; | extern struct vnet *vnet0; | ||||
#ifdef VIMAGE_RUNTIME | |||||
#define IS_DEFAULT_VNET(arg) (vimage_configured && (arg) == vnet0) | |||||
#else | |||||
#define IS_DEFAULT_VNET(arg) ((arg) == vnet0) | #define IS_DEFAULT_VNET(arg) ((arg) == vnet0) | ||||
#endif | |||||
#define CRED_TO_VNET(cr) (cr)->cr_prison->pr_vnet | #define CRED_TO_VNET(cr) (cr)->cr_prison->pr_vnet | ||||
#define TD_TO_VNET(td) CRED_TO_VNET((td)->td_ucred) | #define TD_TO_VNET(td) CRED_TO_VNET((td)->td_ucred) | ||||
#define P_TO_VNET(p) CRED_TO_VNET((p)->p_ucred) | #define P_TO_VNET(p) CRED_TO_VNET((p)->p_ucred) | ||||
/* | /* | ||||
* Global linked list of all virtual network stacks, along with read locks to | * Global linked list of all virtual network stacks, along with read locks to | ||||
* access it. If a caller may sleep while accessing the list, it must use | * access it. If a caller may sleep while accessing the list, it must use | ||||
* the sleepable lock macros. | * the sleepable lock macros. | ||||
*/ | */ | ||||
LIST_HEAD(vnet_list_head, vnet); | LIST_HEAD(vnet_list_head, vnet); | ||||
extern struct vnet_list_head vnet_head; | extern struct vnet_list_head vnet_head; | ||||
extern struct rwlock vnet_rwlock; | extern struct rwlock vnet_rwlock; | ||||
extern struct sx vnet_sxlock; | extern struct sx vnet_sxlock; | ||||
#ifdef VIMAGE_RUNTIME | |||||
#define VNET_LIST_RLOCK() do { \ | |||||
if (vimage_configured) \ | |||||
sx_slock(&vnet_sxlock) \ | |||||
} while(0); | |||||
#define VNET_LIST_RLOCK_NOSLEEP() do { \ | |||||
if (vimage_configured) \ | |||||
rw_rlock(&vnet_rwlock) \ | |||||
} while(0); | |||||
#define VNET_LIST_RUNLOCK() do { \ | |||||
if (vimage_configured) \ | |||||
sx_sunlock(&vnet_sxlock) \ | |||||
} while(0); | |||||
#define VNET_LIST_RUNLOCK_NOSLEEP() do { \ | |||||
if (vimage_configured) \ | |||||
rw_runlock(&vnet_rwlock) \ | |||||
} while(0); | |||||
#else | |||||
#define VNET_LIST_RLOCK() sx_slock(&vnet_sxlock) | #define VNET_LIST_RLOCK() sx_slock(&vnet_sxlock) | ||||
#define VNET_LIST_RLOCK_NOSLEEP() rw_rlock(&vnet_rwlock) | #define VNET_LIST_RLOCK_NOSLEEP() rw_rlock(&vnet_rwlock) | ||||
#define VNET_LIST_RUNLOCK() sx_sunlock(&vnet_sxlock) | #define VNET_LIST_RUNLOCK() sx_sunlock(&vnet_sxlock) | ||||
#define VNET_LIST_RUNLOCK_NOSLEEP() rw_runlock(&vnet_rwlock) | #define VNET_LIST_RUNLOCK_NOSLEEP() rw_runlock(&vnet_rwlock) | ||||
#endif | |||||
/* | /* | ||||
* Iteration macros to walk the global list of virtual network stacks. | * Iteration macros to walk the global list of virtual network stacks. | ||||
*/ | */ | ||||
#define VNET_ITERATOR_DECL(arg) struct vnet *arg | #define VNET_ITERATOR_DECL(arg) struct vnet *arg | ||||
#ifdef VIMAGE_RUNTIME | |||||
#define VNET_FOREACH(arg) if (vimage_configured) \ | |||||
LIST_FOREACH((arg), &vnet_head, vnet_le) | |||||
#else | |||||
#define VNET_FOREACH(arg) LIST_FOREACH((arg), &vnet_head, vnet_le) | #define VNET_FOREACH(arg) LIST_FOREACH((arg), &vnet_head, vnet_le) | ||||
#endif | |||||
/* | /* | ||||
* Virtual network stack memory allocator, which allows global variables to | * Virtual network stack memory allocator, which allows global variables to | ||||
* be automatically instantiated for each network stack instance. | * be automatically instantiated for each network stack instance. | ||||
*/ | */ | ||||
#define VNET_NAME(n) vnet_entry_##n | |||||
#define VNET_DECLARE(t, n) extern t VNET_NAME(n) | #define VNET_DECLARE(t, n) extern t VNET_NAME(n) | ||||
/* struct _hack is to stop this from being used with static data */ | /* struct _hack is to stop this from being used with static data */ | ||||
#define VNET_DEFINE(t, n) \ | #define VNET_DEFINE(t, n) \ | ||||
struct _hack; t VNET_NAME(n) __section(VNET_SETNAME) __used | struct _hack; t VNET_NAME(n) __section(VNET_SETNAME) __used | ||||
#if defined(KLD_MODULE) && (defined(__aarch64__) || defined(__riscv)) | #if defined(KLD_MODULE) && (defined(__aarch64__) || defined(__riscv)) | ||||
/* | /* | ||||
* As with DPCPU_DEFINE_STATIC we are unable to mark this data as static | * As with DPCPU_DEFINE_STATIC we are unable to mark this data as static | ||||
* in modules on some architectures. | * in modules on some architectures. | ||||
Show All 10 Lines | |||||
#define _VNET(b, n) (*_VNET_PTR(b, n)) | #define _VNET(b, n) (*_VNET_PTR(b, n)) | ||||
/* | /* | ||||
* Virtualized global variable accessor macros. | * Virtualized global variable accessor macros. | ||||
*/ | */ | ||||
#define VNET_VNET_PTR(vnet, n) _VNET_PTR((vnet)->vnet_data_base, n) | #define VNET_VNET_PTR(vnet, n) _VNET_PTR((vnet)->vnet_data_base, n) | ||||
#define VNET_VNET(vnet, n) (*VNET_VNET_PTR((vnet), n)) | #define VNET_VNET(vnet, n) (*VNET_VNET_PTR((vnet), n)) | ||||
#ifdef VIMAGE_RUNTIME | |||||
#define VNET_PTR(n) \ | |||||
*(vimage_configured ? &VNET_VNET_PTR(curvnet, n) : &&(VNET_NAME(n))) | |||||
#define VNET(n) \ | |||||
*(vimage_configured ? &VNET_VNET(curvnet, n) : &(VNET_NAME(n))) | |||||
#else | |||||
#define VNET_PTR(n) VNET_VNET_PTR(curvnet, n) | #define VNET_PTR(n) VNET_VNET_PTR(curvnet, n) | ||||
#define VNET(n) VNET_VNET(curvnet, n) | #define VNET(n) VNET_VNET(curvnet, n) | ||||
#endif | |||||
#ifdef VIMAGE_RUNTIME | |||||
/* | /* | ||||
* Virtual network stack allocator interfaces from the kernel linker. | * These are provided by vnet_support.c and determine if they should invoke | ||||
* the SYSINIT/SYSUNINIT callbacks directly or instead dispatch the request | |||||
* through to the underlying vnet_{,de}register_* versions. | |||||
*/ | */ | ||||
void *vnet_data_alloc(int size); | #define _vnet_register_sysinit vnet_dynamic_register_sysinit | ||||
void vnet_data_copy(void *start, int size); | #define _vnet_deregister_sysinit vnet_dynamic_deregister_sysinit | ||||
void vnet_data_free(void *start_arg, int size); | #define _vnet_register_sysuninit vnet_dynamic_register_sysuninit | ||||
#define _vnet_deregister_sysuninit vnet_dynamic_deregister_sysuninit | |||||
#else | |||||
#define _vnet_register_sysinit vnet_register_sysinit | |||||
#define _vnet_deregister_sysinit vnet_deregister_sysinit | |||||
#define _vnet_register_sysuninit vnet_register_sysuninit | |||||
#define _vnet_deregister_sysuninit vnet_deregister_sysuninit | |||||
#endif | |||||
/* | |||||
* Virtual sysinit mechanism, allowing network stack components to declare | |||||
* startup and shutdown methods to be run when virtual network stack | |||||
* instances are created and destroyed. | |||||
*/ | |||||
#include <sys/kernel.h> | |||||
/* | |||||
* SYSINIT/SYSUNINIT variants that provide per-vnet constructors and | |||||
* destructors. | |||||
*/ | |||||
struct vnet_sysinit { | |||||
enum sysinit_sub_id subsystem; | |||||
enum sysinit_elem_order order; | |||||
sysinit_cfunc_t func; | |||||
const void *arg; | |||||
TAILQ_ENTRY(vnet_sysinit) link; | |||||
}; | |||||
#define VNET_SYSINIT(ident, subsystem, order, func, arg) \ | #define VNET_SYSINIT(ident, subsystem, order, func, arg) \ | ||||
static struct vnet_sysinit ident ## _vnet_init = { \ | static struct vnet_sysinit ident ## _vnet_init = { \ | ||||
subsystem, \ | subsystem, \ | ||||
order, \ | order, \ | ||||
(sysinit_cfunc_t)(sysinit_nfunc_t)func, \ | (sysinit_cfunc_t)(sysinit_nfunc_t)func, \ | ||||
(arg) \ | (arg) \ | ||||
}; \ | }; \ | ||||
SYSINIT(vnet_init_ ## ident, subsystem, order, \ | SYSINIT(vnet_init_ ## ident, subsystem, order, \ | ||||
vnet_register_sysinit, &ident ## _vnet_init); \ | _vnet_register_sysinit, &ident ## _vnet_init); \ | ||||
SYSUNINIT(vnet_init_ ## ident, subsystem, order, \ | SYSUNINIT(vnet_init_ ## ident, subsystem, order, \ | ||||
vnet_deregister_sysinit, &ident ## _vnet_init) | _vnet_deregister_sysinit, &ident ## _vnet_init) | ||||
#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ | #define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ | ||||
static struct vnet_sysinit ident ## _vnet_uninit = { \ | static struct vnet_sysinit ident ## _vnet_uninit = { \ | ||||
subsystem, \ | subsystem, \ | ||||
order, \ | order, \ | ||||
(sysinit_cfunc_t)(sysinit_nfunc_t)func, \ | (sysinit_cfunc_t)(sysinit_nfunc_t)func, \ | ||||
(arg) \ | (arg) \ | ||||
}; \ | }; \ | ||||
SYSINIT(vnet_uninit_ ## ident, subsystem, order, \ | SYSINIT(vnet_uninit_ ## ident, subsystem, order, \ | ||||
vnet_register_sysuninit, &ident ## _vnet_uninit); \ | _vnet_register_sysuninit, &ident ## _vnet_uninit); \ | ||||
SYSUNINIT(vnet_uninit_ ## ident, subsystem, order, \ | SYSUNINIT(vnet_uninit_ ## ident, subsystem, order, \ | ||||
vnet_deregister_sysuninit, &ident ## _vnet_uninit) | _vnet_deregister_sysuninit, &ident ## _vnet_uninit) | ||||
/* | /* | ||||
* Run per-vnet sysinits or sysuninits during vnet creation/destruction. | * Run per-vnet sysinits or sysuninits during vnet creation/destruction. | ||||
*/ | */ | ||||
void vnet_sysinit(void); | void vnet_sysinit(void); | ||||
void vnet_sysuninit(void); | void vnet_sysuninit(void); | ||||
/* | /* | ||||
* Interfaces for managing per-vnet constructors and destructors. | * Interfaces for managing per-vnet constructors and destructors. | ||||
*/ | */ | ||||
void vnet_register_sysinit(void *arg); | void vnet_register_sysinit(void *arg); | ||||
void vnet_register_sysuninit(void *arg); | void vnet_register_sysuninit(void *arg); | ||||
void vnet_deregister_sysinit(void *arg); | void vnet_deregister_sysinit(void *arg); | ||||
void vnet_deregister_sysuninit(void *arg); | void vnet_deregister_sysuninit(void *arg); | ||||
/* | /* | ||||
* EVENTHANDLER(9) extensions. | * EVENTHANDLER(9) extensions. | ||||
*/ | */ | ||||
#include <sys/eventhandler.h> | #include <sys/eventhandler.h> | ||||
void vnet_global_eventhandler_iterator_func(void *, ...); | void vnet_global_eventhandler_iterator_func(void *, ...); | ||||
#define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \ | #define VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(tag, name, func, arg, priority) \ | ||||
do { \ | do { \ | ||||
if (IS_DEFAULT_VNET(curvnet)) { \ | if (vimage_configured && IS_DEFAULT_VNET(curvnet)) { \ | ||||
(tag) = vimage_eventhandler_register(NULL, #name, func, \ | (tag) = vimage_eventhandler_register(NULL, #name, func, \ | ||||
arg, priority, \ | arg, priority, \ | ||||
vnet_global_eventhandler_iterator_func); \ | vnet_global_eventhandler_iterator_func); \ | ||||
} else if (!vimage_configured) { \ | |||||
(tag) = eventhandler_register(NULL, #name, func, arg, \ | |||||
priority); \ | |||||
} \ | } \ | ||||
} while(0) | } while(0) | ||||
#define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority) \ | #define VNET_GLOBAL_EVENTHANDLER_REGISTER(name, func, arg, priority) \ | ||||
do { \ | do { \ | ||||
if (IS_DEFAULT_VNET(curvnet)) { \ | if (vimage_configured && IS_DEFAULT_VNET(curvnet)) { \ | ||||
vimage_eventhandler_register(NULL, #name, func, \ | vimage_eventhandler_register(NULL, #name, func, \ | ||||
arg, priority, \ | arg, priority, \ | ||||
vnet_global_eventhandler_iterator_func); \ | vnet_global_eventhandler_iterator_func); \ | ||||
} else if (!vimage_configured) { \ | |||||
eventhandler_register(NULL, #name, func, arg, priority); \ | |||||
} \ | } \ | ||||
} while(0) | } while(0) | ||||
#else /* !VIMAGE */ | #else /* !VIMAGE */ | ||||
/* | /* | ||||
* Various virtual network stack macros compile to no-ops without VIMAGE. | * Various virtual network stack macros compile to no-ops without VIMAGE. | ||||
*/ | */ | ||||
Show All 13 Lines | |||||
#define IS_DEFAULT_VNET(arg) 1 | #define IS_DEFAULT_VNET(arg) 1 | ||||
#define CRED_TO_VNET(cr) NULL | #define CRED_TO_VNET(cr) NULL | ||||
#define TD_TO_VNET(td) NULL | #define TD_TO_VNET(td) NULL | ||||
#define P_TO_VNET(p) NULL | #define P_TO_VNET(p) NULL | ||||
/* | /* | ||||
* Versions of the VNET macros that compile to normal global variables and | * Versions of the VNET macros that compile to normal global variables and | ||||
* standard sysctl definitions. | * standard sysctl definitions. To ease the pain for kmods that determine at | ||||
* runtime if they are operating in VIMAGE mode or not, we name the globals | |||||
* with VNET_NAME so that modules can consistently reference VNET_NAME(n). | |||||
*/ | */ | ||||
#define VNET_NAME(n) n | #define VNET_DECLARE(t, n) extern t VNET_NAME(n) | ||||
#define VNET_DECLARE(t, n) extern t n | #define VNET_DEFINE(t, n) struct _hack; t VNET_NAME(n) | ||||
#define VNET_DEFINE(t, n) struct _hack; t n | #define VNET_DEFINE_STATIC(t, n) static t VNET_NAME(n) | ||||
#define VNET_DEFINE_STATIC(t, n) static t n | |||||
#define _VNET_PTR(b, n) &VNET_NAME(n) | #define _VNET_PTR(b, n) &VNET_NAME(n) | ||||
/* | /* | ||||
* Virtualized global variable accessor macros. | * Virtualized global variable accessor macros. | ||||
*/ | */ | ||||
#define VNET_VNET_PTR(vnet, n) (&(n)) | #define VNET_VNET_PTR(vnet, n) (&(VNET_NAME(n))) | ||||
#define VNET_VNET(vnet, n) (n) | #define VNET_VNET(vnet, n) (VNET_NAME(n)) | ||||
#define VNET_PTR(n) (&(n)) | #define VNET_PTR(n) (&(VNET_NAME(n))) | ||||
#define VNET(n) (n) | #define VNET(n) (VNET_NAME(n)) | ||||
/* | /* | ||||
* When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT | * When VIMAGE isn't compiled into the kernel, VNET_SYSINIT/VNET_SYSUNINIT | ||||
* map into normal sysinits, which have the same ordering properties. | * map into normal sysinits, which have the same ordering properties. | ||||
*/ | */ | ||||
#define VNET_SYSINIT(ident, subsystem, order, func, arg) \ | #define VNET_SYSINIT(ident, subsystem, order, func, arg) \ | ||||
SYSINIT(ident, subsystem, order, func, arg) | SYSINIT(ident, subsystem, order, func, arg) | ||||
#define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ | #define VNET_SYSUNINIT(ident, subsystem, order, func, arg) \ | ||||
Show All 13 Lines |