summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-08-01 19:26:27 +0000
committerrwatson <rwatson@FreeBSD.org>2009-08-01 19:26:27 +0000
commitfb9ffed6504601ed9da2c6b9a620b133c838964c (patch)
tree6dc533c8b591922258259a32957fdee2632a29ac /sys/net
parent2d4b24984c5d2ea2556ae2b1ef1df7f0833dc1b5 (diff)
downloadFreeBSD-src-fb9ffed6504601ed9da2c6b9a620b133c838964c.zip
FreeBSD-src-fb9ffed6504601ed9da2c6b9a620b133c838964c.tar.gz
Merge the remainder of kern_vimage.c and vimage.h into vnet.c and
vnet.h, we now use jails (rather than vimages) as the abstraction for virtualization management, and what remained was specific to virtual network stacks. Minor cleanups are done in the process, and comments updated to reflect these changes. Reviewed by: bz Approved by: re (vimage blanket)
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bpf.c2
-rw-r--r--sys/net/bridgestp.c1
-rw-r--r--sys/net/flowtable.c1
-rw-r--r--sys/net/if.c1
-rw-r--r--sys/net/if_bridge.c1
-rw-r--r--sys/net/if_clone.c1
-rw-r--r--sys/net/if_ef.c1
-rw-r--r--sys/net/if_enc.c1
-rw-r--r--sys/net/if_epair.c4
-rw-r--r--sys/net/if_ethersubr.c1
-rw-r--r--sys/net/if_faith.c2
-rw-r--r--sys/net/if_gif.c2
-rw-r--r--sys/net/if_gre.c2
-rw-r--r--sys/net/if_llatbl.c2
-rw-r--r--sys/net/if_loop.c1
-rw-r--r--sys/net/if_mib.c1
-rw-r--r--sys/net/if_spppsubr.c2
-rw-r--r--sys/net/if_stf.c2
-rw-r--r--sys/net/if_tun.c2
-rw-r--r--sys/net/if_vlan.c1
-rw-r--r--sys/net/netisr.c2
-rw-r--r--sys/net/raw_cb.c1
-rw-r--r--sys/net/raw_usrreq.c1
-rw-r--r--sys/net/route.c2
-rw-r--r--sys/net/rtsock.c1
-rw-r--r--sys/net/vnet.c174
-rw-r--r--sys/net/vnet.h153
27 files changed, 335 insertions, 30 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 5a2ab19..08c9a5e 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 9349be4..3e65113 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 1fe2bbe..4078ae9 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 02796cb..3ac7db0 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 945bc5f..ced953a 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 95c07b7..0dd20fb 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 c0b2d67..7a5fca9 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 7b62734..a49c5dc 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 e299d97..00f99fd 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 545d9ee..bac2044 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 cbca740..ca80883 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 3d75dd4..6abc807 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 4ed2a9e..2b283d6 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 b5da1ea..a1b574f 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 043c808..056b2f9 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 c0018ef..c334ac7 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 2c325ee..3f0faaf 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 ddc5662..5c082c4 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 a9a1c62..37b5e70 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 ac72870..04c2c0d 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 b2db8c1..c8da579 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 30a526f..c430d97 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 0759e42..2de3d69 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 544c3b6..fc76c92 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 88c9807..645cf7e 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 eed353e..a34270a 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 08ee21a..47dc7ac 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.
*/
OpenPOWER on IntegriCloud