How to Use Linux TC for Precise Bandwidth and Burst Control
This guide explains Linux traffic control (TC), covering its core components, queueing disciplines, classes, filters, burst parameters, and provides step‑by‑step command examples to limit download speeds for individual IPs or subnets.
Introduction
Linux traffic control (TC) provides a flexible framework for shaping outbound network traffic. By defining bandwidth limits, rate ceilings, and burst behavior, TC can prevent a single host from monopolizing a shared link.
TC Architecture
TC is built from three core components:
Queueing Discipline (qdisc) : Determines how packets are queued and dequeued on an interface. The simplest qdisc, pfifo, queues packets FIFO without modification.
Class : Represents a traffic‑shaping policy (e.g., a guaranteed rate). Classes can be arranged hierarchically, allowing parent classes to allocate bandwidth to child classes.
Filter : Classifies packets into classes based on criteria such as IP address, fwmark, or u32 matches.
Common qdisc types include FIFO, RED, SFQ, Token Bucket, CBQ, and the hierarchical token bucket (HTB), which is the preferred replacement for CBQ.
Key Parameters
rate : Guaranteed bandwidth for a class.
ceil : Maximum bandwidth a class may borrow; must be at least equal to its rate and to the ceil of any child classes.
prio : Priority value; lower numbers indicate higher priority when bandwidth is contested.
burst / cburst : Amount of data that can be transmitted at the interface’s line rate before the shaping limit takes effect. These values should be at least as large as the corresponding values of child classes.
Typical Configuration Workflow
Assuming eth0 is the outbound interface, the following steps create a root HTB qdisc, define a parent class, add child classes, attach a fair‑queueing discipline, and install filters.
Add a root HTB qdisc that will host all classes:
tc qdisc add dev eth0 root handle 1: htb default 1Create a parent class that sets the overall bandwidth ceiling for the interface:
tc class add dev eth0 parent 1:0 classid 1:30 htb rate 2mbit ceil 4mbit prio 2Add a child class for a specific application or IP group:
tc class add dev eth0 parent 1:30 classid 1:31 htb rate 0.5mbit ceil 2mbit prio 3Attach a fair‑queueing discipline (SFQ) to the child class to prevent a single flow from monopolizing the class:
tc qdisc add dev eth0 parent 1:31 handle 31: sfq perturb 10Insert a filter that maps marked packets to the child class. The example uses an fwmark set by iptables:
tc filter add dev eth0 parent 1: protocol ip prio 31 handle 31 fw flowid 1:31Marking Packets with iptables
Packets can be marked in the mangle table and then matched by TC filters using the fwmark classifier.
iptables -t mangle -I FORWARD -i !eth1 -p tcp --sport 80 -s xxx.xxx.xxx.xxx -j MARK --set-mark 31Practical Examples
Example 1 – Limit a single IP
tc qdisc add dev eth0 root handle 1: htb r2q 1</code>
<code>tc class add dev eth0 parent 1: classid 1:1 htb rate 30mbit ceil 60mbit</code>
<code>tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 192.168.1.2 flowid 1:1This limits traffic to 192.168.1.2 to 30 Mbit with a maximum burst up to 60 Mbit.
Example 2 – Limit a /24 subnet and share bandwidth
tc qdisc add dev eth0 root handle 1: htb r2q 1</code>
<code>tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil 1000mbit</code>
<code>tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 192.168.111.0/24 flowid 1:1</code>
<code>tc qdisc add dev eth0 parent 1:1 handle 10: sfq perturb 10The subnet 192.168.111.0/24 receives a total of 50 Mbit (up to 1000 Mbit if unused), and the SFQ discipline prevents any single host from consuming the entire share.
Command Reference
Common TC command syntax:
tc qdisc [add|change|replace|link] dev DEV [parent qdisc-id|root] [handle qdisc-id] qdisc [qdisc‑specific parameters] tc class [add|change|replace] dev DEV parent qdisc-id [classid class-id] qdisc [qdisc‑specific parameters] tc filter [add|change|replace] dev DEV [parent qdisc-id|root] protocol PROTO prio PRIORITY filtertype [filter‑specific parameters] flowid FLOW-IDShow current configuration (including statistics):
tc -s -d qdisc show dev eth0</code>
<code>tc -s -d class show dev eth0</code>
<code>tc filter show dev eth0Delete the root qdisc when cleaning up:
tc qdisc del dev eth0 rootSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
