It was a major disappointment that Asus' routers, for example my AC66, cannot have QoS on without dropping CTF, the hardware acceleration, and thereby cutting router performance drastically. However i've found a way to have limited yet meaningful QoS-like solution while keeping CTF on.
It's based on a 5 band prio qdisc with TOS classification done at iptables. Could be done with the default 3 band prio qdisc too, but 5 gives finer control in a home network environment.
Bands are 0-4, smaller number means higher priority. Large downloads, including Asus' own Download Master, are put to band 4, and in band 0 we find interactive traffic, dns and icmp.
Unfortunately there aren't much ways to measure its performance except looking at the tc stats, so the improvement is mostly anecdotal, but i think i do see a large difference. Before, with link fully saturated with downloads or both down & up, i couldn't even reload websites anymore. Now, i surf with ease.
This is a proof of concept and a skeleton to start improving on, not a whole solution which is more about iptables in general. It's expected you know your way around linux shell and iptables already. Tc you don't have to touch, except for statistics.
Dns and icmp are handled at both prerouting and postrouting because i'm unsure if CTF affects them and the stats don't quite match, if you know better please comment. Also, tc shows stats stuck at zero for band 0 for unknown reasons, something to do with CTF?
Note that it's your own responsibility to make sure traffic in upper bands never saturates the connection, and thus starves the lower bands entirely. You've been warned...
Edit: this is for a connection which uses PPPOE to connect to isp, if you're using direct cable, just replace ppp0 with eth0.
Experimented with a TBF qdisc on eth0 while this on ppp0, but never got the performance quite right. Recommend just a plain pfifo qdisc at eth0, like "tc qdisc replace dev eth0 pfifo ; ifconfig eth0 txqueuelen NN", where NN is 1/10 seconds worth of 1500 byte packets, for example for a 10 Mbit connection, NN=800.
It's based on a 5 band prio qdisc with TOS classification done at iptables. Could be done with the default 3 band prio qdisc too, but 5 gives finer control in a home network environment.
Bands are 0-4, smaller number means higher priority. Large downloads, including Asus' own Download Master, are put to band 4, and in band 0 we find interactive traffic, dns and icmp.
Unfortunately there aren't much ways to measure its performance except looking at the tc stats, so the improvement is mostly anecdotal, but i think i do see a large difference. Before, with link fully saturated with downloads or both down & up, i couldn't even reload websites anymore. Now, i surf with ease.
This is a proof of concept and a skeleton to start improving on, not a whole solution which is more about iptables in general. It's expected you know your way around linux shell and iptables already. Tc you don't have to touch, except for statistics.
Dns and icmp are handled at both prerouting and postrouting because i'm unsure if CTF affects them and the stats don't quite match, if you know better please comment. Also, tc shows stats stuck at zero for band 0 for unknown reasons, something to do with CTF?
Note that it's your own responsibility to make sure traffic in upper bands never saturates the connection, and thus starves the lower bands entirely. You've been warned...
Edit: this is for a connection which uses PPPOE to connect to isp, if you're using direct cable, just replace ppp0 with eth0.
Experimented with a TBF qdisc on eth0 while this on ppp0, but never got the performance quite right. Recommend just a plain pfifo qdisc at eth0, like "tc qdisc replace dev eth0 pfifo ; ifconfig eth0 txqueuelen NN", where NN is 1/10 seconds worth of 1500 byte packets, for example for a 10 Mbit connection, NN=800.
Code:
# Queue 1000 packets per band
ifconfig ppp0 set txqueuelen 1000
tc qdisc replace dev ppp0 root prio bands 5 priomap 4 2 1 3 3 4 4 4 0 0 0 0 2 2 2 2
# comment out if you don't want your existing table flushed
iptables -t mangle -F
# tos 16 minimize delay interactive -> band 0
# dns
iptables -t mangle -A OUTPUT -p udp --dport 53 -j TOS --set-tos 16
iptables -t mangle -A OUTPUT -p udp --dport 53 -j RETURN
# telnet ssh
iptables -t mangle -A PREROUTING -p tcp --dport 22:23 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp --dport 22:23 -j RETURN
# icmp
iptables -t mangle -A PREROUTING -p icmp -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p icmp -j RETURN
# tos 4 maximize reliability -> band 1
# preferred mac addresses
iptables -t mangle -A PREROUTING -m mac --mac-source 00:11:22:33:44:55 -j TOS --set-tos 4
iptables -t mangle -A PREROUTING -m mac --mac-source 00:11:22:33:44:55 -j RETURN
# tos 2 minimize monetary cost -> band 2
# everyone in our internal network
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -j TOS --set-tos 2
# tos 8 maximize throughput bulk -> band 3
# preferred bulk traffic
# all transfers from internal network larger than 1 MB are put into preferred bulk category
iptables -t mangle -A POSTROUTING -s 192.168.1.0/24 -p tcp -m connbytes --connbytes 1048576: --connbytes-dir both --connbytes-mode bytes -j TOS --set-tos 8
iptables -t mangle -A POSTROUTING -s 192.168.1.0/24 -p udp -m connbytes --connbytes 1048576: --connbytes-dir both --connbytes-mode bytes -j TOS --set-tos 8
# tos 0 normal -> band 4
# slowest bulk traffic here, will (hopefully) include default traffic from router itself; download master
### POSTROUTING
iptables -t mangle -A OUTPUT -p udp --dport 53 -j TOS --set-tos 16
iptables -t mangle -A PREROUTING -p tcp --dport 22:23 -j TOS --set-tos 16
iptables -t mangle -A POSTROUTING -p icmp -j TOS --set-tos 16
# check results with
# tc -s -d qdisc
# tc -s -d class show dev ppp0
# iptables -t mangle -nvL --line-numbers
Last edited: