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>