Operations 11 min read

Master Linux Traffic Shaping: Limit Bandwidth per IP/Port Using tc

This guide explains Linux traffic control fundamentals, showing how to create qdisc, class, and filter structures with the tc tool to shape traffic, limit bandwidth for specific IPs or ports, and manage both egress and ingress traffic using ifb devices.

Open Source Linux
Open Source Linux
Open Source Linux
Master Linux Traffic Shaping: Limit Bandwidth per IP/Port Using tc

1. Linux Traffic Control Principles

By queuing packets, we can control how packets are sent, known as traffic shaping, which includes operations such as adding delay, dropping packets, reordering, duplication/corruption, and rate control.

Increase latency

Drop packets

Reorder

Duplicate or corrupt

Rate control

Under the qdisc-class-filter structure, traffic control requires three steps:

Create a qdisc queue

Linux controls traffic by queuing packets, so a queue must exist first.

Create class classification

A class defines traffic policy categories, e.g., two tiers of bandwidth limits 10 MBps and 20 MBps.

Create filter

Creating a class alone does not bind any IP or port; a filter must bind specific IP/Port to the class for the control to take effect.

TC is the Linux traffic control tool and a core component of networking solutions such as Cilium/eBPF.

2. Limit Access Speed for Specific IP/Port on the Host

2.1 View Network Interface

ifconfig

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 1.1.1.1  netmask 255.255.254.0  broadcast 1.1.1.1
        inet6 1::1:1:1:1  prefixlen 64  scopeid 0x20<link>
        ether 1:1:1:1:1:1  txqueuelen 1000  (Ethernet)
        RX packets 2980910  bytes 2662352343 (2.4 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1475969  bytes 122254809 (116.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2.2 Configure qdisc-class-filter

Create root qdisc

tc qdisc add dev eth0 root handle 1: htb default 1

Create first-level class binding all bandwidth resources

Note that the unit is 6 MBps, which equals 48 Mbps.

tc class add dev eth0 parent 1:0 classid 1:1 htb rate 6MBps burst 15k

Create child class

Multiple child classes can be created for fine‑grained traffic management.

tc class add dev eth0 parent 1:1 classid 1:10 htb rate 6MBps ceil 10MBps burst 15k

Here ceil sets the upper limit; the normal rate is 6 MBps, but the bandwidth can reach 10 MBps when the network is idle.

Create filter to limit IP

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 1.2.3.3 flowid 1:10

This limits traffic to 1.2.3.4 to class 1:10 (6 MBps). You can also apply the class to an entire subnet such as 1.2.0.0/16.

2.3 View and Clean Configuration

Show class configuration

tc class show dev eth0

class htb 1:10 parent 1:1 leaf 10: prio 0 rate 48Mbit ceil 80Mbit burst 15Kb cburst 1600b 
class htb 1:1 root rate 48Mbit ceil 48Mbit burst 15Kb cburst 1590b

Show filter configuration

tc filter show dev eth0

filter parent 1: protocol ip pref 1 u32 chain 0 
filter parent 1: protocol ip pref 1 u32 chain 0 fh 800: ht divisor 1 
filter parent 1: protocol ip pref 1 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 not_in_hw 
  match 01020303/ffffffff at 16

Delete all configuration

tc qdisc del dev eth0 root

3. Limit Host’s Outbound Traffic to Specific IP/Port

Since queuing rules apply to egress traffic, inbound (ingress) traffic must be redirected to an ifb device, and then limited on its egress side.

3.1 Enable Virtual Interface

modprobe ifb numifbs=1
ip link set dev ifb0 up

3.2 Configure qdisc-class-filter

Add ingress qdisc tc qdisc add dev eth0 handle ffff: ingress Redirect traffic to ifb0

tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

Add class and filter on ifb0

tc qdisc add dev ifb0 root handle 1: htb default 10
tc class add dev ifb0 parent 1:0 classid 1:1 htb rate 6Mbps
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 6Mbps
tc filter add dev ifb0 parent 1:0 protocol ip prio 16 u32 match ip dst 1.2.3.4  flowid 1:10

3.3 View and Clean Configuration

Monitoring chart shows inbound traffic limited below 6 MBps while outbound traffic is unrestricted.

Incoming traffic is limited to under 6 MBps, while outgoing traffic is not limited.

Show class configuration

tc class show dev ifb0

class htb 1:10 parent 1:1 prio 0 rate 48Mbit ceil 48Mbit burst 1590b cburst 1590b 
class htb 1:1 root rate 48Mbit ceil 48Mbit burst 1590b cburst 1590b

Show filter configuration

tc filter show dev ifb0

filter parent 1: protocol ip pref 16 u32 chain 0 
filter parent 1: protocol ip pref 16 u32 chain 0 fh 800: ht divisor 1 
filter parent 1: protocol ip pref 16 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 not_in_hw 
  match 01020304/ffffffff at 16

Delete all configuration

tc qdisc del dev eth0 ingress
tc qdisc del dev ifb0 root
modprobe -r ifb

4. References

https://arthurchiao.art/blog/lartc-qdisc-zh/

https://serverfault.com/questions/350023/tc-ingress-policing-and-ifb-mirroring

Original article reproduced from 陈少文的博客, copyright belongs to the original author.
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

LinuxTraffic ShapingtcNetwork Bandwidthqdiscifb
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.