Add CHOKe for Flow-Aware Queue Control
CHOKe is the tc queueing discipline that punishes a flow for hogging the queue, not a complete bandwidth policy on its own. It's a classless, packet-counting qdisc based on RED, and this walks through adding it, reading its counters, and pulling it back out cleanly.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes, plus time to watch real traffic. You need the iproute2 package, the interface name, and elevated privileges for the actual change. The examples use IFACE as a placeholder, swap in a real interface such as eth0 rather than typing the placeholder literally.
Warning
Changing a live interface's root qdisc can alter latency, packet drops and throughput immediately. Test in a network namespace or maintenance window where you can, and record the existing configuration before you replace it.
1. Check the installed implementation
Start with read-only checks. On this machine tc reports iproute2 6.1.0, and the installed Debian package is iproute2 6.1.0-1ubuntu6.4. The local manual page has an older synopsis, so the command's own help is the real authority for the parser installed on this host:
$ tc -V
tc utility, iproute2-6.1.0, libbpf 1.3.0
$ dpkg-query -W -f='${Package} ${Version}\n' iproute2
iproute2 6.1.0-1ubuntu6.4
$ tc qdisc add choke help
Usage: ... choke limit PACKETS bandwidth KBPS [ecn]
[ min PACKETS ] [ max PACKETS ] [ burst PACKETS ]
The installed syntax requires limit and bandwidth, and accepts optional ecn, min, max and burst. Don't copy the manual page's older avpkt and probability form into a script without testing it against your package.
Checkpoint
If the help output on your host differs, stop and adapt the command to that output. Package versions can expose different user-space interfaces even when the kernel qdisc shares the same name.
2. Save the current qdisc
Inspect the interface first. This is an ordinary command and normally needs no root access:
$ tc qdisc show dev IFACE
qdisc FOO 0: root ...
Save it, and if the existing qdisc has more parameters, grab a detailed view too:
$ tc -s qdisc show dev IFACE
Don't assume the existing root qdisc is disposable. A server may already rely on shaping, prioritisation or an ingress setup. If you can't explain the current configuration, don't replace it on a production interface.
3. Add CHOKe as the root qdisc
For a controlled test, set a packet limit and the interface bandwidth. These values are examples, not universal tuning advice. limit, min, max and burst are packet counts in the installed syntax; bandwidth is expressed in kilobits per second by the command help:
$ sudo tc qdisc add dev IFACE root choke \
limit 10000 bandwidth 100000 \
min 1000 max 4000 burst 20
The command should print nothing and return status zero. Verify the qdisc immediately:
$ tc qdisc show dev IFACE
qdisc choke 8001: root refcnt 2 limit 10000 min 1000 max 4000 burst 20 bandwidth 100000
$ tc -s qdisc show dev IFACE
The handle, refcount and stats are host-specific, so compare type and configured values rather than expecting this exact line. If the add command says a qdisc already exists, don't reach for replace as a reflex. Go back to the saved configuration and decide whether a replacement is actually authorised.
4. Understand what the thresholds do
CHOKe watches the average queue length. Once that average reaches the configured region, it draws a random packet already in the queue and compares its flow with the packet being queued. A match drops both packets, which makes a flow that keeps filling the queue more likely to lose packets than one that only shows up occasionally.
- Below min: no early marking expected.
- Between min and max: the RED-style marking probability climbs.
- Above max: new packets are marked or dropped.
- Above the real queue limit: new packets are always dropped.
CHOKe counts packets, unlike RED's byte-oriented limits, so a large packet and a small packet each cost one queue slot for these thresholds. None of this guarantees a rate or latency target, the qdisc can't predict your traffic mix, and a busy queue can make a poor configuration visible as loss or delay. Treat the first run as an observation exercise.
5. Observe counters without generating a test flood
Recheck statistics while the interface carries its normal workload:
$ tc -s qdisc show dev IFACE
$ sleep 10
$ tc -s qdisc show dev IFACE
Look for whether packet and byte counters move, and whether drops or backlog grow. Formatting varies between releases. A quiet interface can show zero drops even when the qdisc is configured correctly, that's not proof it's being exercised.
Don't flood a shared or production link just to make counters move. If you need a repeatable experiment, isolate it in a network namespace or lab network and monitor the other endpoint too.
6. Remove the test configuration
Removing a root qdisc is a service-affecting change. Confirm the target twice, then delete it with elevated privileges:
$ tc qdisc show dev IFACE
$ sudo tc qdisc del dev IFACE root
$ tc qdisc show dev IFACE
Recovery
After deletion, Linux may show the interface's default qdisc, or another configuration may recreate one. If the interface had a deliberate qdisc before the test, restore it from the command or configuration you recorded in step 2, don't invent a restoration command from the abbreviated output.
Common traps
- Wrong units. CHOKe's queue thresholds are packets here, not bytes. The bandwidth argument is separate and shown in kilobits per second by this
tcbuild. - Stale syntax. The installed help doesn't list
avpktorprobability. Always checktc qdisc add choke helpbefore automating across distributions. - ECN assumptions.
ecnchanges how eligible congestion is signalled, it doesn't make the queue lossless, and the configured limit still matters. - Wrong qdisc location.
rootreplaces the interface's root qdisc; a classless qdisc isn't a child class you can attach beneath an arbitrary class hierarchy.
Done means
- Checked the installed syntax. The
tcversion and CHOKe help output match what you expect. - Inspected before changing. The original qdisc was recorded before any privileged change.
- Verified live. CHOKe shows up in
tc qdisc show, and its counters were checked withtc -s. - Tested responsibly. Any live-interface test was treated as service-affecting and didn't rely on a traffic flood.
- Cleaned up or restored. The test qdisc was removed, or the recorded original configuration was put back.