The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0c273335b2deac7cf7dadbcb5cd43d35127eb3f0

commit 0c273335b2deac7cf7dadbcb5cd43d35127eb3f0
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-06-25 15:02:28 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2025-06-27 14:55:15 +0000

    pf: ensure max-pkt-size works on match rules
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h                      |  1 +
 sys/netpfil/pf/pf.c                  | 11 +++++--
 tests/sys/netpfil/pf/max_pkt_size.sh | 61 +++++++++++++++++++++++++++++-------
 3 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 5c798216f9f5..9fc2a00dca77 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -690,6 +690,7 @@ struct pf_rule_actions {
        uint8_t          set_prio[2];
        uint8_t          rt;
        uint8_t          allow_opts;
+       uint16_t         max_pkt_size;
 };
 
 union pf_keth_rule_ptr {
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 6da537aaa2cd..4ce2df2f0e31 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -4886,6 +4886,8 @@ pf_rule_to_actions(struct pf_krule *r, struct 
pf_rule_actions *a)
        }
        if (r->allow_opts)
                a->allow_opts = r->allow_opts;
+       if (r->max_pkt_size)
+               a->max_pkt_size = r->max_pkt_size;
 }
 
 int
@@ -10668,8 +10670,10 @@ done:
        if (pd.m == NULL)
                goto eat_pkt;
 
-       if (action == PF_PASS && pd.badopts &&
-           !((s && s->state_flags & PFSTATE_ALLOWOPTS) || pd.act.allow_opts)) {
+       if (s)
+               memcpy(&pd.act, &s->act, sizeof(s->act));
+
+       if (action == PF_PASS && pd.badopts && !pd.act.allow_opts) {
                action = PF_DROP;
                REASON_SET(&reason, PFRES_IPOPTIONS);
                pd.act.log = PF_LOG_FORCE;
@@ -10677,7 +10681,8 @@ done:
                    ("pf: dropping packet with dangerous headers\n"));
        }
 
-       if (r && r->max_pkt_size && pd.tot_len > r->max_pkt_size) {
+       if (pd.act.max_pkt_size && pd.act.max_pkt_size &&
+           pd.tot_len > pd.act.max_pkt_size) {
                action = PF_DROP;
                REASON_SET(&reason, PFRES_NORM);
                pd.act.log = PF_LOG_FORCE;
diff --git a/tests/sys/netpfil/pf/max_pkt_size.sh 
b/tests/sys/netpfil/pf/max_pkt_size.sh
index 05aab0b7990a..030d642303fc 100644
--- a/tests/sys/netpfil/pf/max_pkt_size.sh
+++ b/tests/sys/netpfil/pf/max_pkt_size.sh
@@ -26,17 +26,8 @@
 
 . $(atf_get_srcdir)/utils.subr
 
-atf_test_case "basic" "cleanup"
-basic_head()
-{
-       atf_set descr 'Basic max-pkt-size test'
-       atf_set require.user root
-}
-
-basic_body()
+common_setup()
 {
-       pft_init
-
        epair=$(vnet_mkepair)
 
        ifconfig ${epair}b 192.0.2.2/24 up
@@ -45,9 +36,10 @@ basic_body()
        jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up
 
        jexec alcatraz pfctl -e
-       pft_set_rules alcatraz \
-           "pass max-pkt-size 128"
+}
 
+common_test()
+{
        # Small packets pass
        atf_check -s exit:0 -o ignore \
            ping -c 1 192.0.2.1
@@ -59,6 +51,25 @@ basic_body()
            ping -c 3 -s 101 192.0.2.1
        atf_check -s exit:2 -o ignore \
            ping -c 3 -s 128 192.0.2.1
+}
+
+atf_test_case "basic" "cleanup"
+basic_head()
+{
+       atf_set descr 'Basic max-pkt-size test'
+       atf_set require.user root
+}
+
+basic_body()
+{
+       pft_init
+
+       common_setup
+
+       pft_set_rules alcatraz \
+           "pass max-pkt-size 128"
+
+       common_test
 
        # We can enforce this on fragmented packets too
        pft_set_rules alcatraz \
@@ -79,7 +90,33 @@ basic_cleanup()
        pft_cleanup
 }
 
+atf_test_case "match" "cleanup"
+match_head()
+{
+       atf_set descr 'max-pkt-size on match rules'
+       atf_set require.user root
+}
+
+match_body()
+{
+       pft_init
+
+       common_setup
+
+       pft_set_rules alcatraz \
+           "match in max-pkt-size 128" \
+           "pass"
+
+       common_test
+}
+
+match_cleanup()
+{
+       pft_cleanup
+}
+
 atf_init_test_cases()
 {
        atf_add_test_case "basic"
+       atf_add_test_case "match"
 }

Reply via email to