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