summaryrefslogtreecommitdiffstats
path: root/sys/net/if_vlan.c
diff options
context:
space:
mode:
authorzec <zec@FreeBSD.org>2010-11-22 23:35:29 +0000
committerzec <zec@FreeBSD.org>2010-11-22 23:35:29 +0000
commit163ca01105dd047c9f3d794b45bbb97881fbabf8 (patch)
tree5bbe2d3ca2b78830c571881bda6246319b620527 /sys/net/if_vlan.c
parent36ae5df8ce79c0f84c14d7eb7ef55f75876fb3e4 (diff)
downloadFreeBSD-src-163ca01105dd047c9f3d794b45bbb97881fbabf8.zip
FreeBSD-src-163ca01105dd047c9f3d794b45bbb97881fbabf8.tar.gz
Allow for vlan(4) ifnets to have overlapping unit numbers if they are
created in separated vnets. As a side-effect of having a separated if_cloner instance for each vnet, all vlan ifnets created in a vnet will be automatically destroyed when vnet teardown is initiated. Disallow SIOCSETVLAN and SIOCGETVLAN ioctls on vlan ifnets which are associated with physical ifnets residing in parent vnets. This is an interim vlan-specific solution which will be superseded by a more generic if_cloner V_irtualization change from p4. For nooptions VIMAGE builds, this should be a no-op change. Discussed with: bz MFC after: 3 days
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r--sys/net/if_vlan.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 63fc026..4e24a5f 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -206,6 +206,11 @@ static void vlan_iflladdr(void *arg, struct ifnet *ifp);
static struct if_clone vlan_cloner = IFC_CLONE_INITIALIZER(VLANNAME, NULL,
IF_MAXUNIT, NULL, vlan_clone_match, vlan_clone_create, vlan_clone_destroy);
+#ifdef VIMAGE
+static VNET_DEFINE(struct if_clone, vlan_cloner);
+#define V_vlan_cloner VNET(vlan_cloner)
+#endif
+
#ifndef VLAN_ARRAY
#define HASH(n, m) ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
@@ -588,7 +593,9 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_input_p = vlan_input;
vlan_link_state_p = vlan_link_state;
vlan_trunk_cap_p = vlan_trunk_capabilities;
+#ifndef VIMAGE
if_clone_attach(&vlan_cloner);
+#endif
if (bootverbose)
printf("vlan: initialized, using "
#ifdef VLAN_ARRAY
@@ -600,7 +607,9 @@ vlan_modevent(module_t mod, int type, void *data)
"\n");
break;
case MOD_UNLOAD:
+#ifndef VIMAGE
if_clone_detach(&vlan_cloner);
+#endif
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
vlan_input_p = NULL;
@@ -625,6 +634,27 @@ static moduledata_t vlan_mod = {
DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
MODULE_VERSION(if_vlan, 3);
+#ifdef VIMAGE
+static void
+vnet_vlan_init(const void *unused __unused)
+{
+
+ V_vlan_cloner = vlan_cloner;
+ if_clone_attach(&V_vlan_cloner);
+}
+VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ vnet_vlan_init, NULL);
+
+static void
+vnet_vlan_uninit(const void *unused __unused)
+{
+
+ if_clone_detach(&V_vlan_cloner);
+}
+VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST,
+ vnet_vlan_uninit, NULL);
+#endif
+
static struct ifnet *
vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
{
@@ -1432,6 +1462,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSETVLAN:
+#ifdef VIMAGE
+ if (ifp->if_vnet != ifp->if_home_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
if (error)
break;
@@ -1461,6 +1497,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCGETVLAN:
+#ifdef VIMAGE
+ if (ifp->if_vnet != ifp->if_home_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
bzero(&vlr, sizeof(vlr));
VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
OpenPOWER on IntegriCloud