Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Jan 2015 03:13:17 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276901 - head/sys/net
Message-ID:  <201501100313.t0A3DHIG060086@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sat Jan 10 03:13:16 2015
New Revision: 276901
URL: https://svnweb.freebsd.org/changeset/base/276901

Log:
  Move the recursion detection code into separate function gif_check_nesting().
  Also make MTAG_GIF definition private to if_gif.c.
  
  MFC after:	1 week

Modified:
  head/sys/net/if_gif.c
  head/sys/net/if_gif.h

Modified: head/sys/net/if_gif.c
==============================================================================
--- head/sys/net/if_gif.c	Sat Jan 10 01:05:12 2015	(r276900)
+++ head/sys/net/if_gif.c	Sat Jan 10 03:13:16 2015	(r276901)
@@ -446,24 +446,12 @@ gif_qflush(struct ifnet *ifp __unused)
 
 }
 
-int
-gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
-	struct route *ro)
+#define	MTAG_GIF	1080679712
+static int
+gif_check_nesting(struct ifnet *ifp, struct mbuf *m)
 {
 	struct m_tag *mtag;
-	uint32_t af;
-	int gif_called;
-	int error = 0;
-#ifdef MAC
-	error = mac_ifnet_check_transmit(ifp, m);
-	if (error)
-		goto err;
-#endif
-	if ((ifp->if_flags & IFF_MONITOR) != 0 ||
-	    (ifp->if_flags & IFF_UP) == 0) {
-		error = ENETDOWN;
-		goto err;
-	}
+	int count;
 
 	/*
 	 * gif may cause infinite recursion calls when misconfigured.
@@ -472,35 +460,49 @@ gif_output(struct ifnet *ifp, struct mbu
 	 * High nesting level may cause stack exhaustion.
 	 * We'll prevent this by introducing upper limit.
 	 */
-	gif_called = 1;
-	mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, NULL);
-	while (mtag != NULL) {
+	count = 1;
+	mtag = NULL;
+	while ((mtag = m_tag_locate(m, MTAG_GIF, 0, mtag)) != NULL) {
 		if (*(struct ifnet **)(mtag + 1) == ifp) {
-			log(LOG_NOTICE,
-			    "gif_output: loop detected on %s\n",
-			    (*(struct ifnet **)(mtag + 1))->if_xname);
-			error = EIO;	/* is there better errno? */
-			goto err;
+			log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname);
+			return (EIO);
 		}
-		mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, mtag);
-		gif_called++;
+		count++;
 	}
-	if (gif_called > V_max_gif_nesting) {
+	if (count > V_max_gif_nesting) {
 		log(LOG_NOTICE,
-		    "gif_output: recursively called too many times(%d)\n",
-		    gif_called);
-		error = EIO;	/* is there better errno? */
+		    "%s: if_output recursively called too many times(%d)\n",
+		    if_name(ifp), count);
+		return (EIO);
+	}
+	mtag = m_tag_alloc(MTAG_GIF, 0, sizeof(struct ifnet *), M_NOWAIT);
+	if (mtag == NULL)
+		return (ENOMEM);
+	*(struct ifnet **)(mtag + 1) = ifp;
+	m_tag_prepend(m, mtag);
+	return (0);
+}
+
+int
+gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
+	struct route *ro)
+{
+	uint32_t af;
+	int error = 0;
+#ifdef MAC
+	error = mac_ifnet_check_transmit(ifp, m);
+	if (error)
 		goto err;
-	}
-	mtag = m_tag_alloc(MTAG_GIF, MTAG_GIF_CALLED, sizeof(struct ifnet *),
-	    M_NOWAIT);
-	if (mtag == NULL) {
-		error = ENOMEM;
+#endif
+	if ((ifp->if_flags & IFF_MONITOR) != 0 ||
+	    (ifp->if_flags & IFF_UP) == 0) {
+		error = ENETDOWN;
 		goto err;
 	}
-	*(struct ifnet **)(mtag + 1) = ifp;
-	m_tag_prepend(m, mtag);
 
+	error = gif_check_nesting(ifp, m);
+	if (error != 0)
+		goto err;
 	m->m_flags &= ~(M_BCAST|M_MCAST);
 	if (dst->sa_family == AF_UNSPEC)
 		bcopy(dst->sa_data, &af, sizeof(af));

Modified: head/sys/net/if_gif.h
==============================================================================
--- head/sys/net/if_gif.h	Sat Jan 10 01:05:12 2015	(r276900)
+++ head/sys/net/if_gif.h	Sat Jan 10 03:13:16 2015	(r276901)
@@ -90,9 +90,6 @@ struct gif_softc {
 #define	GIF_MTU_MIN	(1280)	/* Minimum MTU */
 #define	GIF_MTU_MAX	(8192)	/* Maximum MTU */
 
-#define	MTAG_GIF	1080679712
-#define	MTAG_GIF_CALLED	0
-
 struct etherip_header {
 #if BYTE_ORDER == LITTLE_ENDIAN
 	u_int	eip_resvl:4,	/* reserved */



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