Making it permanent
Everything so far was typed at the command line, and is gone after a reboot. Making it permanent takes two pieces.
Uploads: systemd-networkd. networkd can configure CAKE directly, with a [CAKE] section in the WAN interface's .network file: the bandwidth, and FlowIsolationMode=dual-src-host. networkd applies it whenever it sets up the interface.
Downloads: a small service. networkd can't add the ingress redirect to the IFB, so a short script does the five steps from Downloads, and a oneshot systemd unit runs it at boot, after networkd. RemainAfterExit=yes keeps the service "active" so systemctl status shows it ran, and systemctl stop removes the shaping.
After a reboot, both are back on their own: CAKE on ens4 in dual-srchost mode from networkd, and the IFB with CAKE in dual-dsthost mode from the service. Loaded latency is again about 2 ms on uploads and under 1 ms on downloads.
# /etc/systemd/network/20-wan.network: the link to the modem, with CAKE on the way out.
[Match]
Name=ens4
[Network]
Address=192.0.2.2/24
Gateway=192.0.2.1
LinkLocalAddressing=no
IPv6AcceptRA=no
# Uploads: shape to just under the line's 5 Mbit/s, sharing it equally between LAN hosts.
[CAKE]
Parent=root
Bandwidth=4500K
FlowIsolationMode=dual-src-host- Lines 12–15: networkd puts CAKE on ens4 whenever it configures the interface.
#!/bin/sh
# /usr/local/sbin/cake-ingress: shape downloads arriving on the WAN with CAKE.
# Incoming traffic is redirected to an IFB device, so CAKE can queue it "on the way out" of that.
set -e
WAN=ens4 IFB=ifb4ens4 BANDWIDTH=18mbit
case "$1" in
start)
ip link add "$IFB" type ifb 2>/dev/null || true
ip link set "$IFB" up
tc qdisc del dev "$WAN" ingress 2>/dev/null || true
tc qdisc add dev "$WAN" handle ffff: ingress
tc filter add dev "$WAN" parent ffff: matchall action mirred egress redirect dev "$IFB"
tc qdisc replace dev "$IFB" root cake bandwidth "$BANDWIDTH" ingress dual-dsthost
;;
stop)
tc qdisc del dev "$WAN" ingress 2>/dev/null || true
ip link del "$IFB" 2>/dev/null || true
;;
esac- Line 5: The three things to change for your own line.
- Lines 9–14: The download shaping, as typed earlier.
- Lines 16–19: And how to undo it.
# /etc/systemd/system/cake-ingress.service
[Unit]
Description=CAKE shaping for downloads on the WAN link
After=systemd-networkd.service
Wants=systemd-networkd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/cake-ingress start
ExecStop=/usr/local/sbin/cake-ingress stop
[Install]
WantedBy=multi-user.target- Lines 4–5: Run after networkd has set up the interfaces.
- Lines 8–11: A oneshot service that stays "active", so status shows it ran and stop undoes it.
root@gw:~# chmod 755 /usr/local/sbin/cake-ingress && systemctl daemon-reload && systemctl enable cake-ingress.service
Created symlink '/etc/systemd/system/multi-user.target.wants/cake-ingress.service' → '/etc/systemd/system/cake-ingress.service'.
root@gw:~# systemctl reboot
root@gw:~# uptime -p; systemctl is-active systemd-networkd cake-ingress; tc qdisc show dev ens4; tc qdisc show dev ifb4ens4
up 0 minutes
active
active
qdisc cake 8001: root refcnt 2 bandwidth 4500Kbit diffserv3 dual-srchost nonat nowash no-ack-filter split-gso rtt 100ms raw overhead 0
qdisc ingress ffff: parent ffff:fff1 ----------------
qdisc cake 8002: root refcnt 2 bandwidth 18Mbit diffserv3 dual-dsthost nonat nowash ingress no-ack-filter split-gso rtt 100ms raw overhead 0
root@client:~# iperf3 -c 198.51.100.10 -t 20 > /tmp/up.txt & sleep 3; ping -q -c 75 -i 0.2 198.51.100.10 | tail -2; wait; grep receiver /tmp/up.txt
75 packets transmitted, 75 received, 0% packet loss, time 15099ms
rtt min/avg/max/mdev = 0.436/2.375/4.095/0.918 ms
[ 5] 0.00-20.01 sec 10.2 MBytes 4.30 Mbits/sec receiver
root@client:~# iperf3 -c 198.51.100.10 -t 20 -R > /tmp/down.txt & sleep 3; ping -q -c 75 -i 0.2 198.51.100.10 | tail -2; wait; grep receiver /tmp/down.txt
75 packets transmitted, 75 received, 0% packet loss, time 15312ms
rtt min/avg/max/mdev = 0.203/0.715/1.844/0.293 ms
[ 5] 0.00-20.00 sec 40.6 MBytes 17.0 Mbits/sec receiver- Lines 1–2: Enable the service.
- Lines 6–12: After the reboot: networkd's CAKE on ens4 (dual-srchost), and the service's IFB with CAKE (dual-dsthost).
- Lines 14–22: Loaded latency still about 2 ms up and under 1 ms down.