Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Sep 2014 03:56:07 +0000 (UTC)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271918 - in head/sys: net netinet
Message-ID:  <201409210356.s8L3u7KL016913@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hrs
Date: Sun Sep 21 03:56:06 2014
New Revision: 271918
URL: http://svnweb.freebsd.org/changeset/base/271918

Log:
  - Virtualize interface cloner for gre(4).  This fixes a panic when destroying
    a vnet jail which has a gre(4) interface.
  
  - Make net.link.gre.max_nesting vnet-local.

Modified:
  head/sys/net/if_gre.c
  head/sys/net/if_gre.h
  head/sys/netinet/ip_gre.c

Modified: head/sys/net/if_gre.c
==============================================================================
--- head/sys/net/if_gre.c	Sun Sep 21 03:55:04 2014	(r271917)
+++ head/sys/net/if_gre.c	Sun Sep 21 03:56:06 2014	(r271918)
@@ -102,15 +102,16 @@ struct mtag_gre_nesting {
  * gre_mtx protects all global variables in if_gre.c.
  * XXX: gre_softc data not protected yet.
  */
-struct mtx gre_mtx;
+VNET_DEFINE(struct mtx, gre_mtx);
+VNET_DEFINE(struct gre_softc_head, gre_softc_list);
+
 static const char grename[] = "gre";
 static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
 
-struct gre_softc_head gre_softc_list;
-
 static int	gre_clone_create(struct if_clone *, int, caddr_t);
 static void	gre_clone_destroy(struct ifnet *);
-static struct if_clone *gre_cloner;
+static VNET_DEFINE(struct if_clone *, gre_cloner);
+#define	V_gre_cloner	VNET(gre_cloner)
 
 static int	gre_ioctl(struct ifnet *, u_long, caddr_t);
 static int	gre_output(struct ifnet *, struct mbuf *,
@@ -118,8 +119,6 @@ static int	gre_output(struct ifnet *, st
 
 static int gre_compute_route(struct gre_softc *sc);
 
-static void	greattach(void);
-
 #ifdef INET
 extern struct domain inetdomain;
 static const struct protosw in_gre_protosw = {
@@ -160,26 +159,34 @@ static SYSCTL_NODE(_net_link, IFT_TUNNEL
  */
 #define MAX_GRE_NEST 1
 #endif
-static int max_gre_nesting = MAX_GRE_NEST;
-SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW,
-    &max_gre_nesting, 0, "Max nested tunnels");
+static VNET_DEFINE(int, max_gre_nesting) = MAX_GRE_NEST;
+#define	V_max_gre_nesting	VNET(max_gre_nesting)
+SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET,
+    &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels");
 
-/* ARGSUSED */
 static void
-greattach(void)
+vnet_gre_init(const void *unused __unused)
 {
-
-	mtx_init(&gre_mtx, "gre_mtx", NULL, MTX_DEF);
-	LIST_INIT(&gre_softc_list);
-	gre_cloner = if_clone_simple(grename, gre_clone_create,
+	LIST_INIT(&V_gre_softc_list);
+	GRE_LIST_LOCK_INIT();
+	V_gre_cloner = if_clone_simple(grename, gre_clone_create,
 	    gre_clone_destroy, 0);
 }
+VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+    vnet_gre_init, NULL);
+
+static void
+vnet_gre_uninit(const void *unused __unused)
+{
+
+	if_clone_detach(V_gre_cloner);
+	GRE_LIST_LOCK_DESTROY();
+}
+VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+    vnet_gre_uninit, NULL);
 
 static int
-gre_clone_create(ifc, unit, params)
-	struct if_clone *ifc;
-	int unit;
-	caddr_t params;
+gre_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 {
 	struct gre_softc *sc;
 
@@ -210,21 +217,20 @@ gre_clone_create(ifc, unit, params)
 	sc->key = 0;
 	if_attach(GRE2IFP(sc));
 	bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
-	mtx_lock(&gre_mtx);
-	LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
-	mtx_unlock(&gre_mtx);
+	GRE_LIST_LOCK();
+	LIST_INSERT_HEAD(&V_gre_softc_list, sc, sc_list);
+	GRE_LIST_UNLOCK();
 	return (0);
 }
 
 static void
-gre_clone_destroy(ifp)
-	struct ifnet *ifp;
+gre_clone_destroy(struct ifnet *ifp)
 {
 	struct gre_softc *sc = ifp->if_softc;
 
-	mtx_lock(&gre_mtx);
+	GRE_LIST_LOCK();
 	LIST_REMOVE(sc, sc_list);
-	mtx_unlock(&gre_mtx);
+	GRE_LIST_UNLOCK();
 
 #ifdef INET
 	if (sc->encap != NULL)
@@ -269,7 +275,7 @@ gre_output(struct ifnet *ifp, struct mbu
 
 		gt = (struct mtag_gre_nesting *)(mtag + 1);
 		gt->count++;
-		if (gt->count > min(gt->max,max_gre_nesting)) {
+		if (gt->count > min(gt->max, V_max_gre_nesting)) {
 			printf("%s: hit maximum recursion limit %u on %s\n",
 				__func__, gt->count - 1, ifp->if_xname);
 			m_freem(m);
@@ -301,7 +307,7 @@ gre_output(struct ifnet *ifp, struct mbu
 		 * Note: the sysctl does not actually check for saneness, so we
 		 * limit the maximum numbers of possible recursions here.
 		 */
-		max = imin(max_gre_nesting, 256);
+		max = imin(V_max_gre_nesting, 256);
 		/* If someone sets the sysctl <= 0, we want at least 1. */
 		max = imax(max, 1);
 		len = sizeof(struct mtag_gre_nesting) +
@@ -909,16 +915,12 @@ gremodevent(module_t mod, int type, void
 
 	switch (type) {
 	case MOD_LOAD:
-		greattach();
-		break;
 	case MOD_UNLOAD:
-		if_clone_detach(gre_cloner);
-		mtx_destroy(&gre_mtx);
 		break;
 	default:
-		return EOPNOTSUPP;
+		return (EOPNOTSUPP);
 	}
-	return 0;
+	return (0);
 }
 
 static moduledata_t gre_mod = {

Modified: head/sys/net/if_gre.h
==============================================================================
--- head/sys/net/if_gre.h	Sun Sep 21 03:55:04 2014	(r271917)
+++ head/sys/net/if_gre.h	Sun Sep 21 03:56:06 2014	(r271918)
@@ -176,8 +176,16 @@ struct mobip_h {
 
 #ifdef _KERNEL
 LIST_HEAD(gre_softc_head, gre_softc);
-extern struct mtx gre_mtx;
-extern struct gre_softc_head gre_softc_list;
+VNET_DECLARE(struct gre_softc_head, gre_softc_list);
+#define	V_gre_softc_list	VNET(gre_softc_list)
+
+VNET_DECLARE(struct mtx, gre_mtx);
+#define	V_gre_mtx	VNET(gre_mtx)
+#define	GRE_LIST_LOCK_INIT(x)		mtx_init(&V_gre_mtx, "gre_mtx", NULL, \
+					    MTX_DEF)
+#define	GRE_LIST_LOCK_DESTROY(x)	mtx_destroy(&V_gre_mtx)
+#define	GRE_LIST_LOCK(x)		mtx_lock(&V_gre_mtx)
+#define	GRE_LIST_UNLOCK(x)		mtx_unlock(&V_gre_mtx)
 
 u_int16_t	gre_in_cksum(u_int16_t *, u_int);
 #endif /* _KERNEL */

Modified: head/sys/netinet/ip_gre.c
==============================================================================
--- head/sys/netinet/ip_gre.c	Sun Sep 21 03:55:04 2014	(r271917)
+++ head/sys/netinet/ip_gre.c	Sun Sep 21 03:56:06 2014	(r271918)
@@ -315,18 +315,18 @@ gre_lookup(struct mbuf *m, u_int8_t prot
 	struct ip *ip = mtod(m, struct ip *);
 	struct gre_softc *sc;
 
-	mtx_lock(&gre_mtx);
-	for (sc = LIST_FIRST(&gre_softc_list); sc != NULL;
+	GRE_LIST_LOCK();
+	for (sc = LIST_FIRST(&V_gre_softc_list); sc != NULL;
 	     sc = LIST_NEXT(sc, sc_list)) {
 		if ((sc->g_dst.s_addr == ip->ip_src.s_addr) &&
 		    (sc->g_src.s_addr == ip->ip_dst.s_addr) &&
 		    (sc->g_proto == proto) &&
 		    ((GRE2IFP(sc)->if_flags & IFF_UP) != 0)) {
-			mtx_unlock(&gre_mtx);
+			GRE_LIST_UNLOCK();
 			return (sc);
 		}
 	}
-	mtx_unlock(&gre_mtx);
+	GRE_LIST_UNLOCK();
 
 	return (NULL);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409210356.s8L3u7KL016913>