diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-03-24 20:09:46 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-03-24 20:09:46 +0000 |
commit | 058c2a2ac21b184d3ac0a3acbcc94c736f97b969 (patch) | |
tree | f555aea0ab8fda0e0571274b6308e0718b435615 /sys/net/pf.c | |
parent | a48f8fb673bca17189697c8f316510aed5a91e5a (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.c | 19 |
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 */ |