Я долго писал tc-простыни на HTB. Подбирал burst, quantum, выставлял класс по умолчанию, страдал с подсчётом байтов. CAKE появился в ядре 4.19, но я добрался до него только через несколько лет, когда устал в очередной раз отлаживать «почему трафик пилится, но один поток жрёт всё». После CAKE возвращаться к HTB не хочется вообще.

Что такое CAKE и почему он удобный

CAKE (Common Applications Kept Enhanced) — это qdisc, который из коробки делает три вещи: rate-limit, fair queueing с учётом потоков и AQM (борьбу с bufferbloat через CoDel). Всё параметрами по умолчанию настроено разумно, и для большинства случаев достаточно одной строки.

tc qdisc replace dev eth0 root cake bandwidth 500mbit

Всё. Это полноценный rate-limit на 500 Мбит/с с честным распределением по потокам и контролем latency. На HTB то же самое — это блок строк на 15-20, с классами, фильтрами и SFQ внутри.

Базовые сценарии

Ограничение скорости на интерфейсе

tc qdisc replace dev eth0 root cake bandwidth 1gbit

Раздельный лимит upload и download

Download ограничить сложнее, потому что на физическом интерфейсе мы видим только то, что уже пришло. Стандартный приём — IFB-интерфейс:

modprobe ifb numifbs=1
ip link set dev ifb0 up
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol all u32 match u32 0 0 \
    action mirred egress redirect dev ifb0
tc qdisc replace dev ifb0 root cake bandwidth 500mbit
tc qdisc replace dev eth0 root cake bandwidth 100mbit

Тут upload на eth0 ограничен 100 Мбит, download через IFB — 500 Мбит.

Учёт оверхеда

Если вы режете канал на VPN-туннеле или поверх PPPoE — у пакетов есть оверхед, который CAKE умеет учитывать сам:

tc qdisc replace dev wg0 root cake bandwidth 200mbit \
    overhead 80 mpu 84

Для WireGuard оверхед примерно 60-80 байт в зависимости от IPv4/IPv6 и MTU. mpu 84 (minimum packet unit) важен, потому что мелкие пакеты в реальности занимают на проводе больше, чем их payload.

Diffserv и приоритеты

По дефолту CAKE использует режим diffserv3 — три класса (bulk/best-effort/voice). Это значит, что трафик с DSCP-метками CS5/EF (голос, видеоконференции) автоматически идёт в приоритетный класс. На практике это полезно: если на одной ноде у вас и SSH, и тяжёлые бэкапы — SSH не лагает, потому что попадает в voice-tin (по 22 порту обычно ставят CS5 на стороне sshd).

Включить вручную:

tc qdisc replace dev eth0 root cake bandwidth 1gbit diffserv4

Можно выбрать besteffort (один класс, без приоритетов) или diffserv8. На обычной VPS я обычно оставляю diffserv3.

Бенчмарк против HTB+SFQ

Сравнивал на VPS с 1 Гбит/с каналом, лимит выставлял 500 Мбит. Нагрузка — 50 параллельных iperf3-сессий, плюс параллельный ping для измерения латентности.

HTB+SFQ:
throughput 478 Mbps
ping p50 8 мс, p99 145 мс
конфиг — 22 строки

CAKE:
throughput 487 Mbps
ping p50 5 мс, p99 18 мс
конфиг — 1 строка

Разница в throughput почти нулевая, разница в p99-latency — почти на порядок. Это и есть эффект встроенного CoDel — CAKE не даёт очереди разрастаться, и интерактивный трафик не страдает.

Грабли, на которые наступил

Версия iproute2

В Debian 11 версия iproute2 не знала про некоторые ключи CAKE (например, ack-filter). На Debian 12 уже всё нормально. Если получаете Unknown qdisc "cake" — значит, либо модуль не подгружен (modprobe sch_cake), либо ядро древнее.

CAKE на ingress без IFB

Не работает напрямую. Только через IFB или ifb-подобный механизм. Это документировано, но я как-то раз потратил час, прежде чем вспомнил.

Слишком высокий bandwidth

Если выставить bandwidth 1gbit на интерфейсе, который физически выдаёт 950 Мбит — CAKE не сможет нормально шейпить, потому что не успеет вмешаться. Всегда ставьте лимит на 5-10% ниже реальной пропускной способности канала.

# реальный канал 1 Гбит/с
tc qdisc replace dev eth0 root cake bandwidth 940mbit

NAT и flow-isolation

В дефолтном режиме CAKE считает поток по (src, dst, src_port, dst_port, proto). При NAT за роутером это значит, что все клиенты с одним публичным IP считаются одним хостом и делят полосу не так, как ожидаешь. Лечится режимом dual-srchost/dual-dsthost:

tc qdisc replace dev eth0 root cake bandwidth 500mbit dual-srchost

Это говорит CAKE: для исходящего трафика считай fairness по dest-host, а внутри хоста — по flow. Для домашних роутеров — must have.

Просмотр статистики

tc -s qdisc show dev eth0

CAKE показывает много всего — байты по tin’ам, дропы, ECN-отметки, latency-target. Полезно при отладке.

Итог

CAKE — это тот случай, когда новый инструмент реально лучше старого по всем фронтам: проще конфигурится, лучше работает, меньше граблей. Если у вас на ноде стоит классический HTB и нет особых причин его держать — попробуйте CAKE. С большой вероятностью вы снесёте HTB-конфиг через неделю и не вернётесь.