diff --git a/sys/netpfil/pf/pf.c b/netpfil/pf/pf.c --- a/sys/netpfil/pf/pf.c +++ b/netpfil/pf/pf.c @@ -5262,6 +5262,14 @@ if (!state_icmp && (r->keep_state || nr != NULL || (pd->flags & PFDESC_TCP_NORM))) { int action; + + if (r->max_states && + (counter_u64_fetch(r->states_cur) > r->max_states)) { + counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1); + REASON_SET(&reason, PFRES_MAXSTATES); + goto cleanup; + } + action = pf_create_state(r, nr, a, pd, nsn, nk, sk, m, off, sport, dport, &rewrite, kif, sm, tag, bproto_sum, bip_sum, hdrlen, &match_rules, udp_mapping); @@ -5330,13 +5338,6 @@ u_short reason, sn_reason; struct pf_krule_item *ri; - /* check maximums */ - if (r->max_states && - (counter_u64_fetch(r->states_cur) >= r->max_states)) { - counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1); - REASON_SET(&reason, PFRES_MAXSTATES); - goto csfailed; - } /* src node for filter rule */ if ((r->rule_flag & PFRULE_SRCTRACK || r->rpool.opts & PF_POOL_STICKYADDR) && diff --git a/tests/sys/netpfil/pf/max_states.sh b/sys/netpfil/pf/max_states.sh --- a/tests/sys/netpfil/pf/max_states.sh +++ b/sys/netpfil/pf/max_states.sh @@ -43,10 +43,10 @@ "pass in on ${epair_tester}b keep state (max 3)" \ "pass out on ${epair_server}a keep state" - # The exact limit is off by 1 ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-sport=4201 ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-sport=4202 - ping_dummy_check_request exit:1 --ping-type=tcpsyn --send-sport=4203 + ping_dummy_check_request exit:0 --ping-type=tcpsyn --send-sport=4203 + ping_dummy_check_request exit:1 --ping-type=tcpsyn --send-sport=4204 } max_states_cleanup()