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?