summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2011-03-24 20:09:46 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2011-03-24 20:09:46 +0000
commit058c2a2ac21b184d3ac0a3acbcc94c736f97b969 (patch)
treef555aea0ab8fda0e0571274b6308e0718b435615 /sys/net/pf.c
parenta48f8fb673bca17189697c8f316510aed5a91e5a (diff)
Reassemble IPv6 fragments in pf. In the forward case, pf refragments
the packets with the same maximum size. This allows the sender to determine the optimal fragment size by Path MTU Discovery. testing sthen@ matthieu@ ok claudio@
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 08bed7d7253..85193cc4f12 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.729 2011/03/07 23:30:18 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.730 2011/03/24 20:09:44 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -6051,12 +6051,13 @@ done:
#ifdef INET6
int
-pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
+pf_test6(int fwdir, struct ifnet *ifp, struct mbuf **m0,
struct ether_header *eh)
{
struct pfi_kif *kif;
u_short action, reason = 0;
struct mbuf *m = *m0;
+ struct m_tag *mtag;
struct ip6_hdr *h;
struct pf_rule *a = NULL, *r = &pf_default_rule;
struct pf_state *s = NULL;
@@ -6064,6 +6065,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
struct pf_pdesc pd;
union pf_headers hdrs;
int off, hdrlen;
+ int dir = (fwdir == PF_FWD) ? PF_OUT : fwdir;
if (!pf_status.running)
return (PF_PASS);
@@ -6101,8 +6103,14 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET)
return (PF_PASS);
+ if (m->m_pkthdr.pf.flags & PF_TAG_REFRAGMENTED) {
+ m->m_pkthdr.pf.flags &= ~PF_TAG_REFRAGMENTED;
+ return (PF_PASS);
+ }
+
/* packet reassembly */
- if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
+ if (pf_status.reass &&
+ pf_normalize_ip6(m0, fwdir, kif, &reason, &pd) != PF_PASS) {
action = PF_DROP;
goto done;
}
@@ -6308,6 +6316,11 @@ done:
break;
}
+ /* if reassembled packet passed, create new fragments */
+ if (pf_status.reass && action == PF_PASS && *m0 && fwdir == PF_FWD &&
+ (mtag = m_tag_find(m, PACKET_TAG_PF_REASSEMBLED, NULL)) != NULL)
+ action = pf_refragment6(m0, mtag, fwdir);
+
return (action);
}
#endif /* INET6 */