diff options
| author | Robert Watson <rwatson@FreeBSD.org> | 2009-08-01 19:26:27 +0000 |
|---|---|---|
| committer | Robert Watson <rwatson@FreeBSD.org> | 2009-08-01 19:26:27 +0000 |
| commit | 530c006014fae95c670f4b699fef8bb93034bc6d (patch) | |
| tree | 6dc533c8b591922258259a32957fdee2632a29ac /sys/net | |
| parent | 2df76c160ba5c04ece8efeff418362c9a1adc9f5 (diff) | |
Notes
Diffstat (limited to 'sys/net')
| -rw-r--r-- | sys/net/bpf.c | 2 | ||||
| -rw-r--r-- | sys/net/bridgestp.c | 1 | ||||
| -rw-r--r-- | sys/net/flowtable.c | 1 | ||||
| -rw-r--r-- | sys/net/if.c | 1 | ||||
| -rw-r--r-- | sys/net/if_bridge.c | 1 | ||||
| -rw-r--r-- | sys/net/if_clone.c | 1 | ||||
| -rw-r--r-- | sys/net/if_ef.c | 1 | ||||
| -rw-r--r-- | sys/net/if_enc.c | 1 | ||||
| -rw-r--r-- | sys/net/if_epair.c | 4 | ||||
| -rw-r--r-- | sys/net/if_ethersubr.c | 1 | ||||
| -rw-r--r-- | sys/net/if_faith.c | 2 | ||||
| -rw-r--r-- | sys/net/if_gif.c | 2 | ||||
| -rw-r--r-- | sys/net/if_gre.c | 2 | ||||
| -rw-r--r-- | sys/net/if_llatbl.c | 2 | ||||
| -rw-r--r-- | sys/net/if_loop.c | 1 | ||||
| -rw-r--r-- | sys/net/if_mib.c | 1 | ||||
| -rw-r--r-- | sys/net/if_spppsubr.c | 2 | ||||
| -rw-r--r-- | sys/net/if_stf.c | 2 | ||||
| -rw-r--r-- | sys/net/if_tun.c | 2 | ||||
| -rw-r--r-- | sys/net/if_vlan.c | 1 | ||||
| -rw-r--r-- | sys/net/netisr.c | 2 | ||||
| -rw-r--r-- | sys/net/raw_cb.c | 1 | ||||
| -rw-r--r-- | sys/net/raw_usrreq.c | 1 | ||||
| -rw-r--r-- | sys/net/route.c | 2 | ||||
| -rw-r--r-- | sys/net/rtsock.c | 1 | ||||
| -rw-r--r-- | sys/net/vnet.c | 174 | ||||
| -rw-r--r-- | sys/net/vnet.h | 153 |
27 files changed, 335 insertions, 30 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 5a2ab19160ee..08c9a5eee26b 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -56,7 +56,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sockio.h> #include <sys/ttycom.h> #include <sys/uio.h> -#include <sys/vimage.h> #include <sys/event.h> #include <sys/file.h> @@ -73,6 +72,7 @@ __FBSDID("$FreeBSD$"); #endif #include <net/bpf_zerocopy.h> #include <net/bpfdesc.h> +#include <net/vnet.h> #include <netinet/in.h> #include <netinet/if_ether.h> diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index 9349be44b767..3e65113c2d56 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/mutex.h> #include <sys/taskqueue.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_dl.h> diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c index 1fe2bbe69b8d..4078ae9138e1 100644 --- a/sys/net/flowtable.c +++ b/sys/net/flowtable.c @@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$"); #include <sys/socket.h> #include <sys/syslog.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_llatbl.h> diff --git a/sys/net/if.c b/sys/net/if.c index 02796cbcf6c0..3ac7db05c14b 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -59,7 +59,6 @@ #include <sys/taskqueue.h> #include <sys/domain.h> #include <sys/jail.h> -#include <sys/vimage.h> #include <machine/stdarg.h> #include <vm/uma.h> diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 945bc5f2e661..ced953a52f0f 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -101,7 +101,6 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/mutex.h> #include <sys/rwlock.h> -#include <sys/vimage.h> #include <net/bpf.h> #include <net/if.h> diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index 95c07b731d0c..0dd20fb36108 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -39,7 +39,6 @@ #include <sys/systm.h> #include <sys/types.h> #include <sys/socket.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index c0b2d671759a..7a5fca916d7f 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -39,7 +39,6 @@ #include <sys/syslog.h> #include <sys/kernel.h> #include <sys/module.h> -#include <sys/vimage.h> #include <net/ethernet.h> #include <net/if_llc.h> diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c index 7b62734d14c7..a49c5dc5b236 100644 --- a/sys/net/if_enc.c +++ b/sys/net/if_enc.c @@ -38,7 +38,6 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index e299d972bb2d..00f99fdfa5c0 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -38,7 +38,7 @@ /* * Things to re-think once we have more experience: * - ifp->if_reassign function once we can test with vimage. Depending on - * how if_vomve() is going to be improved. + * how if_vmove() is going to be improved. * - Real random etheraddrs that are checked to be uniquish; we would need * to re-do them in case we move the interface between network stacks * in a private if_reassign function. @@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$"); #include <sys/sockio.h> #include <sys/sysctl.h> #include <sys/types.h> -#include <sys/vimage.h> #include <net/bpf.h> #include <net/ethernet.h> @@ -70,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_var.h> #include <net/if_types.h> #include <net/netisr.h> +#include <net/vnet.h> #define EPAIRNAME "epair" diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 545d9ee1a481..bac204449230 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -50,7 +50,6 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_arp.h> diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index cbca740ed5db..ca8088362a96 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -54,7 +54,6 @@ #include <sys/queue.h> #include <sys/types.h> #include <sys/malloc.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> @@ -62,6 +61,7 @@ #include <net/netisr.h> #include <net/route.h> #include <net/bpf.h> +#include <net/vnet.h> #ifdef INET #include <netinet/in.h> diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 3d75dd46e42e..6abc8071e021 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -49,7 +49,6 @@ #include <sys/proc.h> #include <sys/protosw.h> #include <sys/conf.h> -#include <sys/vimage.h> #include <machine/cpu.h> #include <net/if.h> @@ -58,6 +57,7 @@ #include <net/netisr.h> #include <net/route.h> #include <net/bpf.h> +#include <net/vnet.h> #include <netinet/in.h> #include <netinet/in_systm.h> diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 4ed2a9ef13f5..2b283d69e3d7 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -64,13 +64,13 @@ #include <sys/sockio.h> #include <sys/sysctl.h> #include <sys/systm.h> -#include <sys/vimage.h> #include <net/ethernet.h> #include <net/if.h> #include <net/if_clone.h> #include <net/if_types.h> #include <net/route.h> +#include <net/vnet.h> #ifdef INET #include <netinet/in.h> diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index b5da1ea44360..a1b574f9f371 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/mutex.h> #include <sys/rwlock.h> -#include <sys/vimage.h> #include <vm/uma.h> @@ -51,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_dl.h> #include <net/if_var.h> #include <net/route.h> +#include <net/vnet.h> #include <netinet/if_ether.h> #include <netinet6/in6_var.h> #include <netinet6/nd6.h> diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 043c808f7f0c..056b2f93a353 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -49,7 +49,6 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c index c0018efae9ba..c334ac7f1a44 100644 --- a/sys/net/if_mib.c +++ b/sys/net/if_mib.c @@ -34,7 +34,6 @@ #include <sys/kernel.h> #include <sys/socket.h> #include <sys/sysctl.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_mib.h> diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 2c325eea9bdd..3f0faafa3d6c 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -36,7 +36,6 @@ #include <sys/random.h> #include <sys/malloc.h> #include <sys/mbuf.h> -#include <sys/vimage.h> #include <sys/md5.h> @@ -44,6 +43,7 @@ #include <net/netisr.h> #include <net/if_types.h> #include <net/route.h> +#include <net/vnet.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index ddc56629b2aa..5c082c4926a6 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -92,7 +92,6 @@ #include <machine/cpu.h> #include <sys/malloc.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> @@ -100,6 +99,7 @@ #include <net/netisr.h> #include <net/if_types.h> #include <net/if_stf.h> +#include <net/vnet.h> #include <netinet/in.h> #include <netinet/in_systm.h> diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index a9a1c62d0810..37b5e70302c1 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -43,13 +43,13 @@ #include <sys/uio.h> #include <sys/malloc.h> #include <sys/random.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_clone.h> #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> +#include <net/vnet.h> #ifdef INET #include <netinet/in.h> #endif diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index ac7287006d12..04c2c0dc6448 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -55,7 +55,6 @@ #include <sys/sockio.h> #include <sys/sysctl.h> #include <sys/systm.h> -#include <sys/vimage.h> #include <net/bpf.h> #include <net/ethernet.h> diff --git a/sys/net/netisr.c b/sys/net/netisr.c index b2db8c153aec..c8da579834e3 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$"); #include <sys/socket.h> #include <sys/sysctl.h> #include <sys/systm.h> -#include <sys/vimage.h> #ifdef DDB #include <ddb/ddb.h> @@ -87,6 +86,7 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/if_var.h> #include <net/netisr.h> +#include <net/vnet.h> /*- * Synchronize use and modification of the registered netisr data structures; diff --git a/sys/net/raw_cb.c b/sys/net/raw_cb.c index 30a526fbbeab..c430d973d84a 100644 --- a/sys/net/raw_cb.c +++ b/sys/net/raw_cb.c @@ -42,7 +42,6 @@ #include <sys/socketvar.h> #include <sys/sysctl.h> #include <sys/systm.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/raw_cb.h> diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c index 0759e427483a..2de3d692163a 100644 --- a/sys/net/raw_usrreq.c +++ b/sys/net/raw_usrreq.c @@ -44,7 +44,6 @@ #include <sys/socketvar.h> #include <sys/sx.h> #include <sys/systm.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/raw_cb.h> diff --git a/sys/net/route.c b/sys/net/route.c index 544c3b643629..fc76c924c66e 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -51,11 +51,11 @@ #include <sys/proc.h> #include <sys/domain.h> #include <sys/kernel.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_dl.h> #include <net/route.h> +#include <net/vnet.h> #ifdef RADIX_MPATH #include <net/radix_mpath.h> diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 88c980703065..645cf7e54eb8 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -50,7 +50,6 @@ #include <sys/socketvar.h> #include <sys/sysctl.h> #include <sys/systm.h> -#include <sys/vimage.h> #include <net/if.h> #include <net/if_dl.h> diff --git a/sys/net/vnet.c b/sys/net/vnet.c index eed353e644b6..a34270a3eea6 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -1,4 +1,12 @@ /*- + * Copyright (c) 2004-2009 University of Zagreb + * Copyright (c) 2006-2009 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by the University of Zagreb and the + * FreeBSD Foundation under sponsorship by the Stichting NLnet and the + * FreeBSD Foundation. + * * Copyright (c) 2009 Jeffrey Roberson <jeff@freebsd.org> * Copyright (c) 2009 Robert N. M. Watson * All rights reserved. @@ -28,30 +36,67 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_ddb.h" + #include <sys/param.h> #include <sys/kernel.h> +#include <sys/jail.h> #include <sys/systm.h> #include <sys/sysctl.h> #include <sys/linker_set.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/socket.h> #include <sys/sx.h> #include <sys/sysctl.h> -#include <sys/vimage.h> +#ifdef DDB +#include <ddb/ddb.h> +#endif + +#include <net/if.h> +#include <net/if_var.h> #include <net/vnet.h> /*- * This file implements core functions for virtual network stacks: * + * - Core virtual network stack management functions. + * * - Virtual network stack memory allocator, which virtualized global * variables in the network stack * * - Virtualized SYSINIT's/SYSUNINIT's, which allow network stack subsystems * to register startup/shutdown events to be run for each virtual network * stack instance. - * + */ + +MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); + +/* + * The virtual network stack list has two read-write locks, one sleepable and + * the other not, so that the list can be stablized and walked in a variety + * of network stack contexts. Both must be acquired exclusively to modify + * the list. + */ +struct rwlock vnet_rwlock; +struct sx vnet_sxlock; + +#define VNET_LIST_WLOCK() do { \ + sx_xlock(&vnet_sxlock); \ + rw_wlock(&vnet_rwlock); \ +} while (0) + +#define VNET_LIST_WUNLOCK() do { \ + rw_wunlock(&vnet_rwlock); \ + sx_xunlock(&vnet_sxlock); \ +} while (0) + +struct vnet_list_head vnet_head; +struct vnet *vnet0; + +/* * The virtual network stack allocator provides storage for virtualized * global variables. These variables are defined/declared using the * VNET_DEFINE()/VNET_DECLARE() macros, which place them in the 'set_vnet' @@ -157,6 +202,114 @@ static TAILQ_HEAD(, vnet_data_free) vnet_data_free_head = static struct sx vnet_data_free_lock; /* + * Allocate a virtual network stack. + */ +struct vnet * +vnet_alloc(void) +{ + struct vnet *vnet; + + vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO); + vnet->vnet_magic_n = VNET_MAGIC_N; + vnet_data_init(vnet); + + /* Initialize / attach vnet module instances. */ + CURVNET_SET_QUIET(vnet); + + sx_xlock(&vnet_sxlock); + vnet_sysinit(); + CURVNET_RESTORE(); + + rw_wlock(&vnet_rwlock); + LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); + VNET_LIST_WUNLOCK(); + + return (vnet); +} + +/* + * Destroy a virtual network stack. + */ +void +vnet_destroy(struct vnet *vnet) +{ + struct ifnet *ifp, *nifp; + + KASSERT(vnet->vnet_sockcnt == 0, + ("%s: vnet still has sockets", __func__)); + + VNET_LIST_WLOCK(); + LIST_REMOVE(vnet, vnet_le); + rw_wunlock(&vnet_rwlock); + + CURVNET_SET_QUIET(vnet); + + /* Return all inherited interfaces to their parent vnets. */ + TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) { + if (ifp->if_home_vnet != ifp->if_vnet) + if_vmove(ifp, ifp->if_home_vnet); + } + + vnet_sysuninit(); + sx_xunlock(&vnet_sxlock); + + CURVNET_RESTORE(); + + /* Hopefully, we are OK to free the vnet container itself. */ + vnet_data_destroy(vnet); + vnet->vnet_magic_n = 0xdeadbeef; + free(vnet, M_VNET); +} + +static void +vnet_foreach(void (*vnet_foreach_fn)(struct vnet *, void *), void *arg) +{ + struct vnet *vnet; + + VNET_LIST_RLOCK(); + LIST_FOREACH(vnet, &vnet_head, vnet_le) + vnet_foreach_fn(vnet, arg); + VNET_LIST_RUNLOCK(); +} + +/* + * Boot time initialization and allocation of virtual network stacks. + */ +static void +vnet_init_prelink(void *arg) +{ + + rw_init(&vnet_rwlock, "vnet_rwlock"); + sx_init(&vnet_sxlock, "vnet_sxlock"); + LIST_INIT(&vnet_head); +} +SYSINIT(vnet_init_prelink, SI_SUB_VNET_PRELINK, SI_ORDER_FIRST, + vnet_init_prelink, NULL); + +static void +vnet0_init(void *arg) +{ + + /* + * We MUST clear curvnet in vi_init_done() before going SMP, + * otherwise CURVNET_SET() macros would scream about unnecessary + * curvnet recursions. + */ + curvnet = prison0.pr_vnet = vnet0 = vnet_alloc(); +} +SYSINIT(vnet0_init, SI_SUB_VNET, SI_ORDER_FIRST, vnet0_init, NULL); + +static void +vnet_init_done(void *unused) +{ + + curvnet = NULL; +} + +SYSINIT(vnet_init_done, SI_SUB_VNET_DONE, SI_ORDER_FIRST, vnet_init_done, + NULL); + +/* * Allocate storage for virtualized global variables in a new virtual network * stack instance, and copy in initial values from our 'master' copy. */ @@ -490,3 +643,20 @@ vnet_sysuninit(void) vs->func(vs->arg); } } + +#ifdef DDB +DB_SHOW_COMMAND(vnets, db_show_vnets) +{ + VNET_ITERATOR_DECL(vnet_iter); + +#if SIZE_MAX == UINT32_MAX /* 32-bit arch */ + db_printf(" vnet ifs socks\n"); +#else /* 64-bit arch, most probaly... */ + db_printf(" vnet ifs socks\n"); +#endif + VNET_FOREACH(vnet_iter) { + db_printf("%p %3d %5d\n", vnet_iter, vnet_iter->vnet_ifcnt, + vnet_iter->vnet_sockcnt); + } +} +#endif diff --git a/sys/net/vnet.h b/sys/net/vnet.h index 08ee21a8d871..47dc7ac03b46 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -1,4 +1,12 @@ /*- + * Copyright (c) 2006-2009 University of Zagreb + * Copyright (c) 2006-2009 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by the University of Zagreb and the + * FreeBSD Foundation under sponsorship by the Stichting NLnet and the + * FreeBSD Foundation. + * * Copyright (c) 2009 Jeffrey Roberson <jeff@freebsd.org> * Copyright (c) 2009 Robert N. M. Watson * All rights reserved. @@ -31,6 +39,9 @@ * This header file defines several sets of interfaces supporting virtualized * network stacks: * + * - Definition of 'struct vnet' and functions and macros to allocate/free/ + * manipulate it. + * * - A virtual network stack memory allocator, which provides support for * virtualized global variables via a special linker set, set_vnet. * @@ -47,17 +58,133 @@ #define _NET_VNET_H_ /* - * Virtual network stack memory allocator, which allows global variables to - * be automatically instantiated for each network stack instance. + * struct vnet describes a virtualized network stack, and is primarily a + * pointer to storage for virtualized global variables. Expose to userspace + * as required for libkvm. */ #if defined(_KERNEL) || defined(_WANT_VNET) +#include <sys/queue.h> + +struct vnet { + LIST_ENTRY(vnet) vnet_le; /* all vnets list */ + u_int vnet_magic_n; + u_int vnet_ifcnt; + u_int vnet_sockcnt; + void *vnet_data_mem; + uintptr_t vnet_data_base; +}; +#define VNET_MAGIC_N 0x3e0d8f29 + +/* + * These two virtual network stack allocator definitions are also required + * for libkvm so that it can evaluate virtualized global variables. + */ #define VNET_SETNAME "set_vnet" #define VNET_SYMPREFIX "vnet_entry_" #endif #ifdef _KERNEL + #ifdef VIMAGE +#include <sys/lock.h> +#include <sys/proc.h> /* for struct thread */ +#include <sys/rwlock.h> +#include <sys/sx.h> + +/* + * Functions to allocate and destroy virtual network stacks. + */ +struct vnet *vnet_alloc(void); +void vnet_destroy(struct vnet *vnet); + +/* + * The current virtual network stack -- we may wish to move this to struct + * pcpu in the future. + */ +#define curvnet curthread->td_vnet + +/* + * Various macros -- get and set the current network stack, but also + * assertions. + */ +#ifdef INVARIANTS +#define VNET_DEBUG +#endif +#ifdef VNET_DEBUG +#define VNET_ASSERT(condition) \ + if (!(condition)) { \ + printf("VNET_ASSERT @ %s:%d %s():\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + panic(#condition); \ + } +#define CURVNET_SET_QUIET(arg) \ + VNET_ASSERT((arg)->vnet_magic_n == VNET_MAGIC_N); \ + struct vnet *saved_vnet = curvnet; \ + const char *saved_vnet_lpush = curthread->td_vnet_lpush; \ + curvnet = arg; \ + curthread->td_vnet_lpush = __FUNCTION__; + +#define CURVNET_SET_VERBOSE(arg) \ + CURVNET_SET_QUIET(arg) \ + if (saved_vnet) \ + printf("CURVNET_SET(%p) in %s() on cpu %d, prev %p in %s()\n", \ + curvnet, curthread->td_vnet_lpush, curcpu, \ + saved_vnet, saved_vnet_lpush); + +#define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) + +#define CURVNET_RESTORE() \ + VNET_ASSERT(saved_vnet == NULL || \ + saved_vnet->vnet_magic_n == VNET_MAGIC_N); \ + curvnet = saved_vnet; \ + curthread->td_vnet_lpush = saved_vnet_lpush; +#else /* !VNET_DEBUG */ +#define VNET_ASSERT(condition) + +#define CURVNET_SET(arg) \ + struct vnet *saved_vnet = curvnet; \ + curvnet = arg; + +#define CURVNET_SET_VERBOSE(arg) CURVNET_SET(arg) +#define CURVNET_SET_QUIET(arg) CURVNET_SET(arg) + +#define CURVNET_RESTORE() \ + curvnet = saved_vnet; +#endif /* VNET_DEBUG */ + +extern struct vnet *vnet0; +#define IS_DEFAULT_VNET(arg) ((arg) == vnet0) + +#define CRED_TO_VNET(cr) (cr)->cr_prison->pr_vnet +#define TD_TO_VNET(td) CRED_TO_VNET((td)->td_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 + * access it. If a caller may sleep while accessing the list, it must use + * the sleepable lock macros. + */ +LIST_HEAD(vnet_list_head, vnet); +extern struct vnet_list_head vnet_head; +extern struct rwlock vnet_rwlock; +extern struct sx vnet_sxlock; + +#define VNET_LIST_RLOCK() sx_slock(&vnet_sxlock) +#define VNET_LIST_RLOCK_NOSLEEP() rw_rlock(&vnet_rwlock) +#define VNET_LIST_RUNLOCK() sx_sunlock(&vnet_sxlock) +#define VNET_LIST_RUNLOCK_NOSLEEP() rw_runlock(&vnet_rwlock) + +/* + * Iteration macros to walk the global list of virtual network stacks. + */ +#define VNET_ITERATOR_DECL(arg) struct vnet *arg +#define VNET_FOREACH(arg) LIST_FOREACH((arg), &vnet_head, vnet_le) + +/* + * Virtual network stack memory allocator, which allows global variables to + * be automatically instantiated for each network stack instance. + */ #if defined(__arm__) __asm__(".section " VNET_SETNAME ", \"aw\", %progbits"); #else @@ -193,6 +320,28 @@ void vnet_deregister_sysuninit(void *arg); #else /* !VIMAGE */ /* + * Various virtual network stack macros compile to no-ops without VIMAGE. + */ +#define curvnet NULL + +#define VNET_ASSERT(condition) +#define CURVNET_SET(arg) +#define CURVNET_SET_QUIET(arg) +#define CURVNET_RESTORE() + +#define VNET_LIST_RLOCK() +#define VNET_LIST_RLOCK_NOSLEEP() +#define VNET_LIST_RUNLOCK() +#define VNET_LIST_RUNLOCK_NOSLEEP() +#define VNET_ITERATOR_DECL(arg) +#define VNET_FOREACH(arg) + +#define IS_DEFAULT_VNET(arg) 1 +#define CRED_TO_VNET(cr) NULL +#define TD_TO_VNET(td) NULL +#define P_TO_VNET(p) NULL + +/* * Versions of the VNET macros that compile to normal global variables and * standard sysctl definitions. */ |
