diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-25 06:30:23 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-06-25 06:30:23 +0000 |
commit | 958f24596bb135b6fdf76f7f31402516df50be23 (patch) | |
tree | 5bb321e718860fac3648c9167feeed197555e9aa /sys/net | |
parent | 528b3acaeafa6af57bdac5f91e037290ef3334f9 (diff) |
Use tags to detect loops. In the future, perhaps we'll use them to
actually also send the packet out the right interface.
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_gre.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 0386437295f..5d8d63cf7c2 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.14 2001/06/25 01:50:16 fgsch Exp $ */ +/* $OpenBSD: if_gre.c,v 1.15 2001/06/25 06:30:22 angelos Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -168,15 +168,25 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct ip *inp = NULL; u_short etype = 0; struct mobile_h mob_h; - static int recursions = 0; /* XXX MUTEX */ + struct m_tag *mtag; - /* Try to limit infinite recursion through misconfiguration */ - if (++recursions >= GRE_RECURSION_LIMIT) { - IF_DROP(&ifp->if_snd); + /* Try to limit infinite recursion through misconfiguration. */ + for (mtag = m_tag_find(m, PACKET_TAG_GRE, NULL); mtag; + mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) { + if (!bcmp((caddr_t)(mtag + 1), &ifp, sizeof(struct ifnet *))) { + IF_DROP(&ifp->if_snd); + m_freem(m); + return (EIO); /* Use the same as in if_gif.c */ + } + } + + mtag = m_tag_get(PACKET_TAG_GRE, sizeof(struct ifnet *), M_NOWAIT); + if (mtag == NULL) { m_freem(m); - recursions = 0; - return (EIO); /* Use the same as in if_gif.c */ + return (ENOBUFS); } + bcopy(&ifp, (caddr_t)(mtag + 1), sizeof(struct ifnet *)); + m_tag_prepend(m, mtag); #if NBPFILTER >0 if (ifp->if_bpf) @@ -187,7 +197,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, if (ip_mobile_allow == 0) { IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (EACCES); } @@ -203,7 +212,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m = m_pullup(m, sizeof(struct ip)); if (m == NULL) { IF_DROP(&ifp->if_snd); - recursions = 0; return (ENOBUFS); } else inp = mtod(m, struct ip *); @@ -213,7 +221,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, sizeof(inp->ip_hl << 2)); if (m == NULL) { IF_DROP(&ifp->if_snd); - recursions = 0; return (ENOBUFS); } } @@ -250,7 +257,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, if (m0 == NULL) { IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (ENOBUFS); } M_COPY_HDR(m0, m); @@ -282,14 +288,12 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, } else { /* AF_INET */ IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (EINVAL); } } else if (sc->g_proto == IPPROTO_GRE) { if (gre_allow == 0) { IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (EACCES); } @@ -299,7 +303,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, m = m_pullup(m, sizeof(struct ip)); if (m == NULL) { IF_DROP(&ifp->if_snd); - recursions = 0; return (ENOBUFS); } } @@ -320,7 +323,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, default: IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (EAFNOSUPPORT); } @@ -329,13 +331,11 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, error = EINVAL; IF_DROP(&ifp->if_snd); m_freem(m); - recursions = 0; return (error); } if (m == NULL) { IF_DROP(&ifp->if_snd); - recursions = 0; return (ENOBUFS); } @@ -364,7 +364,6 @@ gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, error = ip_output(m, NULL, &sc->route, 0, NULL, NULL); if (error) ifp->if_oerrors++; - recursions = 0; return (error); } |