Sổ tay kỹ thuật

Giả lập delay, loss, băng thông bằng tc netem và tbf

how-to#linux#tc#networking#testing· cập nhật 2026-11-06

Dùng khi cần thử app/automation trong điều kiện mạng xấu (WAN chậm, mất gói, băng thông thấp) ngay trên một máy Linux, và gỡ bỏ sạch sau khi thử.

Sửa trang này
Mục lục

Tóm tắt: tc gắn qdisc vào interface. netem thêm delay/jitter/loss/duplicate/reorder/corrupt, tbf giới hạn băng thông. Qdisc chỉ tác động chiều ra (egress) của interface đó; muốn tác động chiều vào thì chuyển traffic sang interface ifb. Tất cả là runtime, mất sau reboot, gỡ bằng tc qdisc del dev <if> root.

Đặt netem lên interface đang SSH vào có thể làm mất phiên. Hẹn giờ tự gỡ trước khi thử: sudo systemd-run --on-active=5m /usr/sbin/tc qdisc del dev eth0 root.

Luồng hoạt động

flowchart LR A["App"] --> B["root qdisc eth0"] B --> C["netem: delay, loss"] C --> D["tbf: rate limit"] D --> E["NIC eth0 (egress)"] F["Traffic vào eth0"] --> G["ingress + mirred"] G --> H["ifb0: netem"] H --> I["Stack nhận"]

Lệnh

Xem và gỡ

tc qdisc show dev eth0
tc -s qdisc show dev eth0           # kèm counter: sent, dropped, overlimits
sudo tc qdisc del dev eth0 root     # gỡ toàn bộ, về mặc định (fq_codel / mq)

netem cơ bản

Mục đích Lệnh
Delay cố định 100 ms tc qdisc add dev eth0 root netem delay 100ms
Delay 100 ms ± 20 ms jitter, phân bố normal tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal
Mất 1% gói tc qdisc add dev eth0 root netem loss 1%
Mất gói theo cụm (correlation 25%) tc qdisc add dev eth0 root netem loss 1% 25%
Nhân đôi / hỏng / đảo thứ tự gói tc qdisc add dev eth0 root netem delay 10ms duplicate 1% corrupt 0.1% reorder 5% 50%
Giới hạn tốc độ ngay trong netem tc qdisc add dev eth0 root netem delay 50ms rate 10mbit
Đổi tham số không gỡ tc qdisc change dev eth0 root netem delay 200ms loss 2%
Thêm hoặc thay (idempotent) tc qdisc replace dev eth0 root netem delay 80ms

Tất cả cần sudo. reorder chỉ có tác dụng khi có delay (gói "đảo" được gửi ngay, phần còn lại bị delay).

netem + tbf (delay và giới hạn băng thông)

sudo tc qdisc add dev eth0 root handle 1: netem delay 50ms loss 0.5%
sudo tc qdisc add dev eth0 parent 1: handle 2: tbf rate 10mbit burst 32kbit latency 400ms
tc -s qdisc show dev eth0

tbf: rate là tốc độ, burst là bucket (quá nhỏ so với rate thì không đạt được rate), latency là thời gian tối đa gói nằm chờ (quá thì drop).

Chỉ áp cho một đích

Dùng prio để chia band, chỉ band 3 có netem, filter đẩy traffic tới đích vào band đó:

sudo tc qdisc add dev eth0 root handle 1: prio
sudo tc qdisc add dev eth0 parent 1:3 handle 30: netem delay 200ms loss 2%
sudo tc filter add dev eth0 parent 1:0 protocol ip prio 3 \
  u32 match ip dst 203.0.113.0/24 flowid 1:3
tc filter show dev eth0

Chiều vào (ingress) qua ifb

sudo modprobe ifb
sudo ip link add ifb0 type ifb
sudo ip link set ifb0 up
sudo tc qdisc add dev eth0 handle ffff: ingress
sudo tc filter add dev eth0 parent ffff: matchall action mirred egress redirect dev ifb0
sudo tc qdisc add dev ifb0 root netem delay 100ms
 
# Gỡ
sudo tc qdisc del dev eth0 ingress
sudo tc qdisc del dev ifb0 root
sudo ip link del ifb0

Trong container / network namespace

Không cần đụng interface của host: chạy tc trong netns của container (veth phía container).

sudo ip netns exec ns1 tc qdisc add dev veth1 root netem delay 100ms
# Docker: nsenter vào netns của container
sudo nsenter -t "$(docker inspect -f '{{.State.Pid}}' app)" -n tc qdisc add dev eth0 root netem delay 100ms

Đo kết quả bằng ping, mtr, iperf3: xem Network testing cheatsheet.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Error: Exclusivity flag on, cannot modify. Đã có qdisc root do bạn thêm Dùng tc qdisc change / replace, hoặc del rồi add
Error: Specified qdisc kind is unknown. Thiếu module sch_netem (một số kernel tối giản/cloud) sudo modprobe sch_netem; không có thì cài gói linux-modules-extra-$(uname -r) nếu tồn tại
Delay chỉ thấy một chiều netem chỉ tác động egress Áp cả hai đầu, hoặc dùng ifb cho chiều vào
ping thấy delay gấp đôi Áp netem ở cả hai máy Bình thường: RTT = tổng hai chiều
tbf không đạt rate đặt burst quá nhỏ, hoặc offload (TSO/GSO) gửi gói lớn Tăng burst; thử ethtool -K eth0 tso off gso off khi test
Mất SSH ngay sau khi thêm Loss/delay quá nặng trên interface quản lý Gỡ từ console hoặc chờ job systemd-run tự gỡ
Sau test máy vẫn chậm Quên gỡ qdisc tc qdisc show trên mọi interface, del dev <if> root

Tham khảo