I recently had to shape the connection of a FreeBSD firewall due to massive packet loss when the 2Mbit line reached full capacity in either direction.

As usual know your basic FreeBSD (incl. how to compile a kernel) to use this guide. A lot of this guide can be found in the FreeBSD Handbook.

In your custom kernel file add these line to enable pf, pflog(optional) and altq

device pf
device pflog
device pfsync

options         ALTQ
options         ALTQ_CBQ        # Class Bases Queuing (CBQ)
options         ALTQ_RED        # Random Early Detection (RED)
options         ALTQ_RIO        # RED In/Out
options         ALTQ_HFSC       # Hierarchical Packet Scheduler (HFSC)
options         ALTQ_PRIQ       # Priority Queuing (PRIQ)
options         ALTQ_NOPCC      # Required for SMP build

Add the firewall options (again pflog is optional) to rc.conf

pf_enable="YES"                 # Enable PF (load module if required)
pf_rules="/etc/pf.conf"         # rules definition file for pf
pf_flags=""                     # additional flags for pfctl startup
pflog_enable="YES"              # start pflogd(8)
pflog_logfile="/var/log/pflog"  # where pflogd should store the logfile
pflog_flags=""                  # additional flags for pflogd startup

If you use it as a firewall with NAT or as a router/gateway add

gateway_enable="YES"            # Enable as LAN gateway

Edit your /etc/pf.conf file and change the details to match your setup

int_if="em0"
ext_if="em1"
 
internal_net="10.10.10.0/24"
external_addr="x.x.x.x"
 
altq on $ext_if hfsc bandwidth 1950Kb queue {def_up}
altq on $int_if hfsc bandwidth 1950Kb queue {def_down}
 
queue def_up bandwidth 1950Kb hfsc(default)
queue def_down bandwidth 1950Kb hfsc(default)
 
nat on $ext_if from $internal_net to any -> $external_addr
 
pass in quick on $ext_if from any to any
pass out quick on $int_if from any to any queue def_down
 
pass in quick on $int_if from any to any
pass out quick on $ext_if from any to any queue def_up

This will shape your bandwidth to a maximum of 1950Kbit/sec in both directions (as I am using it as a firewall with NAT). One of the limitations of pf+ALTQ is that you can’t shape both direction on one interface.

That’s it, enjoy easy bandwidth shaping – for more detailed ALTQ setups and shaping/prioritizing pr. protocol/port look here or here.

NOTE: OpenBSD changed the syntax of the pf configuration, but FreeBSD is still using the old syntax – so make sure the guides you use online are for FreeBSD’s syntax.

Did you like this? Share it: