Traffic Shaping with pf/ALTQ
Sallyport is the traffic shaping bridge for the office. It runs FreeBSD in bridge mode, and uses PF's ALTQ to do bandwidth shaping. It is installed directly between our LAN Firewall, and the Internet.
Contents
Why not do the shaping on the firewall?
Good question. Here's the thing: ALTQ has this huge caveat - it can only queue traffic on an outbound interface. That is, say you have the following firewall configuration:
(external interface - xl0) _________|___________ | | | firewall | |___________________| | | (LAN interface) (DMZ interface)
In such a configuration, you use the external interface to limit upload, but you have to use both the LAN and the DMZ interface to limit downloads. They can't share a queue, and they can't use the same one. Ergo, unless you're willing to hard limit the LAN to say, 66% of your pipe, and the DMZ to the other 33%, you have to do the queuing elsewhere.
Hardware
- P3 833MHz
- 512MB ram
- 1x22GB ATA100
Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 19G 737M 17G 4% / devfs 1.0K 1.0K 0B 100% /dev
Software
- FreeBSD 6.2-RELEASE (GENERIC-ALTQ-BRIDGE) #0: Wed Mar 14 14:01:21 CDT 2007
Network Configuration
- xl0: LAN/Admin Connection
- xl1: External/Inet Connection (bridge)
- xl2: Internal Connection (bridge)
ALTQ Configuration
Kernel Bits
This configuration requires Bridging and ALTQ bits in the kernel.
Enable Bridging
Set the following entries in /etc/sysctl.conf:
net.link.ether.bridge.enable=1 net.link.ether.bridge.config=xl1,xl2
Configure PF
Configure pf.conf with two queues to prioritize traffic to the downtown subnets and guarantee a certain amount of bandwidth, leaving the rest to random downloads and web browsing.
# If you're going to change these values, change the sysctl # variable in /etc/sysctl.conf for bridging! ext_if="xl1" int_if="xl2" # LAN IPs table <lanips> { 10.0.0.1/24, 192.168.1.1/24 } # Use the external interface to queue uploads (towards the internet) altq on $ext_if cbq bandwidth 1.544Mb queue {uploads} queue uploads bandwidth 100% cbq(default ecn) # queue downloads on the internal interface (*sigh*) altq on $int_if cbq bandwidth 1.544Mb queue {other, downtown} queue other bandwidth 1Mb priority 2 cbq(default ecn) queue downtown bandwidth 0.544Mb priority 1 cbq(borrow ecn) pass in quick on $ext_if from <downtown> to any queue downtown keep state pass in quick on $ext_if from !<downtown> to any queue other keep state pass out quick on $ext_if queue uploads keep state