summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c95
1 files changed, 53 insertions, 42 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 13b373924e8..3899a2616b3 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.446 2004/05/05 23:16:03 frantzen Exp $ */
+/* $OpenBSD: pf.c,v 1.447 2004/05/11 07:06:52 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -4894,12 +4894,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;
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;
@@ -4908,18 +4908,30 @@ 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;
}
- m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
- if (m0 == NULL)
+ *(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) {
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == 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;
@@ -4966,17 +4978,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) {
if (pf_test(PF_OUT, ifp, &m0) != PF_PASS)
goto bad;
@@ -5101,18 +5105,30 @@ 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;
}
- m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT);
- if (m0 == NULL)
+ *(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) {
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == 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;
@@ -5155,22 +5171,17 @@ 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);
- 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;
+ if (m0->m_len < sizeof(struct ip6_hdr))
+ panic("pf_route6: m0->m_len < sizeof(struct ip6_hdr)");
+ ip6 = mtod(m0, struct ip6_hdr *);
}
/*