summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-25 06:30:23 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2001-06-25 06:30:23 +0000
commit958f24596bb135b6fdf76f7f31402516df50be23 (patch)
tree5bb321e718860fac3648c9167feeed197555e9aa /sys/net
parent528b3acaeafa6af57bdac5f91e037290ef3334f9 (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.c35
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);
}