diff options
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r-- | sys/net/pf.c | 95 |
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 *); } /* |