PF (inline) anchor + table = fail?

Fellow Scientists :p

Today I was revisiting the approach of optimizing my PF ruleset by grouping related rules into inline anchors, so that ruleset evaluation would skip such an anchor in it's entirety, if the conditions associated with the anchor itself are not met. Something like this:

Code:
anchor "Lan" on fxp0 {
        <... rules dealing with interface fxp0 exclusively ...>
}
Unfortunately such a configuration comes with one problem: Tables
Tables seem to exist within a namespace, and the namespace of an anchor is separated from the namespace used in the main ruleset. Which means that the following does not work, cause the table defined in the main ruleset is not visible from within the anchor:

Code:
table <badguys> const { 192.168.1.1, 192.168.2.1 }

anchor "Lan" on fxp0 {
        block in log quick from <badguys>
}
The solution would be to define the table within the anchor (albeit then being unable to reference the table within the main ruleset and/or other anchors), like so:

Code:
anchor "Lan" on fxp0 {
        table <badguys> const { 192.168.1.1, 192.168.2.1 }

        block in log quick from <badguys>
}
But it seems pfctl really does not like to let you do this.

Code:
pfctl -n -f test.pf
test.pf:2: syntax error
test.pf:5: syntax error
When you load the anchor fom a file instead of inlining it, the syntax is however perfectly valid. Then again you are facing another problem: all macros defined in the main ruleset are non-existent in the external anchor-file and defining the same macro in different places is likely error-prone.

So my questions are:
  1. Is the refusal to define a table within an inline anchor intended behaviour?
  2. Can I actually expect some kind of performance gain when ruleset evalution can skip over entire rule blocks contained within an anchor compared to having a flat config where each rule needs to be evaluated until either a quick match is found or the end of the ruleset is reached?
 
I ran into the same problem. Try this, it seems to work for me:
Code:
table <badguys> const persist { 192.168.1.1, 192.168.2.1 }

anchor "Lan" on fxp0 {
        block in log quick from <badguys>
}
It seems that if the table is not used in its immediate/defining scope then it is removed. Which is is not clear from the docs, but is kind of hinted at here: https://www.openbsd.org/faq/pf/tables.html
persist - causes the kernel to keep the table in memory even when no rules refer to it. Without this attribute, the kernel will automatically remove the table when the last rule referencing it is flushed.
 
Back
Top