summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/bridgestp.c1
-rw-r--r--sys/net/flowtable.c143
-rw-r--r--sys/net/flowtable.h5
-rw-r--r--sys/net/if.c86
-rw-r--r--sys/net/if_bridge.c6
-rw-r--r--sys/net/if_clone.c23
-rw-r--r--sys/net/if_ef.c1
-rw-r--r--sys/net/if_enc.c1
-rw-r--r--sys/net/if_ethersubr.c14
-rw-r--r--sys/net/if_faith.c2
-rw-r--r--sys/net/if_gif.c44
-rw-r--r--sys/net/if_gif.h30
-rw-r--r--sys/net/if_gre.c4
-rw-r--r--sys/net/if_loop.c23
-rw-r--r--sys/net/if_mib.c4
-rw-r--r--sys/net/if_spppsubr.c2
-rw-r--r--sys/net/if_stf.c3
-rw-r--r--sys/net/if_var.h16
-rw-r--r--sys/net/if_vlan.c1
-rw-r--r--sys/net/raw_cb.c5
-rw-r--r--sys/net/raw_cb.h6
-rw-r--r--sys/net/raw_usrreq.c2
-rw-r--r--sys/net/route.c70
-rw-r--r--sys/net/rtsock.c3
-rw-r--r--sys/net/vnet.c341
-rw-r--r--sys/net/vnet.h161
26 files changed, 609 insertions, 388 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c
index a4ec6bc..9349be4 100644
--- a/sys/net/bridgestp.c
+++ b/sys/net/bridgestp.c
@@ -2006,7 +2006,6 @@ bstp_same_bridgeid(uint64_t id1, uint64_t id2)
void
bstp_reinit(struct bstp_state *bs)
{
- INIT_VNET_NET(curvnet);
struct bstp_port *bp;
struct ifnet *ifp, *mif;
u_char *e_addr;
diff --git a/sys/net/flowtable.c b/sys/net/flowtable.c
index fafdc0a..dd1b040 100644
--- a/sys/net/flowtable.c
+++ b/sys/net/flowtable.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/sctp.h>
-#include <netinet/vinet.h>
#include <libkern/jenkins.h>
@@ -164,29 +163,28 @@ struct flowtable {
};
static struct proc *flowcleanerproc;
-#ifdef VIMAGE_GLOBALS
-static struct flowtable *flow_list_head;
-static uint32_t flow_hashjitter;
-static uma_zone_t flow_ipv4_zone;
-static uma_zone_t flow_ipv6_zone;
-#endif
+static VNET_DEFINE(struct flowtable *, flow_list_head);
+static VNET_DEFINE(uint32_t, flow_hashjitter);
+static VNET_DEFINE(uma_zone_t, flow_ipv4_zone);
+static VNET_DEFINE(uma_zone_t, flow_ipv6_zone);
+
+#define V_flow_list_head VNET_GET(flow_list_head)
+#define V_flow_hashjitter VNET_GET(flow_hashjitter)
+#define V_flow_ipv4_zone VNET_GET(flow_ipv4_zone)
+#define V_flow_ipv6_zone VNET_GET(flow_ipv6_zone)
static int flowtable_iattach(const void *);
#ifdef VIMAGE
static int flowtable_idetach(const void *);
-#endif
-#ifndef VIMAGE_GLOBALS
static const vnet_modinfo_t flowtable_modinfo = {
.vmi_id = VNET_MOD_FLOWTABLE,
.vmi_name = "flowtable",
.vmi_dependson = VNET_MOD_INET,
.vmi_iattach = flowtable_iattach,
-#ifdef VIMAGE
.vmi_idetach = flowtable_idetach
-#endif
};
-#endif /* !VIMAGE_GLOBALS */
+#endif
/*
* TODO:
@@ -205,54 +203,67 @@ static const vnet_modinfo_t flowtable_modinfo = {
* - support explicit connection state (currently only ad-hoc for DSR)
* - idetach() cleanup for options VIMAGE builds.
*/
-#ifdef VIMAGE_GLOBALS
-int flowtable_enable;
-static int flowtable_hits;
-static int flowtable_lookups;
-static int flowtable_misses;
-static int flowtable_frees;
-static int flowtable_free_checks;
-static int flowtable_max_depth;
-static int flowtable_collisions;
-static int flowtable_syn_expire;
-static int flowtable_udp_expire;
-static int flowtable_fin_wait_expire;
-static int flowtable_tcp_expire;
-static int flowtable_nmbflows;
-#endif
+VNET_DEFINE(int, flowtable_enable) = 1;
+static VNET_DEFINE(int, flowtable_hits);
+static VNET_DEFINE(int, flowtable_lookups);
+static VNET_DEFINE(int, flowtable_misses);
+static VNET_DEFINE(int, flowtable_frees);
+static VNET_DEFINE(int, flowtable_free_checks);
+static VNET_DEFINE(int, flowtable_max_depth);
+static VNET_DEFINE(int, flowtable_collisions);
+static VNET_DEFINE(int, flowtable_syn_expire) = SYN_IDLE;
+static VNET_DEFINE(int, flowtable_udp_expire) = UDP_IDLE;
+static VNET_DEFINE(int, flowtable_fin_wait_expire) = FIN_WAIT_IDLE;
+static VNET_DEFINE(int, flowtable_tcp_expire) = TCP_IDLE;
+static VNET_DEFINE(int, flowtable_nmbflows) = 4096;
+
+#define V_flowtable_enable VNET_GET(flowtable_enable)
+#define V_flowtable_hits VNET_GET(flowtable_hits)
+#define V_flowtable_lookups VNET_GET(flowtable_lookups)
+#define V_flowtable_misses VNET_GET(flowtable_misses)
+#define V_flowtable_frees VNET_GET(flowtable_frees)
+#define V_flowtable_free_checks VNET_GET(flowtable_free_checks)
+#define V_flowtable_max_depth VNET_GET(flowtable_max_depth)
+#define V_flowtable_collisions VNET_GET(flowtable_collisions)
+#define V_flowtable_syn_expire VNET_GET(flowtable_syn_expire)
+#define V_flowtable_udp_expire VNET_GET(flowtable_udp_expire)
+#define V_flowtable_fin_wait_expire VNET_GET(flowtable_fin_wait_expire)
+#define V_flowtable_tcp_expire VNET_GET(flowtable_tcp_expire)
+#define V_flowtable_nmbflows VNET_GET(flowtable_nmbflows)
+
SYSCTL_NODE(_net_inet, OID_AUTO, flowtable, CTLFLAG_RD, NULL, "flowtable");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, enable,
- CTLFLAG_RW, flowtable_enable, 0, "enable flowtable caching.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, hits,
- CTLFLAG_RD, flowtable_hits, 0, "# flowtable hits.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, lookups,
- CTLFLAG_RD, flowtable_lookups, 0, "# flowtable lookups.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, misses,
- CTLFLAG_RD, flowtable_misses, 0, "#flowtable misses.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, frees,
- CTLFLAG_RD, flowtable_frees, 0, "#flows freed.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, free_checks,
- CTLFLAG_RD, flowtable_free_checks, 0, "#flows free checks.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, max_depth,
- CTLFLAG_RD, flowtable_max_depth, 0, "max collision list length.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, collisions,
- CTLFLAG_RD, flowtable_collisions, 0, "#flowtable collisions.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, enable, CTLFLAG_RW,
+ &VNET_NAME(flowtable_enable), 0, "enable flowtable caching.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, hits, CTLFLAG_RD,
+ &VNET_NAME(flowtable_hits), 0, "# flowtable hits.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, lookups, CTLFLAG_RD,
+ &VNET_NAME(flowtable_lookups), 0, "# flowtable lookups.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, misses, CTLFLAG_RD,
+ &VNET_NAME(flowtable_misses), 0, "#flowtable misses.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, frees, CTLFLAG_RD,
+ &VNET_NAME(flowtable_frees), 0, "#flows freed.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, free_checks, CTLFLAG_RD,
+ &VNET_NAME(flowtable_free_checks), 0, "#flows free checks.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, max_depth, CTLFLAG_RD,
+ &VNET_NAME(flowtable_max_depth), 0, "max collision list length.");
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, collisions, CTLFLAG_RD,
+ &VNET_NAME(flowtable_collisions), 0, "#flowtable collisions.");
/*
* XXX This does not end up updating timeouts at runtime
* and only reflects the value for the last table added :-/
*/
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, syn_expire,
- CTLFLAG_RW, flowtable_syn_expire, 0,
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, syn_expire, CTLFLAG_RW,
+ &VNET_NAME(flowtable_syn_expire), 0,
"seconds after which to remove syn allocated flow.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, udp_expire,
- CTLFLAG_RW, flowtable_udp_expire, 0,
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, udp_expire, CTLFLAG_RW,
+ &VNET_NAME(flowtable_udp_expire), 0,
"seconds after which to remove flow allocated to UDP.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, fin_wait_expire,
- CTLFLAG_RW, flowtable_fin_wait_expire, 0,
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, fin_wait_expire, CTLFLAG_RW,
+ &VNET_NAME(flowtable_fin_wait_expire), 0,
"seconds after which to remove a flow in FIN_WAIT.");
-SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, tcp_expire,
- CTLFLAG_RW, flowtable_tcp_expire, 0,
+SYSCTL_VNET_INT(_net_inet_flowtable, OID_AUTO, tcp_expire, CTLFLAG_RW,
+ &VNET_NAME(flowtable_tcp_expire), 0,
"seconds after which to remove flow allocated to a TCP connection.");
@@ -266,7 +277,6 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, tcp_expire,
static int
sysctl_nmbflows(SYSCTL_HANDLER_ARGS)
{
- INIT_VNET_INET(curvnet);
int error, newnmbflows;
newnmbflows = V_flowtable_nmbflows;
@@ -283,8 +293,8 @@ sysctl_nmbflows(SYSCTL_HANDLER_ARGS)
}
return (error);
}
-SYSCTL_V_PROC(V_NET, vnet_inet, _net_inet_flowtable, OID_AUTO, nmbflows,
- CTLTYPE_INT|CTLFLAG_RW, flowtable_nmbflows, 0, sysctl_nmbflows, "IU",
+SYSCTL_VNET_PROC(_net_inet_flowtable, OID_AUTO, nmbflows,
+ CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_nmbflows, "IU",
"Maximum number of flows allowed");
#ifndef RADIX_MPATH
@@ -338,7 +348,6 @@ static uint32_t
ipv4_flow_lookup_hash_internal(struct mbuf *m, struct route *ro,
uint32_t *key, uint16_t *flags, uint8_t *protop)
{
- INIT_VNET_INET(curvnet);
uint16_t sport = 0, dport = 0;
struct ip *ip = NULL;
uint8_t proto = 0;
@@ -505,7 +514,6 @@ static int
flowtable_insert(struct flowtable *ft, uint32_t hash, uint32_t *key,
uint8_t proto, struct route *ro, uint16_t flags)
{
- INIT_VNET_INET(curvnet);
struct flentry *fle, *fletail, *newfle, **flep;
int depth;
uma_zone_t flezone;
@@ -596,7 +604,6 @@ flowtable_key_equal(struct flentry *fle, uint32_t *key)
int
flowtable_lookup(struct flowtable *ft, struct mbuf *m, struct route *ro)
{
- INIT_VNET_INET(curvnet);
uint32_t key[9], hash;
struct flentry *fle;
uint16_t flags;
@@ -718,7 +725,6 @@ uncached:
struct flowtable *
flowtable_alloc(int nentry, int flags)
{
- INIT_VNET_INET(curvnet);
struct flowtable *ft, *fttail;
int i;
@@ -800,7 +806,7 @@ static void
flowtable_setup(void *arg)
{
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&flowtable_modinfo);
#else
flowtable_iattach(NULL);
@@ -810,21 +816,6 @@ flowtable_setup(void *arg)
static int
flowtable_iattach(const void *unused __unused)
{
- INIT_VNET_INET(curvnet);
-
- V_flowtable_enable = 1;
- V_flowtable_hits = 0;
- V_flowtable_lookups = 0;
- V_flowtable_misses = 0;
- V_flowtable_frees = 0;
- V_flowtable_free_checks = 0;
- V_flowtable_max_depth = 0;
- V_flowtable_collisions = 0;
- V_flowtable_syn_expire = SYN_IDLE;
- V_flowtable_udp_expire = UDP_IDLE;
- V_flowtable_fin_wait_expire = FIN_WAIT_IDLE;
- V_flowtable_tcp_expire = TCP_IDLE;
- V_flowtable_nmbflows = 4096;
V_flow_ipv4_zone = uma_zcreate("ip4flow", sizeof(struct flentry_v4),
NULL, NULL, NULL, NULL, 64, UMA_ZONE_MAXBUCKET);
@@ -839,7 +830,6 @@ flowtable_iattach(const void *unused __unused)
static int
flowtable_idetach(const void *unused __unused)
{
- INIT_VNET_INET(curvnet);
uma_zdestroy(V_flow_ipv4_zone);
uma_zdestroy(V_flow_ipv6_zone);
@@ -858,7 +848,6 @@ SYSINIT(flowtable_setup, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, flowtable_setup, NUL
static void
fle_free(struct flentry *fle)
{
- INIT_VNET_INET(curvnet);
struct rtentry *rt;
struct llentry *lle;
@@ -873,7 +862,6 @@ fle_free(struct flentry *fle)
static void
flowtable_free_stale(struct flowtable *ft)
{
- INIT_VNET_INET(curvnet);
int curbit = 0, count;
struct flentry *fle, **flehead, *fleprev;
struct flentry *flefreehead, *flefreetail, *fletmp;
@@ -961,7 +949,6 @@ flowtable_free_stale(struct flowtable *ft)
static void
flowtable_clean_vnet(void)
{
- INIT_VNET_INET(curvnet);
struct flowtable *ft;
int i;
diff --git a/sys/net/flowtable.h b/sys/net/flowtable.h
index 26aa11d..13fdfdb 100644
--- a/sys/net/flowtable.h
+++ b/sys/net/flowtable.h
@@ -38,9 +38,8 @@ $FreeBSD$
#define FL_PCPU (1<<1) /* pcpu cache */
struct flowtable;
-#ifdef VIMAGE_GLOBALS
-extern struct flowtable *ip_ft;
-#endif
+VNET_DECLARE(struct flowtable *, ip_ft);
+#define V_ip_ft VNET_GET(ip_ft)
struct flowtable *flowtable_alloc(int nentry, int flags);
diff --git a/sys/net/if.c b/sys/net/if.c
index 4803477..daab1ac 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -84,7 +84,6 @@
#endif
#ifdef INET
#include <netinet/if_ether.h>
-#include <netinet/vinet.h>
#endif
#if defined(INET) || defined(INET6)
#ifdef DEV_CARP
@@ -94,12 +93,6 @@
#include <security/mac/mac_framework.h>
-#ifndef VIMAGE
-#ifndef VIMAGE_GLOBALS
-struct vnet_net vnet_net_0;
-#endif
-#endif
-
struct ifindex_entry {
struct ifnet *ife_ifnet;
};
@@ -162,37 +155,30 @@ static int vnet_net_iattach(const void *);
static int vnet_net_idetach(const void *);
#endif
-#ifdef VIMAGE_GLOBALS
-struct ifnethead ifnet; /* depend on static init XXX */
-struct ifgrouphead ifg_head;
-int if_index;
-static int if_indexlim;
+VNET_DEFINE(struct ifnethead, ifnet); /* depend on static init XXX */
+VNET_DEFINE(struct ifgrouphead, ifg_head);
+VNET_DEFINE(int, if_index);
+static VNET_DEFINE(int, if_indexlim) = 8;
+
/* Table of ifnet by index. Locked with ifnet_lock. */
-static struct ifindex_entry *ifindex_table;
-#endif
+static VNET_DEFINE(struct ifindex_entry *, ifindex_table);
+
+#define V_if_indexlim VNET_GET(if_indexlim)
+#define V_ifindex_table VNET_GET(ifindex_table)
int ifqmaxlen = IFQ_MAXLEN;
struct rwlock ifnet_lock;
static if_com_alloc_t *if_com_alloc[256];
static if_com_free_t *if_com_free[256];
-#ifndef VIMAGE_GLOBALS
-static struct vnet_symmap vnet_net_symmap[] = {
- VNET_SYMMAP(net, ifnet),
- VNET_SYMMAP_END
-};
-
+#ifdef VIMAGE
static const vnet_modinfo_t vnet_net_modinfo = {
.vmi_id = VNET_MOD_NET,
.vmi_name = "net",
- .vmi_size = sizeof(struct vnet_net),
- .vmi_symmap = vnet_net_symmap,
.vmi_iattach = vnet_net_iattach,
-#ifdef VIMAGE
.vmi_idetach = vnet_net_idetach
-#endif
};
-#endif /* !VIMAGE_GLOBALS */
+#endif
/*
* System initialization
@@ -207,7 +193,6 @@ MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
struct ifnet *
ifnet_byindex_locked(u_short idx)
{
- INIT_VNET_NET(curvnet);
if (idx > V_if_index)
return (NULL);
@@ -244,7 +229,6 @@ ifnet_byindex_ref(u_short idx)
static void
ifnet_setbyindex(u_short idx, struct ifnet *ifp)
{
- INIT_VNET_NET(curvnet);
IFNET_WLOCK_ASSERT();
@@ -276,7 +260,7 @@ static void
if_init(void *dummy __unused)
{
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&vnet_net_modinfo);
#else
vnet_net_iattach(NULL);
@@ -289,11 +273,6 @@ if_init(void *dummy __unused)
static int
vnet_net_iattach(const void *unused __unused)
{
- INIT_VNET_NET(curvnet);
-
- V_if_index = 0;
- V_ifindex_table = NULL;
- V_if_indexlim = 8;
TAILQ_INIT(&V_ifnet);
TAILQ_INIT(&V_ifg_head);
@@ -306,7 +285,6 @@ vnet_net_iattach(const void *unused __unused)
static int
vnet_net_idetach(const void *unused __unused)
{
- INIT_VNET_NET(curvnet);
VNET_ASSERT(TAILQ_EMPTY(&V_ifnet));
VNET_ASSERT(TAILQ_EMPTY(&V_ifg_head));
@@ -320,7 +298,6 @@ vnet_net_idetach(const void *unused __unused)
void
if_grow(void)
{
- INIT_VNET_NET(curvnet);
u_int n;
struct ifindex_entry *e;
@@ -354,7 +331,6 @@ if_check(void *dummy __unused)
struct ifnet *
if_alloc(u_char type)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO);
@@ -418,7 +394,6 @@ if_alloc(u_char type)
static void
if_free_internal(struct ifnet *ifp)
{
- INIT_VNET_NET(curvnet); /* ifp->if_vnet is already NULL here */
KASSERT((ifp->if_flags & IFF_DYING),
("if_free_internal: interface not dying"));
@@ -544,7 +519,6 @@ if_attach(struct ifnet *ifp)
static void
if_attach_internal(struct ifnet *ifp, int vmove)
{
- INIT_VNET_NET(curvnet);
unsigned socksize, ifasize;
int namelen, masklen;
struct sockaddr_dl *sdl;
@@ -649,7 +623,6 @@ if_attach_internal(struct ifnet *ifp, int vmove)
static void
if_attachdomain(void *dummy)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
int s;
@@ -769,7 +742,6 @@ if_detach(struct ifnet *ifp)
static void
if_detach_internal(struct ifnet *ifp, int vmove)
{
- INIT_VNET_NET(ifp->if_vnet);
struct ifaddr *ifa;
struct radix_node_head *rnh;
int i, j;
@@ -904,25 +876,17 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
/*
* Unlink the ifnet from ifindex_table[] in current vnet,
* and shrink the if_index for that vnet if possible.
- * do / while construct below is needed to confine the scope
- * of INIT_VNET_NET().
*/
- {
- INIT_VNET_NET(curvnet);
-
- IFNET_WLOCK();
- ifnet_setbyindex(ifp->if_index, NULL);
- while (V_if_index > 0 && \
- ifnet_byindex_locked(V_if_index) == NULL)
- V_if_index--;
- IFNET_WUNLOCK();
- };
+ IFNET_WLOCK();
+ ifnet_setbyindex(ifp->if_index, NULL);
+ while (V_if_index > 0 && ifnet_byindex_locked(V_if_index) == NULL)
+ V_if_index--;
+ IFNET_WUNLOCK();
/*
* Switch to the context of the target vnet.
*/
CURVNET_SET_QUIET(new_vnet);
- INIT_VNET_NET(new_vnet);
/*
* Try to find an empty slot below if_index. If we fail, take
@@ -956,7 +920,6 @@ if_vmove(struct ifnet *ifp, struct vnet *new_vnet)
int
if_addgroup(struct ifnet *ifp, const char *groupname)
{
- INIT_VNET_NET(ifp->if_vnet);
struct ifg_list *ifgl;
struct ifg_group *ifg = NULL;
struct ifg_member *ifgm;
@@ -1026,7 +989,6 @@ if_addgroup(struct ifnet *ifp, const char *groupname)
int
if_delgroup(struct ifnet *ifp, const char *groupname)
{
- INIT_VNET_NET(ifp->if_vnet);
struct ifg_list *ifgl;
struct ifg_member *ifgm;
@@ -1072,7 +1034,6 @@ if_delgroup(struct ifnet *ifp, const char *groupname)
static void
if_delgroups(struct ifnet *ifp)
{
- INIT_VNET_NET(ifp->if_vnet);
struct ifg_list *ifgl;
struct ifg_member *ifgm;
char groupname[IFNAMSIZ];
@@ -1164,7 +1125,6 @@ if_getgroup(struct ifgroupreq *data, struct ifnet *ifp)
static int
if_getgroupmembers(struct ifgroupreq *data)
{
- INIT_VNET_NET(curvnet);
struct ifgroupreq *ifgr = data;
struct ifg_group *ifg;
struct ifg_member *ifgm;
@@ -1336,7 +1296,6 @@ ifa_free(struct ifaddr *ifa)
static struct ifaddr *
ifa_ifwithaddr_internal(struct sockaddr *addr, int getref)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1392,7 +1351,6 @@ ifa_ifwithaddr_check(struct sockaddr *addr)
struct ifaddr *
ifa_ifwithbroadaddr(struct sockaddr *addr)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1426,7 +1384,6 @@ done:
struct ifaddr *
ifa_ifwithdstaddr(struct sockaddr *addr)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifaddr *ifa;
@@ -1460,7 +1417,6 @@ done:
struct ifaddr *
ifa_ifwithnet(struct sockaddr *addr)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifaddr *ifa;
struct ifaddr *ifa_maybe = NULL;
@@ -1841,7 +1797,6 @@ if_slowtimo(void *arg)
VNET_LIST_RLOCK();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- INIT_VNET_NET(vnet_iter);
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp->if_timer == 0 || --ifp->if_timer)
continue;
@@ -1863,7 +1818,6 @@ if_slowtimo(void *arg)
struct ifnet *
ifunit_ref(const char *name)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
IFNET_RLOCK();
@@ -1881,7 +1835,6 @@ ifunit_ref(const char *name)
struct ifnet *
ifunit(const char *name)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
IFNET_RLOCK();
@@ -2478,7 +2431,6 @@ ifpromisc(struct ifnet *ifp, int pswitch)
static int
ifconf(u_long cmd, caddr_t data)
{
- INIT_VNET_NET(curvnet);
struct ifconf *ifc = (struct ifconf *)data;
#ifdef __amd64__
struct ifconf32 *ifc32 = (struct ifconf32 *)data;
@@ -2837,7 +2789,6 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
int lastref;
#ifdef INVARIANTS
struct ifnet *oifp;
- INIT_VNET_NET(ifp->if_vnet);
IFNET_RLOCK();
TAILQ_FOREACH(oifp, &V_ifnet, if_link)
@@ -2878,9 +2829,6 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
void
if_delmulti_ifma(struct ifmultiaddr *ifma)
{
-#ifdef DIAGNOSTIC
- INIT_VNET_NET(curvnet);
-#endif
struct ifnet *ifp;
int lastref;
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 08310d7..945bc5f 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -116,11 +116,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
-#include <netinet/vinet.h>
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
-#include <netinet6/vinet6.h>
#endif
#if defined(INET) || defined(INET6)
#ifdef DEV_CARP
@@ -3042,7 +3040,6 @@ bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
}
if (ip_fw_chk_ptr && pfil_ipfw != 0 && dir == PFIL_OUT && ifp != NULL) {
- INIT_VNET_INET(curvnet);
struct dn_pkt_tag *dn_tag;
error = -1;
@@ -3236,7 +3233,6 @@ bad:
static int
bridge_ip_checkbasic(struct mbuf **mp)
{
- INIT_VNET_INET(curvnet);
struct mbuf *m = *mp;
struct ip *ip;
int len, hlen;
@@ -3332,7 +3328,6 @@ bad:
static int
bridge_ip6_checkbasic(struct mbuf **mp)
{
- INIT_VNET_INET6(curvnet);
struct mbuf *m = *mp;
struct ip6_hdr *ip6;
@@ -3387,7 +3382,6 @@ static int
bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
int snap, struct llc *llc)
{
- INIT_VNET_INET(curvnet);
struct mbuf *m0;
struct ip *ip;
int error = -1;
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index eaa7397..9347d2c 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -58,10 +58,11 @@ static int if_clone_createif(struct if_clone *ifc, char *name, size_t len,
static int vnet_clone_iattach(const void *);
static struct mtx if_cloners_mtx;
-#ifdef VIMAGE_GLOBALS
-static int if_cloners_count;
-LIST_HEAD(, if_clone) if_cloners;
-#endif
+static VNET_DEFINE(int, if_cloners_count);
+VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners);
+
+#define V_if_cloners_count VNET_GET(if_cloners_count)
+#define V_if_cloners VNET_GET(if_cloners)
#define IF_CLONERS_LOCK_INIT() \
mtx_init(&if_cloners_mtx, "if_cloners lock", NULL, MTX_DEF)
@@ -115,17 +116,16 @@ LIST_HEAD(, if_clone) if_cloners;
static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework");
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
static const vnet_modinfo_t vnet_clone_modinfo = {
.vmi_id = VNET_MOD_IF_CLONE,
.vmi_name = "if_clone",
.vmi_iattach = vnet_clone_iattach
};
-#endif /* !VIMAGE_GLOBALS */
+#endif
static int vnet_clone_iattach(const void *unused __unused)
{
- INIT_VNET_NET(curvnet);
LIST_INIT(&V_if_cloners);
return (0);
@@ -136,7 +136,7 @@ if_clone_init(void)
{
IF_CLONERS_LOCK_INIT();
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&vnet_clone_modinfo);
#else
vnet_clone_iattach(NULL);
@@ -149,7 +149,6 @@ if_clone_init(void)
int
if_clone_create(char *name, size_t len, caddr_t params)
{
- INIT_VNET_NET(curvnet);
struct if_clone *ifc;
/* Try to find an applicable cloner for this request */
@@ -162,7 +161,6 @@ if_clone_create(char *name, size_t len, caddr_t params)
#ifdef VIMAGE
if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
CURVNET_SET_QUIET(vnet0);
- INIT_VNET_NET(vnet0);
LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (ifc->ifc_match(ifc, name))
break;
@@ -213,7 +211,6 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params)
int
if_clone_destroy(const char *name)
{
- INIT_VNET_NET(curvnet);
struct if_clone *ifc;
struct ifnet *ifp;
@@ -231,7 +228,6 @@ if_clone_destroy(const char *name)
#ifdef VIMAGE
if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) {
CURVNET_SET_QUIET(vnet0);
- INIT_VNET_NET(vnet0);
LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (ifc->ifc_match(ifc, name))
break;
@@ -289,7 +285,6 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
void
if_clone_attach(struct if_clone *ifc)
{
- INIT_VNET_NET(curvnet);
int len, maxclone;
/*
@@ -322,7 +317,6 @@ if_clone_attach(struct if_clone *ifc)
void
if_clone_detach(struct if_clone *ifc)
{
- INIT_VNET_NET(curvnet);
struct ifc_simple_data *ifcs = ifc->ifc_data;
IF_CLONERS_LOCK();
@@ -362,7 +356,6 @@ if_clone_free(struct if_clone *ifc)
int
if_clone_list(struct if_clonereq *ifcr)
{
- INIT_VNET_NET(curvnet);
char *buf, *dst, *outbuf = NULL;
struct if_clone *ifc;
int buf_count, count, err = 0;
diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c
index e5e7dd8..c0b2d67 100644
--- a/sys/net/if_ef.c
+++ b/sys/net/if_ef.c
@@ -493,7 +493,6 @@ ef_load(void)
VNET_LIST_RLOCK();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- INIT_VNET_NET(vnet_iter);
IFNET_RLOCK();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp->if_type != IFT_ETHER) continue;
diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c
index 38321ff..7b62734 100644
--- a/sys/net/if_enc.c
+++ b/sys/net/if_enc.c
@@ -47,6 +47,7 @@
#include <net/route.h>
#include <net/netisr.h>
#include <net/bpf.h>
+#include <net/vnet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 5e98e53..f7c9042 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -73,7 +73,7 @@
#include <netinet/if_ether.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
-#include <netinet/vinet.h>
+#include <netinet/ip_var.h>
#endif
#ifdef INET6
#include <netinet6/nd6.h>
@@ -148,9 +148,8 @@ MALLOC_DEFINE(M_ARPCOM, "arpcom", "802.* interface internals");
#if defined(INET) || defined(INET6)
int
ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared);
-#ifdef VIMAGE_GLOBALS
-static int ether_ipfw;
-#endif
+static VNET_DEFINE(int, ether_ipfw);
+#define V_ether_ipfw VNET_GET(ether_ipfw)
#endif
@@ -434,7 +433,6 @@ int
ether_output_frame(struct ifnet *ifp, struct mbuf *m)
{
#if defined(INET) || defined(INET6)
- INIT_VNET_NET(ifp->if_vnet);
if (ip_fw_chk_ptr && V_ether_ipfw != 0) {
if (ether_ipfw_chk(&m, ifp, 0) == 0) {
@@ -463,7 +461,6 @@ ether_output_frame(struct ifnet *ifp, struct mbuf *m)
int
ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared)
{
- INIT_VNET_INET(dst->if_vnet);
struct ether_header *eh;
struct ether_header save_eh;
struct mbuf *m;
@@ -774,7 +771,6 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
KASSERT(ifp != NULL, ("%s: NULL interface pointer", __func__));
#if defined(INET) || defined(INET6)
- INIT_VNET_NET(ifp->if_vnet);
/*
* Allow dummynet and/or ipfw to claim the frame.
* Do not do this for PROMISC frames in case we are re-entered.
@@ -994,8 +990,8 @@ ether_ifdetach(struct ifnet *ifp)
SYSCTL_DECL(_net_link);
SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
#if defined(INET) || defined(INET6)
-SYSCTL_V_INT(V_NET, vnet_net, _net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW,
- ether_ipfw, 0, "Pass ether pkts through firewall");
+SYSCTL_VNET_INT(_net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW,
+ &VNET_NAME(ether_ipfw), 0, "Pass ether pkts through firewall");
#endif
#if 0
diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c
index 3b60d2c..cbca740 100644
--- a/sys/net/if_faith.c
+++ b/sys/net/if_faith.c
@@ -77,7 +77,6 @@
#include <netinet6/in6_var.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
-#include <netinet6/vinet6.h>
#endif
#define FAITHNAME "faith"
@@ -328,7 +327,6 @@ static int
faithprefix(in6)
struct in6_addr *in6;
{
- INIT_VNET_INET6(curvnet);
struct rtentry *rt;
struct sockaddr_in6 sin6;
int ret;
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 06a849a..e96cb41 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -95,22 +95,21 @@
static struct mtx gif_mtx;
static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface");
-#ifndef VIMAGE
-#ifndef VIMAGE_GLOBALS
-struct vnet_gif vnet_gif_0;
-#endif
-#endif
+static VNET_DEFINE(LIST_HEAD(, gif_softc), gif_softc_list);
+static VNET_DEFINE(int, max_gif_nesting);
+static VNET_DEFINE(int, parallel_tunnels);
+
+#define V_gif_softc_list VNET_GET(gif_softc_list)
+#define V_max_gif_nesting VNET_GET(max_gif_nesting)
+#define V_parallel_tunnels VNET_GET(parallel_tunnels)
-#ifdef VIMAGE_GLOBALS
-static LIST_HEAD(, gif_softc) gif_softc_list;
-static int max_gif_nesting;
-static int parallel_tunnels;
#ifdef INET
-int ip_gif_ttl;
+VNET_DEFINE(int, ip_gif_ttl);
+#define V_ip_gif_ttl VNET_GET(ip_gif_ttl)
#endif
#ifdef INET6
-int ip6_gif_hlim;
-#endif
+VNET_DEFINE(int, ip6_gif_hlim);
+#define V_ip6_gif_hlim VNET_GET(ip6_gif_hlim)
#endif
void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af);
@@ -123,11 +122,10 @@ static int gif_clone_create(struct if_clone *, int, caddr_t);
static void gif_clone_destroy(struct ifnet *);
static int vnet_gif_iattach(const void *);
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
static const vnet_modinfo_t vnet_gif_modinfo = {
.vmi_id = VNET_MOD_GIF,
.vmi_name = "gif",
- .vmi_size = sizeof(struct vnet_gif),
.vmi_dependson = VNET_MOD_NET,
.vmi_iattach = vnet_gif_iattach
};
@@ -151,13 +149,13 @@ SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0,
*/
#define MAX_GIF_NEST 1
#endif
-SYSCTL_V_INT(V_NET, vnet_gif, _net_link_gif, OID_AUTO, max_nesting,
- CTLFLAG_RW, max_gif_nesting, 0, "Max nested tunnels");
+SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW,
+ &VNET_NAME(max_gif_nesting), 0, "Max nested tunnels");
#ifdef INET6
SYSCTL_DECL(_net_inet6_ip6);
-SYSCTL_V_INT(V_NET, vnet_gif, _net_inet6_ip6, IPV6CTL_GIF_HLIM,
- gifhlim, CTLFLAG_RW, ip6_gif_hlim, 0, "");
+SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_RW,
+ &VNET_NAME(ip6_gif_hlim), 0, "");
#endif
/*
@@ -165,8 +163,8 @@ SYSCTL_V_INT(V_NET, vnet_gif, _net_inet6_ip6, IPV6CTL_GIF_HLIM,
* pair of addresses. Some applications require this functionality so
* we allow control over this check here.
*/
-SYSCTL_V_INT(V_NET, vnet_gif, _net_link_gif, OID_AUTO, parallel_tunnels,
- CTLFLAG_RW, parallel_tunnels, 0, "Allow parallel tunnels?");
+SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW,
+ &VNET_NAME(parallel_tunnels), 0, "Allow parallel tunnels?");
/* copy from src/sys/net/if_ethersubr.c */
static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
@@ -182,7 +180,6 @@ gif_clone_create(ifc, unit, params)
int unit;
caddr_t params;
{
- INIT_VNET_GIF(curvnet);
struct gif_softc *sc;
sc = malloc(sizeof(struct gif_softc), M_GIF, M_WAITOK | M_ZERO);
@@ -265,7 +262,6 @@ gif_clone_destroy(ifp)
static int
vnet_gif_iattach(const void *unused __unused)
{
- INIT_VNET_GIF(curvnet);
LIST_INIT(&V_gif_softc_list);
V_max_gif_nesting = MAX_GIF_NEST;
@@ -295,7 +291,7 @@ gifmodevent(mod, type, data)
case MOD_LOAD:
mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF);
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&vnet_gif_modinfo);
#else
vnet_gif_iattach(NULL);
@@ -419,7 +415,6 @@ gif_output(ifp, m, dst, ro)
struct sockaddr *dst;
struct route *ro;
{
- INIT_VNET_GIF(ifp->if_vnet);
struct gif_softc *sc = ifp->if_softc;
struct m_tag *mtag;
int error = 0;
@@ -944,7 +939,6 @@ gif_set_tunnel(ifp, src, dst)
struct sockaddr *src;
struct sockaddr *dst;
{
- INIT_VNET_GIF(ifp->if_vnet);
struct gif_softc *sc = ifp->if_softc;
struct gif_softc *sc2;
struct sockaddr *osrc, *odst, *sa;
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h
index c8768b5..5257837 100644
--- a/sys/net/if_gif.h
+++ b/sys/net/if_gif.h
@@ -119,34 +119,8 @@ int gif_set_tunnel(struct ifnet *, struct sockaddr *, struct sockaddr *);
void gif_delete_tunnel(struct ifnet *);
int gif_encapcheck(const struct mbuf *, int, int, void *);
-/*
- * Virtualization support
- */
-
-struct vnet_gif {
- LIST_HEAD(, gif_softc) _gif_softc_list;
- int _max_gif_nesting;
- int _parallel_tunnels;
- int _ip_gif_ttl;
- int _ip6_gif_hlim;
-};
-
-#ifndef VIMAGE
-#ifndef VIMAGE_GLOBALS
-extern struct vnet_gif vnet_gif_0;
-#endif
-#endif
-
-#define INIT_VNET_GIF(vnet) \
- INIT_FROM_VNET(vnet, VNET_MOD_GIF, struct vnet_gif, vnet_gif)
-
-#define VNET_GIF(sym) VSYM(vnet_gif, sym)
-
-#define V_gif_softc_list VNET_GIF(gif_softc_list)
-#define V_max_gif_nesting VNET_GIF(max_gif_nesting)
-#define V_parallel_tunnels VNET_GIF(parallel_tunnels)
-#define V_ip_gif_ttl VNET_GIF(ip_gif_ttl)
-#define V_ip6_gif_hlim VNET_GIF(ip6_gif_hlim)
+VNET_DECLARE(int, ip_gif_ttl);
+#define V_ip_gif_ttl VNET_GET(ip_gif_ttl)
#endif /* _KERNEL */
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index e7eb34a..4ed2a9e 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -80,7 +80,6 @@
#include <netinet/ip_gre.h>
#include <netinet/ip_var.h>
#include <netinet/ip_encap.h>
-#include <netinet/vinet.h>
#else
#error "Huh? if_gre without inet?"
#endif
@@ -243,9 +242,6 @@ static int
gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
struct route *ro)
{
-#ifdef INET6
- INIT_VNET_INET(ifp->if_vnet);
-#endif
int error = 0;
struct gre_softc *sc = ifp->if_softc;
struct greip *gh;
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 82c68ff..c2acacd 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -108,25 +108,26 @@ static int vnet_loif_iattach(const void *);
static int vnet_loif_idetach(const void *);
#endif
-#ifdef VIMAGE_GLOBALS
-struct ifnet *loif; /* Used externally */
-#endif
+VNET_DEFINE(struct ifnet *, loif); /* Used externally */
#ifdef VIMAGE
+static VNET_DEFINE(struct ifc_simple_data *, lo_cloner_data);
+static VNET_DEFINE(struct if_clone *, lo_cloner);
+#define V_lo_cloner_data VNET_GET(lo_cloner_data)
+#define V_lo_cloner VNET_GET(lo_cloner)
+
MALLOC_DEFINE(M_LO_CLONER, "lo_cloner", "lo_cloner");
#endif
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
static const vnet_modinfo_t vnet_loif_modinfo = {
.vmi_id = VNET_MOD_LOIF,
.vmi_dependson = VNET_MOD_IF_CLONE,
.vmi_name = "loif",
.vmi_iattach = vnet_loif_iattach,
-#ifdef VIMAGE
.vmi_idetach = vnet_loif_idetach
-#endif
};
-#endif /* !VIMAGE_GLOBALS */
+#endif
IFC_SIMPLE_DECLARE(lo, 1);
@@ -147,7 +148,6 @@ lo_clone_destroy(struct ifnet *ifp)
static int
lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
ifp = if_alloc(IFT_LOOP);
@@ -173,10 +173,7 @@ lo_clone_create(struct if_clone *ifc, int unit, caddr_t params)
static int
vnet_loif_iattach(const void *unused __unused)
{
- INIT_VNET_NET(curvnet);
- V_loif = NULL;
-
#ifdef VIMAGE
V_lo_cloner = malloc(sizeof(*V_lo_cloner), M_LO_CLONER,
M_WAITOK | M_ZERO);
@@ -196,7 +193,6 @@ vnet_loif_iattach(const void *unused __unused)
static int
vnet_loif_idetach(const void *unused __unused)
{
- INIT_VNET_NET(curvnet);
if_clone_detach(V_lo_cloner);
free(V_lo_cloner, M_LO_CLONER);
@@ -213,7 +209,7 @@ loop_modevent(module_t mod, int type, void *data)
switch (type) {
case MOD_LOAD:
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&vnet_loif_modinfo);
#else
vnet_loif_iattach(NULL);
@@ -309,7 +305,6 @@ looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
int
if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen)
{
- INIT_VNET_NET(ifp->if_vnet);
int isr;
M_ASSERTPKTHDR(m);
diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c
index e4c8a98..c0018ef 100644
--- a/sys/net/if_mib.c
+++ b/sys/net/if_mib.c
@@ -67,8 +67,8 @@ SYSCTL_DECL(_net_link_generic);
SYSCTL_NODE(_net_link_generic, IFMIB_SYSTEM, system, CTLFLAG_RW, 0,
"Variables global to all interfaces");
-SYSCTL_V_INT(V_NET, vnet_net, _net_link_generic_system, IFMIB_IFCOUNT,
- ifcount, CTLFLAG_RD, if_index, 0,
+SYSCTL_VNET_INT(_net_link_generic_system, IFMIB_IFCOUNT, ifcount, CTLFLAG_RD,
+ &VNET_NAME(if_index), 0,
"Number of configured interfaces");
static int
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index 0515afc..2c325ee 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -56,7 +56,6 @@
#ifdef INET
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/vinet.h>
#endif
#ifdef INET6
@@ -4937,7 +4936,6 @@ sppp_get_ip_addrs(struct sppp *sp, u_long *src, u_long *dst, u_long *srcmask)
static void
sppp_set_ip_addr(struct sppp *sp, u_long src)
{
- INIT_VNET_INET(curvnet);
STDDCL;
struct ifaddr *ifa;
struct sockaddr_in *si;
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 24e5ca5..ddc5662 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -106,7 +106,6 @@
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/in_var.h>
-#include <netinet/vinet.h>
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
@@ -378,7 +377,6 @@ static struct in6_ifaddr *
stf_getsrcifa6(ifp)
struct ifnet *ifp;
{
- INIT_VNET_INET(ifp->if_vnet);
struct ifaddr *ia;
struct in_ifaddr *ia4;
struct sockaddr_in6 *sin6;
@@ -596,7 +594,6 @@ stf_checkaddr4(sc, in, inifp)
struct in_addr *in;
struct ifnet *inifp; /* incoming interface */
{
- INIT_VNET_INET(curvnet);
struct in_ifaddr *ia4;
/*
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index a995dfd..07914f5 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -80,6 +80,7 @@ struct vnet;
#include <sys/mbuf.h>
#include <sys/eventhandler.h>
#include <sys/buf_ring.h>
+#include <net/vnet.h>
#endif /* _KERNEL */
#include <sys/lock.h> /* XXX */
#include <sys/mutex.h> /* XXX */
@@ -779,11 +780,16 @@ struct ifnet *ifnet_byindex_ref(u_short idx);
*/
struct ifaddr *ifaddr_byindex(u_short idx);
-#ifdef VIMAGE_GLOBALS
-extern struct ifnethead ifnet;
-extern struct ifnet *loif; /* first loopback interface */
-extern int if_index;
-#endif
+VNET_DECLARE(struct ifnethead, ifnet);
+VNET_DECLARE(struct ifgrouphead, ifg_head);
+VNET_DECLARE(int, if_index);
+VNET_DECLARE(struct ifnet *, loif); /* first loopback interface */
+
+#define V_ifnet VNET_GET(ifnet)
+#define V_ifg_head VNET_GET(ifg_head)
+#define V_if_index VNET_GET(if_index)
+#define V_loif VNET_GET(loif)
+
extern int ifqmaxlen;
int if_addgroup(struct ifnet *, const char *);
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 6278396..ac72870 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -576,7 +576,6 @@ MODULE_VERSION(if_vlan, 3);
static struct ifnet *
vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
{
- INIT_VNET_NET(curvnet);
const char *cp;
struct ifnet *ifp;
int t = 0;
diff --git a/sys/net/raw_cb.c b/sys/net/raw_cb.c
index 1dedff8..30a526f 100644
--- a/sys/net/raw_cb.c
+++ b/sys/net/raw_cb.c
@@ -58,9 +58,7 @@
*/
struct mtx rawcb_mtx;
-#ifdef VIMAGE_GLOBALS
-struct rawcb_list_head rawcb_list;
-#endif
+VNET_DEFINE(struct rawcb_list_head, rawcb_list);
SYSCTL_NODE(_net, OID_AUTO, raw, CTLFLAG_RW, 0, "Raw socket infrastructure");
@@ -79,7 +77,6 @@ SYSCTL_ULONG(_net_raw, OID_AUTO, recvspace, CTLFLAG_RW, &raw_recvspace, 0,
int
raw_attach(struct socket *so, int proto)
{
- INIT_VNET_NET(so->so_vnet);
struct rawcb *rp = sotorawcb(so);
int error;
diff --git a/sys/net/raw_cb.h b/sys/net/raw_cb.h
index ffdf731..aa84a05 100644
--- a/sys/net/raw_cb.h
+++ b/sys/net/raw_cb.h
@@ -55,9 +55,9 @@ struct rawcb {
#define RAWRCVQ 8192
#ifdef _KERNEL
-#ifdef VIMAGE_GLOBALS
-extern LIST_HEAD(rawcb_list_head, rawcb) rawcb_list;
-#endif
+VNET_DECLARE(LIST_HEAD(rawcb_list_head, rawcb), rawcb_list);
+#define V_rawcb_list VNET_GET(rawcb_list)
+
extern struct mtx rawcb_mtx;
/*
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c
index 79d3e30..0759e42 100644
--- a/sys/net/raw_usrreq.c
+++ b/sys/net/raw_usrreq.c
@@ -58,7 +58,6 @@ MTX_SYSINIT(rawcb_mtx, &rawcb_mtx, "rawcb", MTX_DEF);
void
raw_init(void)
{
- INIT_VNET_NET(curvnet);
LIST_INIT(&V_rawcb_list);
}
@@ -73,7 +72,6 @@ raw_init(void)
void
raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src)
{
- INIT_VNET_NET(curvnet);
struct rawcb *rp;
struct mbuf *m = m0;
struct socket *last;
diff --git a/sys/net/route.c b/sys/net/route.c
index 750829a..59a5912 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -63,7 +63,6 @@
#include <netinet/in.h>
#include <netinet/ip_mroute.h>
-#include <netinet/vinet.h>
#include <vm/uma.h>
@@ -88,68 +87,29 @@ SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
&rt_add_addr_allfibs, 0, "");
TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
-#ifdef VIMAGE_GLOBALS
-struct radix_node_head *rt_tables;
-static uma_zone_t rtzone; /* Routing table UMA zone. */
-int rttrash; /* routes not in table but not freed */
-struct rtstat rtstat;
-#endif
-
-#ifndef VIMAGE_GLOBALS
-struct vnet_rtable {
- struct radix_node_head *_rt_tables;
- uma_zone_t _rtzone;
- int _rttrash;
- struct rtstat _rtstat;
-};
-
-/* Size guard. See sys/vimage.h. */
-VIMAGE_CTASSERT(SIZEOF_vnet_rtable, sizeof(struct vnet_rtable));
-
-#ifndef VIMAGE
-static struct vnet_rtable vnet_rtable_0;
-#endif
-#endif
-
-/*
- * Symbol translation macros
- */
-#define INIT_VNET_RTABLE(vnet) \
- INIT_FROM_VNET(vnet, VNET_MOD_RTABLE, struct vnet_rtable, vnet_rtable)
+VNET_DEFINE(struct radix_node_head *, rt_tables);
+static VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */
+VNET_DEFINE(int, rttrash); /* routes not in table but not freed */
+VNET_DEFINE(struct rtstat, rtstat);
-#define VNET_RTABLE(sym) VSYM(vnet_rtable, sym)
-
-#define V_rt_tables VNET_RTABLE(rt_tables)
-#define V_rtstat VNET_RTABLE(rtstat)
-#define V_rttrash VNET_RTABLE(rttrash)
-#define V_rtzone VNET_RTABLE(rtzone)
+#define V_rt_tables VNET_GET(rt_tables)
+#define V_rtzone VNET_GET(rtzone)
+#define V_rttrash VNET_GET(rttrash)
+#define V_rtstat VNET_GET(rtstat)
static void rt_maskedcopy(struct sockaddr *,
struct sockaddr *, struct sockaddr *);
static int vnet_route_iattach(const void *);
#ifdef VIMAGE
static int vnet_route_idetach(const void *);
-#endif
-
-#ifndef VIMAGE_GLOBALS
-static struct vnet_symmap vnet_rtable_symmap[] = {
- VNET_SYMMAP(rtable, rt_tables),
- VNET_SYMMAP(rtable, rtstat),
- VNET_SYMMAP(rtable, rttrash),
- VNET_SYMMAP_END
-};
static const vnet_modinfo_t vnet_rtable_modinfo = {
.vmi_id = VNET_MOD_RTABLE,
.vmi_name = "rtable",
- .vmi_size = sizeof(struct vnet_rtable),
- .vmi_symmap = vnet_rtable_symmap,
.vmi_iattach = vnet_route_iattach,
-#ifdef VIMAGE
.vmi_idetach = vnet_route_idetach
-#endif
};
-#endif /* !VIMAGE_GLOBALS */
+#endif
/* compare two sockaddr structures */
#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
@@ -192,7 +152,6 @@ SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
static __inline struct radix_node_head **
rt_tables_get_rnh_ptr(int table, int fam)
{
- INIT_VNET_RTABLE(curvnet);
struct radix_node_head **rnh;
KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
@@ -226,7 +185,7 @@ route_init(void)
rt_numfibs = 1;
rn_init(); /* initialize all zeroes, all ones, mask table */
-#ifndef VIMAGE_GLOBALS
+#ifdef VIMAGE
vnet_mod_register(&vnet_rtable_modinfo);
#else
vnet_route_iattach(NULL);
@@ -236,7 +195,6 @@ route_init(void)
static int
vnet_route_iattach(const void *unused __unused)
{
- INIT_VNET_RTABLE(curvnet);
struct domain *dom;
struct radix_node_head **rnh;
int table;
@@ -382,7 +340,6 @@ struct rtentry *
rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
u_int fibnum)
{
- INIT_VNET_RTABLE(curvnet);
struct radix_node_head *rnh;
struct rtentry *rt;
struct radix_node *rn;
@@ -452,7 +409,6 @@ done:
void
rtfree(struct rtentry *rt)
{
- INIT_VNET_RTABLE(curvnet);
struct radix_node_head *rnh;
KASSERT(rt != NULL,("%s: NULL rt", __func__));
@@ -551,7 +507,6 @@ rtredirect_fib(struct sockaddr *dst,
struct sockaddr *src,
u_int fibnum)
{
- INIT_VNET_RTABLE(curvnet);
struct rtentry *rt, *rt0 = NULL;
int error = 0;
short *stat = NULL;
@@ -880,7 +835,6 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
int
rtexpunge(struct rtentry *rt)
{
- INIT_VNET_RTABLE(curvnet);
struct radix_node *rn;
struct radix_node_head *rnh;
struct ifaddr *ifa;
@@ -1018,8 +972,6 @@ gwdelete:
RT_LOCK(rt);
RT_ADDREF(rt);
if (req == RTM_DELETE) {
- INIT_VNET_RTABLE(curvnet);
-
rt->rt_flags &= ~RTF_UP;
/*
* One more rtentry floating around that is not
@@ -1027,7 +979,6 @@ gwdelete:
* when RTFREE(rt) is eventually called.
*/
V_rttrash++;
-
}
nondelete:
@@ -1054,7 +1005,6 @@ int
rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
u_int fibnum)
{
- INIT_VNET_RTABLE(curvnet);
int error = 0, needlock = 0;
register struct rtentry *rt;
register struct radix_node *rn;
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 532070d..bdea325 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1238,7 +1238,6 @@ rt_ifannouncemsg(struct ifnet *ifp, int what)
static void
rt_dispatch(struct mbuf *m, const struct sockaddr *sa)
{
- INIT_VNET_NET(curvnet);
struct m_tag *tag;
/*
@@ -1317,7 +1316,6 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
static int
sysctl_iflist(int af, struct walkarg *w)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifaddr *ifa;
struct rt_addrinfo info;
@@ -1378,7 +1376,6 @@ done:
static int
sysctl_ifmalist(int af, struct walkarg *w)
{
- INIT_VNET_NET(curvnet);
struct ifnet *ifp;
struct ifmultiaddr *ifma;
struct rt_addrinfo info;
diff --git a/sys/net/vnet.c b/sys/net/vnet.c
new file mode 100644
index 0000000..a314886
--- /dev/null
+++ b/sys/net/vnet.c
@@ -0,0 +1,341 @@
+/*-
+ * Copyright (c) 2009 Jeffrey Roberson <jeff@freebsd.org>
+ * Copyright (c) 2009 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.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/sx.h>
+#include <sys/sysctl.h>
+#include <sys/vimage.h>
+
+#include <net/vnet.h>
+
+/*-
+ * This is the virtual network stack allocator, which 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' linker set. The details of the implementation are somewhat
+ * subtle, but allow the majority of most network subsystems to maintain
+ * virtualization-agnostic.
+ *
+ * The virtual network stack allocator handles variables in the base kernel
+ * vs. modules in similar but different ways. In both cases, virtualized
+ * global variables are marked as such by being declared to be part of the
+ * vnet linker set. These "master" copies of global variables serve two
+ * functions:
+ *
+ * (1) They contain static initialization or "default" values for global
+ * variables which will be propagated to each virtual network stack
+ * instance when created. As with normal global variables, they default
+ * to zero-filled.
+ *
+ * (2) They act as unique global names by which the variable can be referred
+ * to, regardless of network stack instance. The single global symbol
+ * will be used to calculate the location of a per-virtual instance
+ * variable at run-time.
+ *
+ * Each virtual network stack instance has a complete copy of each
+ * virtualized global variable, stored in a malloc'd block of memory
+ * referred to by vnet->vnet_data_mem. Critical to the design is that each
+ * per-instance memory block is laid out identically to the master block so
+ * that the offset of each global variable is the same across all blocks. To
+ * optimize run-time access, a precalculated 'base' address,
+ * vnet->vnet_data_base, is stored in each vnet, and is the amount that can
+ * be added to the address of a 'master' instance of a variable to get to the
+ * per-vnet instance.
+ *
+ * Virtualized global variables are handled in a similar manner, but as each
+ * module has its own 'set_vnet' linker set, and we want to keep all
+ * virtualized globals togther, we reserve space in the kernel's linker set
+ * for potential module variables using a per-vnet character array,
+ * 'modspace'. The virtual network stack allocator maintains a free list to
+ * track what space in the array is free (all, initially) and as modules are
+ * linked, allocates portions of the space to specific globals. The kernel
+ * module linker queries the virtual network stack allocator and will
+ * bind references of the global to the location during linking. It also
+ * calls into the virtual network stack allocator, once the memory is
+ * initialized, in order to propagate the new static initializations to all
+ * existing virtual network stack instances so that the soon-to-be executing
+ * module will find every network stack instance with proper default values.
+ */
+
+/*
+ * Location of the kernel's 'set_vnet' linker set.
+ */
+extern uintptr_t *__start_set_vnet;
+extern uintptr_t *__stop_set_vnet;
+
+#define VNET_START (uintptr_t)&__start_set_vnet
+#define VNET_STOP (uintptr_t)&__stop_set_vnet
+
+/*
+ * Number of bytes of data in the 'set_vnet' linker set, and hence the total
+ * size of all kernel virtualized global variables, and the malloc(9) type
+ * that will be used to allocate it.
+ */
+#define VNET_BYTES (VNET_STOP - VNET_START)
+
+MALLOC_DEFINE(M_VNET_DATA, "vnet_data", "VNET data");
+
+/*
+ * VNET_MODMIN is the minimum number of bytes we will reserve for the sum of
+ * global variables across all loaded modules. As this actually sizes an
+ * array declared as a virtualized global variable in the kernel itself, and
+ * we want the virtualized global variable space to be page-sized, we may
+ * have more space than that in practice.
+ */
+#define VNET_MODMIN 8192
+#define VNET_SIZE roundup2(VNET_BYTES, PAGE_SIZE)
+#define VNET_MODSIZE (VNET_SIZE - (VNET_BYTES - VNET_MODMIN))
+
+/*
+ * Space to store virtualized global variables from loadable kernel modules,
+ * and the free list to manage it.
+ */
+static VNET_DEFINE(char, modspace[VNET_MODMIN]);
+
+struct vnet_data_free {
+ uintptr_t vnd_start;
+ int vnd_len;
+ TAILQ_ENTRY(vnet_data_free) vnd_link;
+};
+
+MALLOC_DEFINE(M_VNET_DATA_FREE, "vnet_data_free", "VNET resource accounting");
+static TAILQ_HEAD(, vnet_data_free) vnet_data_free_head =
+ TAILQ_HEAD_INITIALIZER(vnet_data_free_head);
+static struct sx vnet_data_free_lock;
+
+/*
+ * Allocate storage for virtualized global variables in a new virtual network
+ * stack instance, and copy in initial values from our 'master' copy.
+ */
+void
+vnet_data_init(struct vnet *vnet)
+{
+
+ vnet->vnet_data_mem = malloc(VNET_SIZE, M_VNET_DATA, M_WAITOK);
+ memcpy(vnet->vnet_data_mem, (void *)VNET_START, VNET_BYTES);
+
+ /*
+ * All use of vnet-specific data will immediately subtract VNET_START
+ * from the base memory pointer, so pre-calculate that now to avoid
+ * it on each use.
+ */
+ vnet->vnet_data_base = (uintptr_t)vnet->vnet_data_mem - VNET_START;
+}
+
+/*
+ * Release storage for a virtual network stack instance.
+ */
+void
+vnet_data_destroy(struct vnet *vnet)
+{
+
+ free(vnet->vnet_data_mem, M_VNET_DATA);
+ vnet->vnet_data_mem = NULL;
+ vnet->vnet_data_base = 0;
+}
+
+/*
+ * Once on boot, initialize the modspace freelist to entirely cover modspace.
+ */
+static void
+vnet_data_startup(void *dummy __unused)
+{
+ struct vnet_data_free *df;
+
+ df = malloc(sizeof(*df), M_VNET_DATA_FREE, M_WAITOK | M_ZERO);
+ df->vnd_start = (uintptr_t)&VNET_NAME(modspace);
+ df->vnd_len = VNET_MODSIZE;
+ TAILQ_INSERT_HEAD(&vnet_data_free_head, df, vnd_link);
+ sx_init(&vnet_data_free_lock, "vnet_data alloc lock");
+}
+SYSINIT(vnet_data, SI_SUB_KLD, SI_ORDER_FIRST, vnet_data_startup, 0);
+
+/*
+ * When a module is loaded and requires storage for a virtualized global
+ * variable, allocate space from the modspace free list. This interface
+ * should be used only by the kernel linker.
+ */
+void *
+vnet_data_alloc(int size)
+{
+ struct vnet_data_free *df;
+ void *s;
+
+ s = NULL;
+ size = roundup2(size, sizeof(void *));
+ sx_xlock(&vnet_data_free_lock);
+ TAILQ_FOREACH(df, &vnet_data_free_head, vnd_link) {
+ if (df->vnd_len < size)
+ continue;
+ if (df->vnd_len == size) {
+ s = (void *)df->vnd_start;
+ TAILQ_REMOVE(&vnet_data_free_head, df, vnd_link);
+ free(df, M_VNET_DATA_FREE);
+ break;
+ }
+ s = (void *)df->vnd_start;
+ df->vnd_len -= size;
+ df->vnd_start = df->vnd_start + size;
+ break;
+ }
+ sx_xunlock(&vnet_data_free_lock);
+
+ return (s);
+}
+
+/*
+ * Free space for a virtualized global variable on module unload.
+ */
+void
+vnet_data_free(void *start_arg, int size)
+{
+ struct vnet_data_free *df;
+ struct vnet_data_free *dn;
+ uintptr_t start;
+ uintptr_t end;
+
+ size = roundup2(size, sizeof(void *));
+ start = (uintptr_t)start_arg;
+ end = start + size;
+ /*
+ * Free a region of space and merge it with as many neighbors as
+ * possible. Keeping the list sorted simplifies this operation.
+ */
+ sx_xlock(&vnet_data_free_lock);
+ TAILQ_FOREACH(df, &vnet_data_free_head, vnd_link) {
+ if (df->vnd_start > end)
+ break;
+ /*
+ * If we expand at the end of an entry we may have to
+ * merge it with the one following it as well.
+ */
+ if (df->vnd_start + df->vnd_len == start) {
+ df->vnd_len += size;
+ dn = TAILQ_NEXT(df, vnd_link);
+ if (df->vnd_start + df->vnd_len == dn->vnd_start) {
+ df->vnd_len += dn->vnd_len;
+ TAILQ_REMOVE(&vnet_data_free_head, dn, vnd_link);
+ free(dn, M_VNET_DATA_FREE);
+ }
+ sx_xunlock(&vnet_data_free_lock);
+ return;
+ }
+ if (df->vnd_start == end) {
+ df->vnd_start = start;
+ df->vnd_len += size;
+ sx_xunlock(&vnet_data_free_lock);
+ return;
+ }
+ }
+ dn = malloc(sizeof(*df), M_VNET_DATA_FREE, M_WAITOK | M_ZERO);
+ dn->vnd_start = start;
+ dn->vnd_len = size;
+ if (df)
+ TAILQ_INSERT_BEFORE(df, dn, vnd_link);
+ else
+ TAILQ_INSERT_TAIL(&vnet_data_free_head, dn, vnd_link);
+ sx_xunlock(&vnet_data_free_lock);
+}
+
+struct vnet_data_copy_fn_arg {
+ void *start;
+ int size;
+};
+
+static void
+vnet_data_copy_fn(struct vnet *vnet, void *arg)
+{
+ struct vnet_data_copy_fn_arg *varg = arg;
+
+ memcpy((void *)((uintptr_t)vnet->vnet_data_base +
+ (uintptr_t)varg->start), varg->start, varg->size);
+}
+
+/*
+ * When a new virtualized global variable has been allocated, propagate its
+ * initial value to each already-allocated virtual network stack instance.
+ */
+void
+vnet_data_copy(void *start, int size)
+{
+ struct vnet_data_copy_fn_arg varg;
+
+ varg.start = start;
+ varg.size = size;
+ vnet_foreach(vnet_data_copy_fn, &varg);
+}
+
+/*
+ * Variants on sysctl_handle_foo that know how to handle virtualized global
+ * variables: if 'arg1' is a pointer, then we transform it to the local vnet
+ * offset.
+ */
+int
+vnet_sysctl_handle_int(SYSCTL_HANDLER_ARGS)
+{
+
+ if (arg1 != NULL)
+ arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
+ return (sysctl_handle_int(oidp, arg1, arg2, req));
+}
+
+int
+vnet_sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
+{
+
+ if (arg1 != NULL)
+ arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
+ return (sysctl_handle_opaque(oidp, arg1, arg2, req));
+}
+
+int
+vnet_sysctl_handle_string(SYSCTL_HANDLER_ARGS)
+{
+
+ if (arg1 != NULL)
+ arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
+ return (sysctl_handle_string(oidp, arg1, arg2, req));
+}
+
+int
+vnet_sysctl_handle_uint(SYSCTL_HANDLER_ARGS)
+{
+
+ if (arg1 != NULL)
+ arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
+ return (sysctl_handle_int(oidp, arg1, arg2, req));
+}
diff --git a/sys/net/vnet.h b/sys/net/vnet.h
index b5d2fbd..4b543e6 100644
--- a/sys/net/vnet.h
+++ b/sys/net/vnet.h
@@ -1,10 +1,6 @@
/*-
- * Copyright (c) 2006-2008 University of Zagreb
- * Copyright (c) 2006-2008 FreeBSD Foundation
- *
- * 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
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,62 +26,131 @@
* $FreeBSD$
*/
+/*
+ * This is the virtual network stack memory allocator, which provides support
+ * for virtualized global variables via a special linker set, set_vnet. When
+ * "options VIMAGE" isn't defined, virtualized global variables are compiled
+ * as normal globals.
+ */
+
#ifndef _NET_VNET_H_
#define _NET_VNET_H_
-#include <net/if_var.h>
+#ifdef _KERNEL
+#ifdef VIMAGE
+
+#if defined(__arm__)
+__asm__(".section set_vnet, \"aw\", %progbits");
+#else
+__asm__(".section set_vnet, \"aw\", @progbits");
+#endif
+__asm__(".previous");
+
+#define VNET_NAME(n) vnet_entry_##n
+#define VNET_DECLARE(t, n) extern t VNET_NAME(n)
+#define VNET_DEFINE(t, n) t VNET_NAME(n) __section("set_vnet") __used
+#define _VNET_PTR(b, n) (__typeof(VNET_NAME(n))*) \
+ ((b) + (uintptr_t)&VNET_NAME(n))
+
+#define _VNET_GET(b, n) (*_VNET_PTR(b, n))
+#define _VNET_SET(b, n, v) (*_VNET_PTR(b, n) = v)
-struct ifindex_entry;
+/*
+ * Virtualized global variable accessor macros.
+ */
+#define VNET_VNET_PTR(vnet, n) _VNET_PTR((vnet)->vnet_data_base, n)
+#define VNET_VNET_GET(vnet, n) (*VNET_VNET_PTR((vnet), n))
+#define VNET_VNET_SET(vnet, n, v) ((*VNET_VNET_PTR((vnet), n)) = v)
-struct vnet_net {
- int _if_index;
- struct ifindex_entry * _ifindex_table;
- struct ifnethead _ifnet;
- struct ifgrouphead _ifg_head;
+#define VNET_PTR(n) VNET_VNET_PTR(curvnet, n)
+#define VNET_GET(n) VNET_VNET_GET(curvnet, n)
+#define VNET_SET(n, v) VNET_VNET_SET(curvnet, n, v)
- int _if_indexlim;
+/*
+ * Sysctl variants for vnet-virtualized global variables. Include
+ * <sys/sysctl.h> to expose these definitions.
+ *
+ * Note: SYSCTL_PROC() handler functions will need to resolve pointer
+ * arguments themselves, if required.
+ */
+#ifdef SYSCTL_OID
+int vnet_sysctl_handle_int(SYSCTL_HANDLER_ARGS);
+int vnet_sysctl_handle_opaque(SYSCTL_HANDLER_ARGS);
+int vnet_sysctl_handle_string(SYSCTL_HANDLER_ARGS);
+int vnet_sysctl_handle_uint(SYSCTL_HANDLER_ARGS);
- struct ifnet * _loif;
- struct if_clone * _lo_cloner;
- struct ifc_simple_data *_lo_cloner_data;
+#define SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|CTLFLAG_MPSAFE|(access), \
+ ptr, val, vnet_sysctl_handle_int, "I", descr)
+#define SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler, \
+ fmt, descr) \
+ SYSCTL_OID(parent, nbr, name, access, ptr, arg, handler, fmt, \
+ descr)
+#define SYSCTL_VNET_STRING(parent, nbr, name, access, arg, len, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_STRING|(access), arg, \
+ len, vnet_sysctl_handle_string, "A", descr)
+#define SYSCTL_VNET_STRUCT(parent, nbr, name, access, ptr, type, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_OPAQUE|(access), ptr, \
+ sizeof(struct type), vnet_sysctl_handle_opaque, "S," #type, \
+ descr)
+#define SYSCTL_VNET_UINT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_OID(parent, nbr, name, CTLTYPE_UINT|CTLFLAG_MPSAFE|(access), \
+ ptr, val, vnet_sysctl_handle_uint, "IU", descr)
+#endif /* SYSCTL_OID */
- LIST_HEAD(, rawcb) _rawcb_list;
+/*
+ * 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);
- LIST_HEAD(, if_clone) _if_cloners;
- int _if_cloners_count;
+/*
+ * Interfaces for vnet setup/teardown.
+ */
+struct vnet;
+void vnet_data_init(struct vnet *vnet);
+void vnet_data_destroy(struct vnet *vnet);
- int _ether_ipfw;
-};
+#else /* !VIMAGE */
-/* Size guard. See sys/vimage.h. */
-VIMAGE_CTASSERT(SIZEOF_vnet_net, sizeof(struct vnet_net));
+/*
+ * Versions of the VNET macros that compile to normal global variables and
+ * standard sysctl definitions.
+ */
+#define VNET_NAME(n) n
+#define VNET_DECLARE(t, n) extern t n
+#define VNET_DEFINE(t, n) t n
+#define _VNET_PTR(b, n) &VNET_NAME(n)
-#ifndef VIMAGE
-#ifndef VIMAGE_GLOBALS
-extern struct vnet_net vnet_net_0;
-#endif
-#endif
+#ifdef SYSCTL_OID
+#define SYSCTL_VNET_INT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_INT(parent, nbr, name, access, ptr, val, descr)
+#define SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler, \
+ fmt, descr) \
+ SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, \
+ descr)
+#define SYSCTL_VNET_STRING(parent, nbr, name, access, arg, len, descr) \
+ SYSCTL_STRING(parent, nbr, name, access, arg, len, descr)
+#define SYSCTL_VNET_STRUCT(parent, nbr, name, access, ptr, type, descr) \
+ SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr)
+#define SYSCTL_VNET_UINT(parent, nbr, name, access, ptr, val, descr) \
+ SYSCTL_UINT(parent, nbr, name, access, ptr, val, descr)
+#endif /* SYSCTL_OID */
/*
- * Symbol translation macros
+ * Virtualized global variable accessor macros.
*/
-#define INIT_VNET_NET(vnet) \
- INIT_FROM_VNET(vnet, VNET_MOD_NET, struct vnet_net, vnet_net)
-
-#define VNET_NET(sym) VSYM(vnet_net, sym)
-
-#define V_ether_ipfw VNET_NET(ether_ipfw)
-#define V_if_index VNET_NET(if_index)
-#define V_if_indexlim VNET_NET(if_indexlim)
-#define V_if_cloners VNET_NET(if_cloners)
-#define V_if_cloners_count VNET_NET(if_cloners_count)
-#define V_ifg_head VNET_NET(ifg_head)
-#define V_ifindex_table VNET_NET(ifindex_table)
-#define V_ifklist VNET_NET(ifklist)
-#define V_ifnet VNET_NET(ifnet)
-#define V_lo_cloner VNET_NET(lo_cloner)
-#define V_lo_cloner_data VNET_NET(lo_cloner_data)
-#define V_loif VNET_NET(loif)
-#define V_rawcb_list VNET_NET(rawcb_list)
+#define VNET_VNET_PTR(vnet, n) (&(n))
+#define VNET_VNET_GET(vnet, n) (n)
+#define VNET_VNET_SET(vnet, n, v) ((n) = (v))
+
+#define VNET_PTR(n) (&(n))
+#define VNET_GET(n) (n)
+#define VNET_SET(n, v) ((n) = (v))
+
+#endif /* VIMAGE */
+
+#endif /* _KERNEL */
#endif /* !_NET_VNET_H_ */
OpenPOWER on IntegriCloud