summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UPDATING5
-rw-r--r--sys/kern/kern_vimage.c5
-rw-r--r--sys/net/if_clone.c84
-rw-r--r--sys/net/if_loop.c13
-rw-r--r--sys/net/vnet.h37
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/vimage.h2
7 files changed, 118 insertions, 30 deletions
diff --git a/UPDATING b/UPDATING
index 8ef1991..85a005a 100644
--- a/UPDATING
+++ b/UPDATING
@@ -23,6 +23,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
ln -s aj /etc/malloc.conf.)
20090523:
+ The layout of struct vnet_net has changed, therefore modules
+ need to be rebuilt.
+ Bump __FreeBSD_version to 800090.
+
+20090523:
The newly imported zic(8) produces a new format in the
output. Please run tzsetup(8) to install the newly created
data to /etc/localtime.
diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c
index d4c48b5..7cb6d84 100644
--- a/sys/kern/kern_vimage.c
+++ b/sys/kern/kern_vimage.c
@@ -66,6 +66,10 @@ struct vprocg vprocg_0;
#endif
#endif
+#ifdef VIMAGE
+struct vnet *vnet0;
+#endif
+
void
vnet_mod_register(const struct vnet_modinfo *vmi)
{
@@ -331,6 +335,7 @@ vi_init(void *unused)
LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le);
vnet->vnet_magic_n = VNET_MAGIC_N;
vip->v_net = vnet;
+ vnet0 = vnet;
/* We MUST clear curvnet in vi_init_done before going SMP. */
curvnet = LIST_FIRST(&vnet_head);
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index a0140fc..eaa7397 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -55,10 +55,13 @@
static void if_clone_free(struct if_clone *ifc);
static int if_clone_createif(struct if_clone *ifc, char *name, size_t len,
caddr_t params);
+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 = LIST_HEAD_INITIALIZER(if_cloners);
+LIST_HEAD(, if_clone) if_cloners;
+#endif
#define IF_CLONERS_LOCK_INIT() \
mtx_init(&if_cloners_mtx, "if_cloners lock", NULL, MTX_DEF)
@@ -112,10 +115,32 @@ LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework");
+#ifndef VIMAGE_GLOBALS
+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 */
+
+static int vnet_clone_iattach(const void *unused __unused)
+{
+ INIT_VNET_NET(curvnet);
+
+ LIST_INIT(&V_if_cloners);
+ return (0);
+}
+
void
if_clone_init(void)
{
+
IF_CLONERS_LOCK_INIT();
+#ifndef VIMAGE_GLOBALS
+ vnet_mod_register(&vnet_clone_modinfo);
+#else
+ vnet_clone_iattach(NULL);
+#endif
}
/*
@@ -124,15 +149,27 @@ 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 */
IF_CLONERS_LOCK();
- LIST_FOREACH(ifc, &if_cloners, ifc_list) {
+ LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (ifc->ifc_match(ifc, name)) {
break;
}
}
+#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;
+ }
+ CURVNET_RESTORE();
+ }
+#endif
IF_CLONERS_UNLOCK();
if (ifc == NULL)
@@ -176,6 +213,7 @@ 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;
@@ -185,11 +223,22 @@ if_clone_destroy(const char *name)
/* Find the cloner for this interface */
IF_CLONERS_LOCK();
- LIST_FOREACH(ifc, &if_cloners, ifc_list) {
+ LIST_FOREACH(ifc, &V_if_cloners, ifc_list) {
if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) {
break;
}
}
+#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;
+ }
+ CURVNET_RESTORE();
+ }
+#endif
IF_CLONERS_UNLOCK();
if (ifc == NULL)
return (EINVAL);
@@ -208,11 +257,17 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
if (ifc->ifc_destroy == NULL)
return(EOPNOTSUPP);
+ /*
+ * Given that the cloned ifnet might be attached to a different
+ * vnet from where its cloner was registered, we have to
+ * switch to the vnet context of the target vnet.
+ */
+ CURVNET_SET_QUIET(ifp->if_vnet);
+
IF_CLONE_LOCK(ifc);
IFC_IFLIST_REMOVE(ifc, ifp);
IF_CLONE_UNLOCK(ifc);
- CURVNET_SET_QUIET(ifp->if_vnet);
if_delgroup(ifp, ifc->ifc_name);
err = (*ifc->ifc_destroy)(ifc, ifp);
@@ -234,6 +289,7 @@ 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;
/*
@@ -249,8 +305,8 @@ if_clone_attach(struct if_clone *ifc)
IF_CLONE_ADDREF(ifc);
IF_CLONERS_LOCK();
- LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
- if_cloners_count++;
+ LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list);
+ V_if_cloners_count++;
IF_CLONERS_UNLOCK();
LIST_INIT(&ifc->ifc_iflist);
@@ -266,11 +322,12 @@ 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();
LIST_REMOVE(ifc, ifc_list);
- if_cloners_count--;
+ V_if_cloners_count--;
IF_CLONERS_UNLOCK();
/* Allow all simples to be destroyed */
@@ -305,6 +362,7 @@ 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;
@@ -321,23 +379,23 @@ if_clone_list(struct if_clonereq *ifcr)
* could be because that would let arbitrary users cause us to
* allocate abritrary amounts of kernel memory.
*/
- buf_count = (if_cloners_count < ifcr->ifcr_count) ?
- if_cloners_count : ifcr->ifcr_count;
+ buf_count = (V_if_cloners_count < ifcr->ifcr_count) ?
+ V_if_cloners_count : ifcr->ifcr_count;
IF_CLONERS_UNLOCK();
outbuf = malloc(IFNAMSIZ*buf_count, M_CLONE, M_WAITOK | M_ZERO);
IF_CLONERS_LOCK();
- ifcr->ifcr_total = if_cloners_count;
+ ifcr->ifcr_total = V_if_cloners_count;
if ((dst = ifcr->ifcr_buffer) == NULL) {
/* Just asking how many there are. */
goto done;
}
- count = (if_cloners_count < buf_count) ?
- if_cloners_count : buf_count;
+ count = (V_if_cloners_count < buf_count) ?
+ V_if_cloners_count : buf_count;
- for (ifc = LIST_FIRST(&if_cloners), buf = outbuf;
+ for (ifc = LIST_FIRST(&V_if_cloners), buf = outbuf;
ifc != NULL && count != 0;
ifc = LIST_NEXT(ifc, ifc_list), count--, buf += IFNAMSIZ) {
strlcpy(buf, ifc->ifc_name, IFNAMSIZ);
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 3319ed8..cc9251b 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -111,9 +111,14 @@ static int vnet_loif_iattach(const void *);
struct ifnet *loif; /* Used externally */
#endif
+#ifdef VIMAGE
+MALLOC_DEFINE(M_LO_CLONER, "lo_cloner", "lo_cloner");
+#endif
+
#ifndef VIMAGE_GLOBALS
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
};
@@ -167,7 +172,15 @@ 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);
+ bcopy(&lo_cloner, V_lo_cloner, sizeof(*V_lo_cloner));
+ if_clone_attach(V_lo_cloner);
+#else
if_clone_attach(&lo_cloner);
+#endif
return (0);
}
diff --git a/sys/net/vnet.h b/sys/net/vnet.h
index 662586a..bdc466b 100644
--- a/sys/net/vnet.h
+++ b/sys/net/vnet.h
@@ -31,7 +31,7 @@
*/
#ifndef _NET_VNET_H_
-#define _NET_VNET_H_
+#define _NET_VNET_H_
#include <net/if_var.h>
@@ -50,10 +50,13 @@ struct vnet_net {
uma_zone_t _rtzone;
struct ifnet * _loif;
- LIST_HEAD(, lo_softc) _lo_list;
+ struct if_clone * _lo_cloner;
LIST_HEAD(, rawcb) _rawcb_list;
+ LIST_HEAD(, if_clone) _if_cloners;
+ int _if_cloners_count;
+
int _ether_ipfw;
};
@@ -74,19 +77,21 @@ extern struct vnet_net vnet_net_0;
#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_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_list VNET_NET(lo_list)
-#define V_loif VNET_NET(loif)
-#define V_rawcb_list VNET_NET(rawcb_list)
-#define V_rt_tables VNET_NET(rt_tables)
-#define V_rtstat VNET_NET(rtstat)
-#define V_rttrash VNET_NET(rttrash)
-#define V_rtzone VNET_NET(rtzone)
+#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_loif VNET_NET(loif)
+#define V_rawcb_list VNET_NET(rawcb_list)
+#define V_rt_tables VNET_NET(rt_tables)
+#define V_rtstat VNET_NET(rtstat)
+#define V_rttrash VNET_NET(rttrash)
+#define V_rtzone VNET_NET(rtzone)
#endif /* !_NET_VNET_H_ */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 19dc83e..eb8c57f 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800089 /* Master, propagated to newvers */
+#define __FreeBSD_version 800090 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h
index b2c0bc1..888e114 100644
--- a/sys/sys/vimage.h
+++ b/sys/sys/vimage.h
@@ -95,6 +95,7 @@ struct vnet_modlink {
#define VNET_MOD_MLD 13
/* Stateless modules. */
+#define VNET_MOD_IF_CLONE 19
#define VNET_MOD_NG_ETHER 20
#define VNET_MOD_NG_IFACE 21
#define VNET_MOD_NG_EIFACE 22
@@ -271,6 +272,7 @@ extern struct vprocg vprocg_0;
#ifdef VIMAGE
LIST_HEAD(vnet_list_head, vnet);
extern struct vnet_list_head vnet_head;
+extern struct vnet *vnet0;
#define VNET_ITERATOR_DECL(arg) struct vnet *arg;
#define VNET_FOREACH(arg) LIST_FOREACH(arg, &vnet_head, vnet_le)
#else
OpenPOWER on IntegriCloud