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" }