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

FreeBSD Manual Pages

  
 
  

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

NAME
     VNET -- network subsystem virtualization infrastructure

SYNOPSIS
     options VIMAGE
     options VNET_DEBUG

     #include <sys/vnet.h>

   Constants and Global	Variables
     VNET_SETNAME VNET_SYMPREFIX

     extern struct vnet	*vnet0;

   Variable Declaration
     VNET(name);

     VNET_NAME(name);

     VNET_DECLARE(type,	name);

     VNET_DEFINE(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 *);

     CURVNET_RESTORE();

     VNET_ITERATOR_DECL(struct vnet *);

     VNET_FOREACH(struct vnet *);

   Locking
     VNET_LIST_RLOCK();

     VNET_LIST_RUNLOCK();

     VNET_LIST_RLOCK_NOSLEEP();

     VNET_LIST_RUNLOCK_NOSLEEP();

   Startup and Teardown	Functions
     struct vnet *
     vnet_alloc(void);

     void
     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);

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

     VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG(eventhandler_tag tag,
	   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,
	   descr);

     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);

DESCRIPTION
     VNET is the name of a technique to	virtualize the network stack.  The
     basic 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
     unrestricted 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
     or	storage	class specifiers, e.g.,

	   static VNET_DEFINE(int, foo)	= 1;
     or
	   static VNET_DEFINE(SLIST_HEAD(, bar), bars);

     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-
     tion):

	   #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
     macro.

     To	set the	correct	context	of the current virtual network instance, use
     the CURVNET_SET() or CURVNET_SET_QUIET() macros.  The CURVNET_SET_QUIET()
     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)
		   CURVNET_SET(vnet);

     nor would this work:

	   if (condition) {
		   CURVNET_SET(vnet);
	   }
	   CURVNET_RESTORE();

     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
     semantics as KASSERT(9).

   Locking
     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
     VNET_LIST_RLOCK_NOSLEEP() and VNET_LIST_RUNLOCK_NOSLEEP().

   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
     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_*()
     macros.

     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.

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

HISTORY
     The virtual network stack implementation first appeared in	FreeBSD	8.0.

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

FreeBSD	11.1		       November	20, 2014		  FreeBSD 11.1

NAME | SYNOPSIS | DESCRIPTION | SEE ALSO | HISTORY | AUTHORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=vnet&sektion=9&manpath=FreeBSD+11.1-RELEASE+and+Ports>

home | help