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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to