How to Configure Network Traffic Shaping with tc
The tc (traffic control) utility in Linux allows you to shape, schedule, and prioritize network traffic on your Breeze instance. Traffic shaping is essential for ensuring quality of service, preventing bandwidth abuse, and guaranteeing minimum bandwidth to critical services.
Understanding tc Components
Traffic control in Linux uses three building blocks:
- Qdiscs (Queuing Disciplines) — algorithms that decide how packets are queued and dequeued
- Classes — subdivisions within a classful qdisc, each with its own bandwidth allocation
- Filters — rules that classify packets into specific classes
Viewing Current Configuration
Check existing traffic control rules on your interface:
tc qdisc show dev eth0
tc class show dev eth0
tc filter show dev eth0
Simple Rate Limiting with TBF
The Token Bucket Filter (TBF) is the simplest way to limit outbound bandwidth on an interface:
sudo tc qdisc add dev eth0 root tbf \
rate 100mbit \
burst 32kbit \
latency 400ms
This limits outbound traffic to 100 Mbps with a burst allowance of 32 Kbit.
Hierarchical Token Bucket (HTB)
HTB provides more flexible traffic shaping with guaranteed minimums and borrowable maximums. Here is a practical example that prioritizes web traffic over bulk downloads:
# Clear existing rules
sudo tc qdisc del dev eth0 root 2>/dev/null
# Add root HTB qdisc
sudo tc qdisc add dev eth0 root handle 1: htb default 30
# Root class: total bandwidth cap
sudo tc class add dev eth0 parent 1: classid 1:1 htb \
rate 500mbit ceil 500mbit
# High priority: web traffic (guaranteed 300mbit, can burst to 500mbit)
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb \
rate 300mbit ceil 500mbit prio 1
# Medium priority: SSH (guaranteed 50mbit)
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb \
rate 50mbit ceil 200mbit prio 2
# Low priority: everything else (guaranteed 150mbit)
sudo tc class add dev eth0 parent 1:1 classid 1:30 htb \
rate 150mbit ceil 500mbit prio 3
Adding Filters to Classify Traffic
Use u32 filters or iptables marks to sort packets into classes:
# Match HTTP/HTTPS traffic to high-priority class
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \
match ip dport 80 0xffff flowid 1:10
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 \
match ip dport 443 0xffff flowid 1:10
# Match SSH traffic to medium-priority class
sudo tc filter add dev eth0 parent 1: protocol ip prio 2 u32 \
match ip dport 22 0xffff flowid 1:20
Adding Fair Queuing to Leaf Classes
Attach Stochastic Fair Queuing (SFQ) to leaf classes to distribute bandwidth fairly among individual flows:
sudo tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
sudo tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
sudo tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10
Verifying and Monitoring
Monitor traffic shaping statistics in real time:
tc -s qdisc show dev eth0
tc -s class show dev eth0
watch -n 1 tc -s class show dev eth0
The statistics show bytes sent, packets processed, and drops per class. High drop counts in a class indicate that traffic is exceeding its allocated rate.
Persisting Rules Across Reboots
Create a script at /etc/network/if-up.d/tc-rules or use a systemd service to reapply your rules after each reboot on your Breeze.