Re: traffic shaping with tc on Linux 5.4.x
Lars Noodén <[email protected]> Mon, 05 Apr 2021 03:32:41 +0000
| Newsgroups | org.kernel.vger.lartc |
|---|---|
| Message-ID | <[email protected]> |
On 2/16/21 6:42 PM, Dave Taht wrote:
> Me being me, I'd just turn on fq_codel as the qdisc, and anything
> interactive, not just ssh, would be automatically prioritized, no need
> for any further classification usually.
How would that be done? I've been picking away at the problem over
time. Below is the current state of my attempt at it.
> Or, if you want something that respects dscp markings, try cake, which
> is basically a one liner on the up and 4 on the down. I don't think
> you have a working tc mired line for shaping inbound above.
>
> To achieve basically everything you did above, if you have sch_cake (openwrt and
> linux 4.19 and after)
>
> tc qdisc add dev eth0 root cake bandwidth 800kbit ack-filter
> {docsis/dsl/ethernet)
>
> (cake also supports the connmark facility)
>
>
> I too am very interested in seeing ipfs perform well, and would be
> very interested in your results. However at 800kbit, oy... and you
> really need to shape inbound too.
The 800kbit cap is necessary because the shaping has to occur on a node
on the LAN not the LAN's router itself. Above that rate, it gets in the
way of the other devices.
What I have below mostly seems to keep IPFS under control, but
establishing new SSH connections involves a very, very long delay while
IPFS is running full blast. So I am welcoming any and all corrections.
/Lars
(Apologies for using iptables instead of nftables in this iteration.)
#!/bin/sh
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
if=wlan0
# remove all existing qdiscs, classes and filters from interface
tc qdisc del dev $if ingress 2>/dev/null
tc qdisc del dev $if root 2>/dev/null
# respect dscp markings using cake
tc qdisc add dev $if root cake bandwidth 800kbit ack-filter
# set default class for all unclassified traffic
tc qdisc replace dev $if root handle 1: htb default 30
# top level class with handle 1:1
# tc class add dev $if parent 1: classid 1:1 htb rate 800kbit
# Class 1:10 is highest priority path, outgoing SSH/SFTP
# Class 1:20 is outgoing SSH/SFTP bulk transfers
# Class 1:30 is next highest priority path, HTTP/HTTPS traffic
# Class 1:40 is default with next lowest priority
# Class 1:50 is lowest priority but highest total bandwidth, IPFS
tc class add dev $if parent 1:1 classid 1:10 htb \
rate 600kbit ceil 1mbit prio 1
tc class add dev $if parent 1:1 classid 1:20 htb \
rate 600kbit ceil 1mbit prio 2
tc class add dev $if parent 1:1 classid 1:30 htb \
rate 100kbit ceil 1mbit prio 3
tc class add dev $if parent 1:1 classid 1:40 htb \
rate 600kbit ceil 1mbit prio 4
tc class add dev $if parent 1:1 classid 1:50 htb \
rate 790kbit prio 5
# leaf qdisc to each child class
tc qdisc add dev $if parent 1:10 fq_codel
tc qdisc add dev $if parent 1:20 fq_codel
tc qdisc add dev $if parent 1:30 fq_codel
tc qdisc add dev $if parent 1:40 fq_codel
tc qdisc add dev $if parent 1:50 fq_codel
# add filters to prioritize traffic
tc filter add dev $if parent 1: handle 100 fw classid 1:10
tc filter add dev $if parent 1: handle 200 fw classid 1:20
tc filter add dev $if parent 1: handle 400 fw classid 1:40
tc filter add dev $if parent 1: handle 500 fw classid 1:50
# drop whatever comes in too fast
tc qdisc add dev $if handle ffff: ingress
tc filter add dev $if parent ffff: protocol ip prio 50 u32 \
match ip src 0.0.0.0/0 police rate 9mbit burst 9mbit drop flowid :1
# clear chains if possible
iptables -Z; # zero counters
iptables -t mangle -F; # flush (delete) rules
iptables -t mangle -X; # delete all extra chains
# label outgoing traffic
iptables -t mangle -A OUTPUT -p tcp -m tcp -m multiport --sports 22 \
-m dscp --dscp 0x04 -m comment --comment sshinteractive \
-j MARK --set-mark 100
iptables -t mangle -A OUTPUT -p tcp -m tcp -m multiport --sports 22 \
-m dscp --dscp 0x02 -m comment --comment sshbulk \
-j MARK --set-mark 200
iptables -t mangle -A OUTPUT -p tcp --match multiport \
--sports 80,443,1965 \
-j MARK --set-mark 400
iptables -t mangle -A OUTPUT -p tcp --match multiport --sports 4001 \
-j MARK --set-mark 500