The Illusion of Infinite Bandwidth
When you deploy an Ubuntu server with a 10-Gigabit Network Interface Card (NIC), it is easy to assume bandwidth will never be an issue. However, the Linux kernel network stack operates on a First-In, First-Out (FIFO) queue architecture. It does not inherently understand the priority of the data it is transmitting.
Suppose you host a critical Voice over IP (VoIP) server and a massive FTP backup server on the same Ubuntu machine. If the backup server decides to upload a 500-Gigabyte archive at exactly 2:00 PM, it will ruthlessly saturate the 10Gbps link. Because the Linux kernel is trying to transmit the FTP packets as fast as physically possible, the tiny, latency-sensitive VoIP packets get stuck at the back of the queue. The CEO’s phone call starts lagging, dropping syllables, and eventually disconnects, entirely because a background backup script was allowed to monopolize the physical wire.
To mathematically eliminate this congestion, network engineers deploy Traffic Control (tc). tc is a brutal, kernel-level utility that intercepts outbound packets before they hit the physical NIC. It allows you to build complex Queuing Disciplines (qdiscs). By implementing Quality of Service (QoS), you can explicitly command the kernel: “Never allow FTP traffic to exceed 2Gbps, and mathematically guarantee that VoIP packets always jump to the absolute front of the transmission queue, regardless of network load.”
Step 1: Understanding the Hierarchy (Qdiscs and Classes)
Traffic Control is not a firewall; it does not drop packets based on security rules. It delays and shapes them based on mathematical hierarchies.
To shape traffic, you use a Class-Based Queuing mechanism, specifically HTB (Hierarchical Token Bucket). HTB allows you to define a master speed limit for the entire server, and then carve that speed limit up into smaller “buckets” for different types of traffic.
- The Root Qdisc: The master controller attached to your network interface (e.g.,
eth0). - The Classes: The mathematical subdivisions (e.g., Class 1 for VoIP, Class 2 for FTP).
- The Filters: The rules that sort the packets into the correct classes based on port numbers or IP addresses.
Step 2: Defining the Root Token Bucket
First, you must delete any existing tc rules on your interface to start clean:
sudo tc qdisc del dev eth0 root
Now, you attach the master HTB qdisc to the root of eth0. We will assign this root a handle of 1:. We also tell it to send any unsorted, generic traffic to a default class (which we will build later as 1:20).
sudo tc qdisc add dev eth0 root handle 1: htb default 20
Next, you define the absolute maximum speed the server is allowed to transmit. If you have a 10Gbps link, but you only pay your ISP for 5Gbps, you must shape the root to 5Gbps to prevent upstream packet drops.
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 5gbit
Step 3: Carving the Bandwidth (Guarantees and Ceilings)
Now you carve the 5Gbps master pipeline into your specific application classes.
Class 1: VoIP (High Priority, Low Bandwidth)
VoIP requires very little bandwidth, but it requires zero latency. You guarantee it 100 Megabits, but cap it at 100 Megabits to prevent a rogue UDP flood from masquerading as VoIP.
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 100mbit ceil 100mbit
Class 2: FTP Backups (Low Priority, High Bandwidth)
FTP requires massive bandwidth, but latency doesn’t matter. You guarantee it 1 Gigabit, but if the network is otherwise empty, you allow it to burst up to a ceiling of 4 Gigabits.
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 1gbit ceil 4gbit
Step 4: Sorting the Packets (U32 Filtering)
The buckets exist, but they are empty. The kernel has no idea which packets are VoIP and which are FTP. You must use u32 filters to inspect the packet headers in real-time and sort them into the correct classid.
Filter 1: Sorting VoIP (UDP Port 5060)
Sort all packets originating from the SIP/VoIP port (5060) directly into the high-priority bucket (1:10).
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip sport 5060 0xffff flowid 1:10
Filter 2: Sorting FTP (TCP Port 21)
Sort all packets originating from the FTP port (21) directly into the heavily throttled bucket (1:20).
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip sport 21 0xffff flowid 1:20
(Notice the prio variable. The kernel evaluates Filter 1 first, ensuring VoIP traffic is sorted microseconds faster than FTP traffic).
Step 5: Verifying the Mathematical Shaping
The exact millisecond you inject the filters, the Linux kernel begins violently holding back FTP packets to enforce the 4-Gigabit ceiling, while instantly expediting the UDP VoIP packets.
To mathematically verify that the buckets are catching the correct traffic, you can view the live statistics of the Hierarchical Token Buckets:
sudo tc -s class show dev eth0
The output is incredibly dense. Look for the class htb 1:10 block. You will see a counter labeled Sent showing the exact number of bytes pushed through the VoIP bucket. Look at the class htb 1:20 block; you will see a counter labeled dropped or overlimits. This definitively proves that the kernel is artificially delaying the FTP traffic, forcing it to respect the 4Gbps boundary and keeping the VoIP lane perfectly clear.
Conclusion
Relying on the default FIFO networking queue in a high-density Linux environment guarantees that aggressive, high-bandwidth applications will starve critical, latency-sensitive services. By mastering the tc (Traffic Control) utility, Ubuntu network engineers gain absolute, mathematical command over the kernel’s transmission architecture. The ability to deploy Hierarchical Token Buckets, enforce hard bandwidth ceilings, and prioritize specific application ports transforms raw network throughput into a highly orchestrated, predictable Quality of Service (QoS) engine.