Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
VNET(9)			 BSD Kernel Developer's	Manual		       VNET(9)

     VNET -- network subsystem virtualization infrastructure

     options VIMAGE
     options VNET_DEBUG

     #include <net/vnet.h>

   Constants and Global	Variables

     extern struct vnet	*vnet0;

   Variable Declaration


     VNET_DECLARE(type,	name);

     VNET_DEFINE(type, name);

     VNET_DEFINE_STATIC(type, name);

     #define V_name  VNET(name)

   Virtual Instance Selection
     CRED_TO_VNET(struct ucred *);

     TD_TO_VNET(struct thread *);

     P_TO_VNET(struct proc *);

     IS_DEFAULT_VNET(struct vnet *);

     VNET_ASSERT(exp, msg);

     CURVNET_SET(struct	vnet *);

     CURVNET_SET_QUIET(struct vnet *);


     VNET_ITERATOR_DECL(struct vnet *);

     VNET_FOREACH(struct vnet *);





   Startup and Teardown	Functions
     struct vnet *

     vnet_destroy(struct vnet *);

     VNET_SYSINIT(ident, enum sysinit_sub_id subsystem,
	   enum	sysinit_elem_order order, sysinit_cfunc_t func,
	   const void *arg);

     VNET_SYSUNINIT(ident, enum	sysinit_sub_id subsystem,
	   enum	sysinit_elem_order order, sysinit_cfunc_t func,
	   const void *arg);

     VNET_GLOBAL_EVENTHANDLER_REGISTER(const char *name, void *func,
	   void	*arg, int priority);

	   const char *name, void *func, void *arg, int	priority);

   Sysctl Handling
     SYSCTL_VNET_INT(parent, nbr, name,	access,	ptr, val, descr);

     SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler, fmt,

     SYSCTL_VNET_STRING(parent,	nbr, name, access, arg,	len, descr);

     SYSCTL_VNET_STRUCT(parent,	nbr, name, access, ptr,	type, descr);

     SYSCTL_VNET_UINT(parent, nbr, name, access, ptr, val, descr);

     VNET_SYSCTL_ARG(req, arg1);

     VNET is the name of a technique to	virtualize the network stack.  The ba-
     sic idea is to change global resources most notably variables into	per
     network stack resources and have functions, sysctls, eventhandlers, etc.
     access and	handle them in the context of the correct instance.  Each
     (virtual) network stack is	attached to a prison, with vnet0 being the un-
     restricted	default	network	stack of the base system.

     The global	defines	for VNET_SETNAME and VNET_SYMPREFIX are	shared with
     kvm(3) to access internals	for debugging reasons.

   Variable Declaration
     Variables are virtualized by using	the VNET_DEFINE() macro	rather than
     writing them out as type name.  One can still use static initialization,

	   VNET_DEFINE(int, foo) = 1;

     Variables declared	with the static	keyword	can use	the
     VNET_DEFINE_STATIC() macro, e.g.,


     Static initialization is not possible when	the virtualized	variable would
     need to be	referenced, e.g., with "TAILQ_HEAD_INITIALIZER()".  In that
     case a VNET_SYSINIT() based initialization	function must be used.

     External variables	have to	be declared using the VNET_DECLARE() macro.
     In	either case the	convention is to define	another	macro, that is then
     used throughout the implementation	to access that variable.  The variable
     name is usually prefixed by V_ to express that it is virtualized.	The
     VNET() macro will then translate accesses to that variable	to the copy of
     the currently selected instance (see the Virtual instance selection sec-

	   #define   V_name    VNET(name)

     NOTE: Do not confuse this with the	convention used	by VFS(9).

     The VNET_NAME() macro returns the offset within the memory	region of the
     virtual network stack instance.  It is usually only used with
     SYSCTL_VNET_*() macros.

   Virtual Instance Selection
     There are three different places where the	current	virtual	network	stack
     pointer is	stored and can be taken	from:

	   1.	a prison:
		      (struct prison *)->pr_vnet

		For convenience	the following macros are provided:
		      CRED_TO_VNET(struct ucred	*)
		      TD_TO_VNET(struct	thread *)
		      P_TO_VNET(struct proc *)

	   2.	a socket:
		      (struct socket *)->so_vnet

	   3.	an interface:
		      (struct ifnet *)->if_vnet

     In	addition the currently active instance is cached in
     "curthread->td_vnet" which	is usually only	accessed through the curvnet

     To	set the	correct	context	of the current virtual network instance, use
     version will not record vnet recursions in	case the kernel	was compiled
     with options VNET_DEBUG and should	thus only be used in well known	cases,
     where recursion is	unavoidable.  Both macros will save the	previous state
     on	the stack and it must be restored with the CURVNET_RESTORE() macro.

     NOTE: As the previous state is saved on the stack,	you cannot have	multi-
     ple CURVNET_SET() calls in	the same block.

     NOTE: As the previous state is saved on the stack,	a CURVNET_RESTORE()
     call has to be in the same	block as the CURVNET_SET() call	or in a	sub-
     block with	the same idea of the saved instances as	the outer block.

     NOTE: As each macro is a set of operations	and, as	previously explained,
     cannot be put into	its own	block when defined, one	cannot conditionally
     set the current vnet context.  The	following will not work:

	   if (condition)

     nor would this work:

	   if (condition) {

     Sometimes one needs to loop over all virtual instances, for example to
     update virtual from global	state, to run a	function from a	callout(9) for
     each instance, etc.  For those cases the VNET_ITERATOR_DECL() and
     VNET_FOREACH() macros are provided.  The former macro defines the vari-
     able that iterates	over the loop, and the latter loops over all of	the
     virtual network stack instances.  See Locking for how to savely traverse
     the list of all virtual instances.

     The IS_DEFAULT_VNET() macro provides a safe way to	check whether the cur-
     rently active instance is the unrestricted	default	network	stack of the
     base system (vnet0).

     The VNET_ASSERT() macro provides a	way to conditionally add assertions
     that are only active with options VIMAGE compiled in and either options
     VNET_DEBUG	or options INVARIANTS enabled as well.	It uses	the same se-
     mantics as	KASSERT(9).

     For public	access to the list of virtual network stack instances e.g., by
     the VNET_FOREACH()	macro, read locks are provided.	 Macros	are used to
     abstract from the actual type of the locks.  If a caller may sleep	while
     traversing	the list, it must use the VNET_LIST_RLOCK() and
     VNET_LIST_RUNLOCK() macros.  Otherwise, the caller	can use

   Startup and Teardown	Functions
     To	start or tear down a virtual network stack instance the	internal func-
     tions vnet_alloc()	and vnet_destroy() are provided	and called from	the
     jail framework.  They run the publicly provided methods to	handle network
     stack startup and teardown.

     For public	control, the system startup interface has been enhanced	to not
     only handle a system boot but to also handle a virtual network stack
     startup and teardown.  To the base	system the VNET_SYSINIT() and
     VNET_SYSUNINIT() macros look exactly as if	there were no virtual network
     stack.  In	fact, if options VIMAGE	is not compiled	in they	are compiled
     to	the standard SYSINIT() macros.	In addition to that they are run for
     each virtual network stack	when starting or, in reverse order, when shut-
     ting down.

     Eventhandlers can be handled in two ways:

	   1.	save the tags returned in each virtual instance	and properly
		free the eventhandlers on teardown using those,	or
	   2.	use one	eventhandler that will iterate over all	virtual	net-
		work stack instances.

     For the first case	one can	just use the normal EVENTHANDLER(9) functions,
     while for the second case the VNET_GLOBAL_EVENTHANDLER_REGISTER() and
     VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG() macros are	provided.  These dif-
     fer in that VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG() takes an extra	first
     argument that will	carry the tag upon return.  Eventhandlers registered
     with either of these will not run func directly but func will be called
     from an internal iterator function	for each vnet.	Both macros can	only
     be	used for eventhandlers that do not take	additional arguments, as the
     variadic arguments	from an	EVENTHANDLER_INVOKE(9) call will be ignored.

   Sysctl Handling
     A sysctl(9) can be	virtualized by using one of the	SYSCTL_VNET_*()

     They take the same	arguments as the standard sysctl(9) functions, with
     the only difference, that the ptr argument	has to be passed as
     `&VNET_NAME(foo)' instead of `&foo' so that the variable can be selected
     from the correct memory region of the virtual network stack instance of
     the caller.

     For the very rare case a sysctl handler function would want to handle
     arg1 itself the VNET_SYSCTL_ARG(req, arg1)	is provided that will trans-
     late the arg1 argument to the correct memory address in the virtual net-
     work stack	context	of the caller.

     jail(2), kvm(3), EVENTHANDLER(9), KASSERT(9), sysctl(9)

     Marko Zec,	Implementing a Clonable	Network	Stack in the FreeBSD Kernel,
     USENIX ATC'03, June 2003, Boston

     The virtual network stack implementation first appeared in	FreeBSD	8.0.

     The VNET framework	was designed and implemented at	the University of Za-
     greb by Marko Zec under sponsorship of the	FreeBSD	Foundation and NLnet
     Foundation, and later extended and	refined	by Bjoern A. Zeeb (also	under
     FreeBSD Foundation	sponsorship), and Robert Watson.

     This manual page was written by Bjoern A. Zeeb, CK	Software GmbH, under
     sponsorship from the FreeBSD Foundation.

BSD			       December	10, 2020			   BSD


Want to link to this manual page? Use this URL:

home | help