svn commit: r272889 - head/sys/net
Hiroki Sato
hrs at FreeBSD.org
Fri Oct 10 06:45:14 UTC 2014
Author: hrs
Date: Fri Oct 10 06:45:13 2014
New Revision: 272889
URL: https://svnweb.freebsd.org/changeset/base/272889
Log:
Virtualize if_epair(4). An if_xname check for both "a" and "b" interfaces
is added to return EEXIST when only "b" interface exists---this can happen
when epair<N>b is moved to a vnet jail and then "ifconfig epair<N> create"
is invoked there.
Modified:
head/sys/net/if_epair.c
Modified: head/sys/net/if_epair.c
==============================================================================
--- head/sys/net/if_epair.c Fri Oct 10 06:24:09 2014 (r272888)
+++ head/sys/net/if_epair.c Fri Oct 10 06:45:13 2014 (r272889)
@@ -101,7 +101,7 @@ static int epair_clone_destroy(struct if
static const char epairname[] = "epair";
-/* Netisr realted definitions and sysctl. */
+/* Netisr related definitions and sysctl. */
static struct netisr_handler epair_nh = {
.nh_name = epairname,
.nh_proto = NETISR_EPAIR,
@@ -172,7 +172,8 @@ STAILQ_HEAD(eid_list, epair_ifp_drain);
static MALLOC_DEFINE(M_EPAIR, epairname,
"Pair of virtual cross-over connected Ethernet-like interfaces");
-static struct if_clone *epair_cloner;
+static VNET_DEFINE(struct if_clone *, epair_cloner);
+#define V_epair_cloner VNET(epair_cloner)
/*
* DPCPU area and functions.
@@ -760,10 +761,17 @@ epair_clone_create(struct if_clone *ifc,
ifc_free_unit(ifc, unit);
return (ENOSPC);
}
- *dp = 'a';
+ *dp = 'b';
/* Must not change dp so we can replace 'a' by 'b' later. */
*(dp+1) = '\0';
+ /* Check if 'a' and 'b' interfaces already exist. */
+ if (ifunit(name) != NULL)
+ return (EEXIST);
+ *dp = 'a';
+ if (ifunit(name) != NULL)
+ return (EEXIST);
+
/* Allocate memory for both [ab] interfaces */
sca = malloc(sizeof(struct epair_softc), M_EPAIR, M_WAITOK | M_ZERO);
EPAIR_REFCOUNT_INIT(&sca->refcount, 1);
@@ -944,6 +952,25 @@ epair_clone_destroy(struct if_clone *ifc
return (0);
}
+static void
+vnet_epair_init(const void *unused __unused)
+{
+
+ V_epair_cloner = if_clone_advanced(epairname, 0,
+ epair_clone_match, epair_clone_create, epair_clone_destroy);
+}
+VNET_SYSINIT(vnet_epair_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ vnet_epair_init, NULL);
+
+static void
+vnet_epair_uninit(const void *unused __unused)
+{
+
+ if_clone_detach(V_epair_cloner);
+}
+VNET_SYSUNINIT(vnet_epair_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ vnet_epair_uninit, NULL);
+
static int
epair_modevent(module_t mod, int type, void *data)
{
@@ -957,13 +984,10 @@ epair_modevent(module_t mod, int type, v
if (TUNABLE_INT_FETCH("net.link.epair.netisr_maxqlen", &qlimit))
epair_nh.nh_qlimit = qlimit;
netisr_register(&epair_nh);
- epair_cloner = if_clone_advanced(epairname, 0,
- epair_clone_match, epair_clone_create, epair_clone_destroy);
if (bootverbose)
printf("%s initialized.\n", epairname);
break;
case MOD_UNLOAD:
- if_clone_detach(epair_cloner);
netisr_unregister(&epair_nh);
epair_dpcpu_detach();
if (bootverbose)
More information about the svn-src-head
mailing list