FreeBSD IPFW and Dummynet: Firewall Rules, Queues, and Traffic Emulation
Design auditable IPFW policies and use Dummynet pipes and queues to shape bandwidth, add latency, and test network behavior safely.
IPFW is FreeBSD’s packet-filtering and traffic-control interface. Its ordered rules can allow, deny, count, redirect, or pass selected packets to Dummynet. Dummynet can constrain bandwidth, queue packets, add propagation delay, and model loss. The combination is useful for host policy and repeatable network experiments, but a mistaken live ruleset can sever the management path needed to repair it.
Treat the firewall and traffic shaper as separate decisions: first establish which packets match and what the firewall should do; then choose how matched traffic is queued or delayed. A pipe is not a general-purpose prioritization rule, and a syntactically valid ruleset does not prove both directions of a connection still work.
How the rule path works
IPFW evaluates numbered rules in order when a packet reaches the firewall hook. A matching rule performs its action, which may terminate evaluation or direct the packet to another subsystem. Rule numbers are therefore part of the policy, not decorative labels. Reserve deliberate ranges for loopback, established state, management access, service policy, logging, and the terminal default behavior. Inspect active rules with ipfw -a list; counters distinguish a rule that exists from one that sees traffic.
Stateful policy usually pairs a rule that permits a new flow with state creation and a rule that recognizes return traffic. Exact syntax and placement must match the intended direction and the existing ruleset. Never paste a small example over an unknown production configuration: earlier rules may accept traffic, later rules may never be reached, and a remote reload can lock out its operator.
IPFW can be loaded as a kernel module. On a machine that relies on a console for recovery, confirm the configured default action before loading or enabling the firewall remotely. FreeBSD’s Handbook warns that firewall configuration needs a recovery plan; prepare an out-of-band console or timed rollback before changing active rules.
Pipes and queues are different models
A Dummynet pipe models a link. It can impose a configured rate and delay and can be given a finite queue and packet-loss probability. Packets selected by an IPFW rule are handed to that pipe, making it possible to emulate a slower, longer-distance, or lossy path in a test environment.
A queue is an allocation policy associated with a pipe. For weighted fair queueing, Dummynet classifies flows and divides service according to configured weights. Weights express relative shares among backlogged flows; they are not strict priorities. A flow with a smaller weight can still make progress, and an idle flow does not consume its share merely by existing.
The distinction matters in practice. Use a pipe when the question is “what happens if this link is 8 Mbit/s with 35 ms of delay?” Use queues when the question is “how should several classes of active traffic share a 20 Mbit/s bottleneck?” Combining classification, queues, and a reference pipe is powerful, but it increases the assumptions that must be observed and tested.
A disposable lab example
The following is a shaping fragment for an isolated virtual machine or jail. Replace the interface and traffic selector with the lab’s actual topology. It is not a complete firewall and is not safe to load on a remote production host as-is.
# Create a test link with a 10 Mbit/s rate and 40 ms of configured delay.
ipfw pipe 10 config bw 10Mbit/s delay 40ms
# Shape only traffic matching the chosen lab interface and direction.
ipfw add 100 pipe 10 ip from any to any out via vtnet1
# Inspect rule counters and pipe state while generating a controlled test.
ipfw -a list
ipfw pipe show
This example shapes only outbound packets that match the rule. A TCP conversation has traffic in both directions, and asymmetric shaping can be intentional, but it must not be mistaken for a symmetric link model. In a test, measure from both endpoints and compare application-level latency, throughput, retransmissions, and queueing rather than assuming the configured delay is the complete round-trip time.
Remove or replace lab rules by their known rule number, not by flushing the whole ruleset. A global flush may remove the access rule that keeps a remote session alive. If a rule is only for a short experiment, keep its number in the test notes and clean it up after capturing results.
Safe rollout and observation
Before changing a live firewall, save ipfw -a list, ipfw pipe show, relevant sysctl values, and a copy of the persistent configuration. Confirm the default policy and identify the exact management flow. Use a timed rollback independent of the SSH session, and test from a second host. Review counters after each change; zero hits often mean the interface, direction, address family, or rule ordering is wrong.
For a shaper, record the configured rate, delay, queue limit, loss setting, classifier, and both traffic directions. Compare that configuration with endpoint measurements. A queue that is too small may turn ordinary bursts into loss; a queue that is too large may preserve throughput while adding unacceptable latency. Capture packets and application measurements at the same points before and after the change.
Keep IPv4 and IPv6 policy explicit. Do not assume an IPv4 selector, NAT rule, or test flow proves the IPv6 path. Validate loopback, DHCP or router advertisements where relevant, DNS, management access, and every advertised service before saving the new policy as permanent boot configuration.
The safe operating principle is simple: build the rule path in an isolated topology, observe that the intended counters increment, measure resulting traffic, and only then promote a reviewed configuration with a tested rollback path.
Related:
- Configuring pf on FreeBSD: A Practical Guide to Packet Filtering
- How to Configure FreeBSD as a Router with pf NAT
Sources: