On Tuesday 09 August 2011 22:56:36 Mike Belopuhov wrote:
> Hi,
>
> I'd like to propose the following change in the pf ruleset evaluation:
>
> Index: pf.c
> ===================================================================
> RCS file: /home/cvs/src/sys/net/pf.c,v
> retrieving revision 1.770
> diff -u -p -r1.770 pf.c
> --- pf.c      3 Aug 2011 12:28:40 -0000       1.770
> +++ pf.c      9 Aug 2011 15:50:42 -0000
> @@ -2924,6 +2924,11 @@ pf_test_rule(struct pf_rule **rm, struct
>               PF_TEST_ATTRIB((r->match_tag && !pf_match_tag(m, r, &tag)),
>                       TAILQ_NEXT(r, entries));
>               PF_TEST_ATTRIB((r->rcv_kif && !pf_match_rcvif(m, r)),
> +                     TAILQ_NEXT(r, entries));
> +
> +             /* see if a rule has reached a maximum number of states */
> +             PF_TEST_ATTRIB((r->anchor == NULL && r->keep_state &&
> +                 r->max_states && r->states_cur >= r->max_states),
>                       TAILQ_NEXT(r, entries));
>
>               /* FALLTHROUGH */
>
>
> I have an application that dynamically inserts rules like that into
> the anchor:
>
> anchor "foo/*" all {
>   anchor "7" all {
>     pass in quick on rdomain 0 inet proto udp from 10.0.2.2 to
> 10.0.1.2 port = 759 flags S/SA keep state (max 1) rtable 0 prio 0 }
>   anchor "8" all {
>     pass in quick on rdomain 0 inet proto udp from 10.0.2.2 to
> 10.0.1.2 port = 759 flags S/SA keep state (max 1) rtable 0 prio 0 }
> }
>
> as you can see source and destination addresses as well as a
> destination port are the same, but these rules serve for two different
> concurrent connections (source ports are different).
>
> Currently this won't work because the first rule matches the second
> connection and when pf_create_state bails out we are already not in
> the rule evaluation loop and drop the packet.
>
> I consider this to be a misfeature and prefer the ruleset evaluation
> to continue, hence the diff.  What do you think?  Any objections?

I see two different kinds of max state count limits here:

  1. (current one) drop packet/connection when limit is reached.
  2. (proposed one) move on to the next rule when limit is reached.

Then you just want another (new) limit, say, max-states-match, which will 
do what you want. It could be useful, yeah, but IMHO it's better to 
count states then per-address, not per-rule. This way you can do 
something like:

table <backends> {
        192.168.6.2 max-states-match 100
        192.168.6.3 max-states-match 140
}
table <fallback> {
        192.168.6.9
}
match in on $ext_if to port http rdr-to <backends>
match in on $ext_if to port http rdr-to <fallback>

But this will requre extending pf_addr structure; not sure if this is a 
good way to go.
-- 
  Best wishes,
    Vadim Zhukov

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

Reply via email to