Page MenuHomeFreeBSD

D37459.id113574.diff
No OneTemporary

D37459.id113574.diff

diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1528,7 +1528,8 @@
}
;
-fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
+fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
+ | FRAGMENT NO REASSEMBLE { $$ = PFRULE_FRAGMENT_NOREASS; }
| FRAGMENT FRAGCROP { $$ = 0; }
| FRAGMENT FRAGDROP { $$ = 0; }
;
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1131,7 +1131,8 @@
if (r->rule_flag & PFRULE_REASSEMBLE_TCP)
printf(" reassemble tcp");
- printf(" fragment reassemble");
+ printf(" fragment %sreassemble",
+ r->rule_flag & PFRULE_FRAGMENT_NOREASS ? "no " : "");
}
i = 0;
while (r->label[i][0])
diff --git a/sbin/pfctl/tests/files/pf1011.in b/sbin/pfctl/tests/files/pf1011.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1011.in
@@ -0,0 +1 @@
+scrub fragment no reassemble
diff --git a/sbin/pfctl/tests/files/pf1011.ok b/sbin/pfctl/tests/files/pf1011.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1011.ok
@@ -0,0 +1 @@
+scrub all fragment no reassemble
diff --git a/sbin/pfctl/tests/files/pf1012.in b/sbin/pfctl/tests/files/pf1012.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1012.in
@@ -0,0 +1 @@
+scrub
diff --git a/sbin/pfctl/tests/files/pf1012.ok b/sbin/pfctl/tests/files/pf1012.ok
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1012.ok
@@ -0,0 +1 @@
+scrub all fragment reassemble
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -121,3 +121,5 @@
PFCTL_TEST(1008, "Ethernet rule with mask length")
PFCTL_TEST(1009, "Ethernet rule with mask")
PFCTL_TEST(1010, "POM_STICKYADDRESS test")
+PFCTL_TEST(1011, "Test disabling scrub fragment reassemble")
+PFCTL_TEST(1012, "Test scrub fragment reassemble is default")
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 28, 2022
+.Dd November 24, 2022
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -832,6 +832,9 @@
The advantage is that filter rules have to deal only with complete
packets, and can ignore fragments.
The drawback of caching fragments is the additional memory cost.
+This is the default behaviour unless no fragment reassemble is specified.
+.It Ar no fragment reassemble
+Do not reassemble fragments.
.It Ar reassemble tcp
Statefully normalizes TCP connections.
.Ar scrub reassemble tcp
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -598,6 +598,7 @@
/* scrub flags */
#define PFRULE_NODF 0x0100
+#define PFRULE_FRAGMENT_NOREASS 0x0200
#define PFRULE_RANDOMID 0x0800
#define PFRULE_REASSEMBLE_TCP 0x1000
#define PFRULE_SET_TOS 0x2000
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -1115,31 +1115,34 @@
DPFPRINTF(("max packet %d\n", fragoff + ip_len));
goto bad;
}
- max = fragoff + ip_len;
- /* Fully buffer all of the fragments
- * Might return a completely reassembled mbuf, or NULL */
- PF_FRAG_LOCK();
- DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
- verdict = pf_reassemble(m0, h, dir, reason);
- PF_FRAG_UNLOCK();
+ if (! (r->rule_flag & PFRULE_FRAGMENT_NOREASS)) {
+ max = fragoff + ip_len;
- if (verdict != PF_PASS)
- return (PF_DROP);
+ /* Fully buffer all of the fragments
+ * Might return a completely reassembled mbuf, or NULL */
+ PF_FRAG_LOCK();
+ DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
+ verdict = pf_reassemble(m0, h, dir, reason);
+ PF_FRAG_UNLOCK();
- m = *m0;
- if (m == NULL)
- return (PF_DROP);
+ if (verdict != PF_PASS)
+ return (PF_DROP);
+
+ m = *m0;
+ if (m == NULL)
+ return (PF_DROP);
- h = mtod(m, struct ip *);
+ h = mtod(m, struct ip *);
no_fragment:
- /* At this point, only IP_DF is allowed in ip_off */
- if (h->ip_off & ~htons(IP_DF)) {
- u_int16_t ip_off = h->ip_off;
+ /* At this point, only IP_DF is allowed in ip_off */
+ if (h->ip_off & ~htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
- h->ip_off &= htons(IP_DF);
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ h->ip_off &= htons(IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
}
pf_scrub_ip(&m, r->rule_flag, r->min_ttl, r->set_tos);

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 13, 6:03 AM (48 m, 27 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17490946
Default Alt Text
D37459.id113574.diff (4 KB)

Event Timeline