summaryrefslogtreecommitdiffstats
path: root/sys/contrib/pf/net
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2004-07-17 17:15:15 +0000
committermlaier <mlaier@FreeBSD.org>2004-07-17 17:15:15 +0000
commit8206972537d22846ebf90ee5084d300d35430f98 (patch)
tree1ad5590e7aae81c00e9487eb2ba2673d04941255 /sys/contrib/pf/net
parent6bd2f3e42ba6a2ebbaf591311cbea3fb98bf9f25 (diff)
downloadFreeBSD-src-8206972537d22846ebf90ee5084d300d35430f98.zip
FreeBSD-src-8206972537d22846ebf90ee5084d300d35430f98.tar.gz
Merge in a stable fix from OpenBSD:
MFC: Fix by dhartmei@ change pf_route() loop detection: introduce a counter (number of times a packet is routed already) in the mbuf tag, allow at most four times. Fixes some legitimate cases broken by the previous change. Reviewed by: dhartmei
Diffstat (limited to 'sys/contrib/pf/net')
-rw-r--r--sys/contrib/pf/net/pf.c115
1 files changed, 63 insertions, 52 deletions
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
index 085f5cb..5df3ba6 100644
--- a/sys/contrib/pf/net/pf.c
+++ b/sys/contrib/pf/net/pf.c
@@ -1,5 +1,5 @@
/* $FreeBSD$ */
-/* $OpenBSD: pf.c,v 1.433.2.1 2004/04/30 21:46:33 brad Exp $ */
+/* $OpenBSD: pf.c,v 1.433.2.2 2004/07/17 03:22:34 brad Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -5119,12 +5119,12 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
struct pf_state *s)
{
struct mbuf *m0, *m1;
+ struct m_tag *mtag;
struct route iproute;
struct route *ro = NULL; /* XXX: was uninitialized */
struct sockaddr_in *dst;
struct ip *ip;
struct ifnet *ifp = NULL;
- struct m_tag *mtag;
struct pf_addr naddr;
struct pf_src_node *sn = NULL;
int error = 0;
@@ -5136,22 +5136,34 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
panic("pf_route: invalid parameters");
- if (r->rt == PF_DUPTO) {
- m0 = *m;
- mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL);
- if (mtag == NULL) {
- mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT);
- if (mtag == NULL)
- goto bad;
- m_tag_prepend(m0, mtag);
+ if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
+ if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
+ NULL) {
+ m0 = *m;
+ *m = NULL;
+ goto bad;
}
+ *(char *)(mtag + 1) = 1;
+ m_tag_prepend(*m, mtag);
+ } else {
+ if (*(char *)(mtag + 1) > 3) {
+ m0 = *m;
+ *m = NULL;
+ goto bad;
+ }
+ (*(char *)(mtag + 1))++;
+ }
+
+ if (r->rt == PF_DUPTO) {
#ifdef __FreeBSD__
- m0 = m_dup(*m, M_DONTWAIT);
+ if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
#else
- m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
#endif
- if (m0 == NULL)
return;
+ if ((mtag = m_tag_copy(mtag)) == NULL)
+ goto bad;
+ m_tag_prepend(m0, mtag);
} else {
if ((r->rt == PF_REPLYTO) == (r->direction == dir))
return;
@@ -5198,17 +5210,9 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
}
}
-
if (ifp == NULL)
goto bad;
- if (m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL) != NULL)
- goto bad;
- mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT);
- if (mtag == NULL)
- goto bad;
- m_tag_prepend(m0, mtag);
-
if (oifp != ifp) {
#ifdef __FreeBSD__
PF_UNLOCK();
@@ -5415,22 +5419,34 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
panic("pf_route6: invalid parameters");
- if (r->rt == PF_DUPTO) {
- m0 = *m;
- mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL);
- if (mtag == NULL) {
- mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT);
- if (mtag == NULL)
- goto bad;
- m_tag_prepend(m0, mtag);
+ if ((mtag = m_tag_find(*m, PACKET_TAG_PF_ROUTED, NULL)) == NULL) {
+ if ((mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 1, M_NOWAIT)) ==
+ NULL) {
+ m0 = *m;
+ *m = NULL;
+ goto bad;
}
+ *(char *)(mtag + 1) = 1;
+ m_tag_prepend(*m, mtag);
+ } else {
+ if (*(char *)(mtag + 1) > 3) {
+ m0 = *m;
+ *m = NULL;
+ goto bad;
+ }
+ (*(char *)(mtag + 1))++;
+ }
+
+ if (r->rt == PF_DUPTO) {
#ifdef __FreeBSD__
- m0 = m_dup(*m, M_DONTWAIT);
+ if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
#else
- m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
#endif
- if (m0 == NULL)
return;
+ if ((mtag = m_tag_copy(mtag)) == NULL)
+ goto bad;
+ m_tag_prepend(m0, mtag);
} else {
if ((r->rt == PF_REPLYTO) == (r->direction == dir))
return;
@@ -5480,34 +5496,29 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
&s->rt_addr, AF_INET6);
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
}
-
if (ifp == NULL)
goto bad;
if (oifp != ifp) {
- mtag = m_tag_find(m0, PACKET_TAG_PF_ROUTED, NULL);
- if (mtag == NULL) {
- mtag = m_tag_get(PACKET_TAG_PF_ROUTED, 0, M_NOWAIT);
- if (mtag == NULL)
- goto bad;
- m_tag_prepend(m0, mtag);
#ifdef __FreeBSD__
- PF_UNLOCK();
- if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) {
- PF_LOCK();
- goto bad;
- } else if (m0 == NULL) {
- PF_LOCK();
- goto done;
- }
+ PF_UNLOCK();
+ if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) {
+ PF_LOCK();
+ goto bad;
+ } else if (m0 == NULL) {
PF_LOCK();
+ goto done;
+ }
+ PF_LOCK();
#else
- if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS)
- goto bad;
- else if (m0 == NULL)
- goto done;
+ if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS)
+ goto bad;
+ else if (m0 == NULL)
+ goto done;
#endif
- }
+ if (m0->m_len < sizeof(struct ip6_hdr))
+ panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)");
+ ip6 = mtod(m0, struct ip6_hdr *);
}
/*
OpenPOWER on IntegriCloud