How to see numbers of CPU cycles for particular FW rule?
-
Dear pfSense Gurus!
This question are about measuring the effectiveness of the ruleset of firewall;
How to see the numbers of CPU cycles, which spends on particular FW rule ?
And better to see in conjunction: bytes(packets) / mediana of CPU cycles per packet which are accepted or rejected by this rule, - to determine which rules are highly loaded by traffic and how many CPU cycles this particular rule (mean it’s up code) are eating.
(I read somewhere the ipfw able to doing that…)This may be very helpful to optimizing the ruleset of whole FW.
Have a nice sunny days!
-
You're absolutely right: profiling firewall rules by CPU cycles and traffic impact can help drastically optimize a pfSense firewall ruleset. However, pfSense (based on pf from OpenBSD) does not natively provide per-rule CPU cycle measurements, unlike ipfw which does have more granular counters and optional DTrace integration on FreeBSD.
Let's break it down and explore both what is and what could be done:
What You Can Do on pfSense Today:
1. Monitor Per-Rule Packet/Byte Counters, Each firewall rule in pf already tracks:
- Number of packets matched
- Number of bytes matched
You can see this via:
pfSense GUI:
Go to Diagnostics → pfTop, then choose rules or rules (bytes) views.
CLI using pfctl: pfctl -vvsr
This will output per-rule stats like:@1 pass in quick on em0 proto tcp from any to any port = 22 flags S/SA keep state (if-bound)
[ Evaluations: 1000000 Packets: 123456 Bytes: 12345678 States: 5 ]2. Estimate Rule Cost Using Hit Rate and Rule Order
pf processes rules top-down. A rule near the bottom of a large list with lots of matches is inefficient.So:
Reorder rules with higher hit counts closer to the top
Eliminate or merge redundant rules
What You Cannot Do (Yet) on pfSense
No Native CPU Cycle Measurement Per Rule
Unlike ipfw, pf does not profile CPU cycles per rule. Reasons:pf is a stateless rule matcher with fast path optimizations; its kernel code isn't instrumented for CPU-time profiling.
pf focuses on packet path and counters, not runtime cost metrics.
Alternatives and Advanced Workarounds
Option 1: Use DTrace (FreeBSD only, not available on pfSense CE/Plus)
If you're on vanilla FreeBSD (not pfSense), you can:Enable DTrace
Hook into pf_test() or pf_check_in() functions
Measure time spent per rule using custom probes
Sample DTrace snippet (illustrative only):
pf:rule:match
{
self->ts = timestamp;
}pf:rule:exit
/self->ts/
{
@time[rule_id] = quantize(timestamp - self->ts);
self->ts = 0;
}But again: this is NOT available on pfSense directly. You’d need a custom build.
Option 2: Mirror and Benchmark in IPFW (Test Rig)
If optimization is critical:Export the same ruleset to a test VM running FreeBSD + IPFW
Use ipfw's net.inet.ip.fw.enable=1 and enable per-rule accounting:
sysctl net.inet.ip.fw.verbose=1
ipfw -a list
Simulate traffic and observe both match counts and CPU impact (possible with DTrace).Suggested Metrics for Rule Profiling
Metric-------------How to Get-----------Use for Optimization
Packets per rule----pfctl -vvsr-----------Prioritize high-hit rules
Bytes per rule------pfctl -vvsr-----------Identify bandwidth-heavy rules
Rule evaluation order----Rule position in pf.conf---Push common rules up
State counts-------pfctl -ss
-----------wc -l
CPU usage (global)-------top / systat -vmstat--------Coarse measure of FW CPU impact