Ultimate SQM settings: Layer_cake + DSCP marks (New Script!)

For now just run from terminal: /root/DSCP.sh

It doesn't seem to work.

root@OpenWrt:~# /root/DSCP.sh
: invalid option
Usage:  /bin/bash [GNU long option] [option] ...
        /bin/bash [GNU long option] [option] script-file ...
GNU long options:
        --debug
        --debugger
        --dump-po-strings
        --dump-strings
        --help
        --init-file
        --login
        --noediting
        --noprofile
        --norc
        --posix
        --pretty-print
        --rcfile
        --restricted
        --verbose
        --version
Shell options:
        -ilrsD or -c command or -O shopt_option         (invocation only)
        -abefhkmnptuvxBCHP or -o option

It seems that my main problem for now is that I cannot run the script for some reason.

How did you created that file DSCP.sh ?
use winscp to create the file

Yes, it's/was in my /root/ folder.
I followed your instruction and created the file again (with WinSCP), copied the content and ran chmod 755 /root/DSCP.sh. All of the sudden it seems to work... :slight_smile:

root@OpenWrt:~# chmod 755 /root/DSCP.sh
root@OpenWrt:~# /root/DSCP.sh
+ IPT=iptables
+ WANIF=pppoe-wan
+ tc qdisc add dev wlan0 root mq
Error: Exclusivity flag on, cannot modify.
+ ip link show+ grep veth0

+ ip link add type veth
+ ip link show
+ grep veth2
+ ip link add type veth
+ ip link set veth0 up
+ ip link set veth1 up
+ ip link set veth2 up
+ ip link set veth3 up
+ ip link set veth1 promisc on
+ brctl addif br-lan veth1
+ brctl addif br-guest veth3
+ ip rule del priority 100
RTNETLINK answers: No such file or directory
+ ip route flush table 100
+ ipset create streaming hash:ip
+ ipset create usrcdn hash:ip
+ ipset create bulk hash:ip
+ ipset create latsens hash:ip
+ ip route add default dev veth0 table 100
+ ip rule add iif pppoe-wan table 100 priority 100
+ ip route add 192.168.1.0/24 dev veth0 table 100
+ ip route add 192.168.55.0/24 dev veth2 table 100
+ ip rule add iif pppoe-wan table 100 priority 100
RTNETLINK answers: File exists
+ iptables -t mangle -N dscp_mark
+ iptables -t mangle -F dscp_mark
+ iptables -t mangle -L POSTROUTING -n
+ grep dscp_mark
+ iptables -t mangle -A POSTROUTING -j dscp_mark
+ iptmark -j DSCP --set-dscp 0
+ iptables -t mangle -A dscp_mark -j DSCP --set-dscp 0
+ iptmark -p udp -m hashlimit --hashlimit-name udp_high_prio --hashlimit-above 115/sec --hashlimit-burst 50 --hashlimit-mode srcip,srcport,dstip,dstport -j CONNMARK --set-mark 0x55 -m comment --comment 'connmark for udp'
+ iptables -t mangle -A dscp_mark -p udp -m hashlimit --hashlimit-name udp_high_prio --hashlimit-above 115/sec --hashlimit-burst 50 --hashlimit-mode srcip,srcport,dstip,dstport -j CONNMARK --set-mark 0x55 -m comment --comment 'connmark for udp'
iptables v1.8.3 (legacy): Couldn't load match `hashlimit':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.
+ iptmark -p udp -m connmark '!' --mark 0x55 -m multiport '!' --ports 22,25,53,67,68,123,143,161,162,514,5353,80,443,8080,60001 -m connbytes --connbytes 0:940 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class CS6 -m comment --comment 'small udp connection gets CS6'
+ iptables -t mangle -A dscp_mark -p udp -m connmark '!' --mark 0x55 -m multiport '!' --ports 22,25,53,67,68,123,143,161,162,514,5353,80,443,8080,60001 -m connbytes --connbytes 0:940 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class CS6 -m comment --comment 'small udp connection gets CS6'
+ iptmark -p udp -m connmark '!' --mark 0x55 -m multiport '!' --ports 22,25,53,67,68,123,143,161,162,514,5353,80,443,8080,60001 -m connbytes --connbytes 940:1500 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class AF41 -m comment --comment 'large udp connection gets AF41'
+ iptables -t mangle -A dscp_mark -p udp -m connmark '!' --mark 0x55 -m multiport '!' --ports 22,25,53,67,68,123,143,161,162,514,5353,80,443,8080,60001 -m connbytes --connbytes 940:1500 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class AF41 -m comment --comment 'large udp connection gets AF41'
+ iptmark -p icmp -j DSCP --set-dscp-class CS5 -m comment --comment ICMP-pings
+ iptables -t mangle -A dscp_mark -p icmp -j DSCP --set-dscp-class CS5 -m comment --comment ICMP-pings
+ iptmark -p udp -m multiport --port 53,5353,8888 -j DSCP --set-dscp-class CS5 -m comment --comment 'DNS udp'
+ iptables -t mangle -A dscp_mark -p udp -m multiport --port 53,5353,8888 -j DSCP --set-dscp-class CS5 -m comment --comment 'DNS udp'
+ iptmark -p tcp -m multiport --port 53,5353,8888 -j DSCP --set-dscp-class CS5 -m comment --comment 'DNS tcp'
+ iptables -t mangle -A dscp_mark -p tcp -m multiport --port 53,5353,8888 -j DSCP --set-dscp-class CS5 -m comment --comment 'DNS tcp'
+ iptmark -p udp -m multiport --port 123 -j DSCP --set-dscp-class CS6 -m comment --comment 'NTP udp'
+ iptables -t mangle -A dscp_mark -p udp -m multiport --port 123 -j DSCP --set-dscp-class CS6 -m comment --comment 'NTP udp'
+ iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctorigsrc 192.168.1.241 -m multiport '!' --ports 80,443,8080 -j DSCP --set-dscp-class CS6 -m comment --comment PS4
+ iptables -t mangle -A PREROUTING -p udp -m conntrack --ctorigsrc 192.168.1.241 -m multiport '!' --ports 80,443,8080 -j DSCP --set-dscp-class CS6 -m comment --comment PS4
+ iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctorigsrc 192.168.1.242 -m multiport '!' --ports 80,443,8080 -j DSCP --set-dscp-class CS6 -m comment --comment PS4
+ iptables -t mangle -A PREROUTING -p udp -m conntrack --ctorigsrc 192.168.1.242 -m multiport '!' --ports 80,443,8080 -j DSCP --set-dscp-class CS6 -m comment --comment PS4
+ iptmark '!' -p tcp -m set --match-set latsens src,dst -j DSCP --set-dscp-class CS6 -m comment --comment 'latency sensitive ipset'
+ iptables -t mangle -A dscp_mark '!' -p tcp -m set --match-set latsens src,dst -j DSCP --set-dscp-class CS6 -m comment --comment 'latency sensitive ipset'
+ iptmark -p tcp -m set --match-set latsens src,dst -j DSCP --set-dscp-class CS5 -m comment --comment 'latency sensitive ipset'
+ iptables -t mangle -A dscp_mark -p tcp -m set --match-set latsens src,dst -j DSCP --set-dscp-class CS5 -m comment --comment 'latency sensitive ipset'
+ iptmark -p tcp -m multiport --ports 80,443,8080 -j DSCP --set-dscp-class CS3 -m comment --comment 'Browsing at CS3'
+ iptables -t mangle -A dscp_mark -p tcp -m multiport --ports 80,443,8080 -j DSCP --set-dscp-class CS3 -m comment --comment 'Browsing at CS3'
+ iptmark -p tcp --tcp-flags ALL ACK -m length --length :128 -j DSCP --set-dscp-class CS3
+ iptables -t mangle -A dscp_mark -p tcp --tcp-flags ALL ACK -m length --length :128 -j DSCP --set-dscp-class CS3
+ iptmark -p tcp --tcp-flags ALL SYN -m length --length :666 -j DSCP --set-dscp-class CS3
+ iptables -t mangle -A dscp_mark -p tcp --tcp-flags ALL SYN -m length --length :666 -j DSCP --set-dscp-class CS3
+ iptmark -m dscp '!' --dscp 24 -m dscp '!' --dscp 18 -m dscp '!' --dscp 34 -m dscp '!' --dscp 40 -m dscp '!' --dscp 48 -m length --length 0:500 -j DSCP --set-dscp-class CS3
+ iptables -t mangle -A dscp_mark -m dscp '!' --dscp 24 -m dscp '!' --dscp 18 -m dscp '!' --dscp 34 -m dscp '!' --dscp 40 -m dscp '!' --dscp 48 -m length --length 0:500 -j DSCP --set-dscp-class CS3
+ iptmark -m dscp '!' --dscp 24 -m dscp '!' --dscp 18 -m dscp '!' --dscp 34 -m dscp '!' --dscp 40 -m dscp '!' --dscp 48 -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class CS3
+ iptables -t mangle -A dscp_mark -m dscp '!' --dscp 24 -m dscp '!' --dscp 18 -m dscp '!' --dscp 34 -m dscp '!' --dscp 40 -m dscp '!' --dscp 48 -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j DSCP --set-dscp-class CS3
+ iptmark -m set --match-set streaming src,dst -j DSCP --set-dscp-class AF41 -m comment --comment 'video audio stream ipset'
+ iptables -t mangle -A dscp_mark -m set --match-set streaming src,dst -j DSCP --set-dscp-class AF41 -m comment --comment 'video audio stream ipset'
+ iptmark -p tcp -m multiport --ports 1935,9982 -j DSCP --set-dscp-class AF41 -m comment --comment 'some iptv streaming service'
+ iptables -t mangle -A dscp_mark -p tcp -m multiport --ports 1935,9982 -j DSCP --set-dscp-class AF41 -m comment --comment 'some iptv streaming service'
+ iptmark -m set --match-set usrcdn src,dst -j DSCP --set-dscp-class AF21 -m comment --comment 'usrcdn ipset'
+ iptables -t mangle -A dscp_mark -m set --match-set usrcdn src,dst -j DSCP --set-dscp-class AF21 -m comment --comment 'usrcdn ipset'
+ iptmark -p tcp -m set --match-set bulk src,dst -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk traffic ipset'
+ iptables -t mangle -A dscp_mark -p tcp -m set --match-set bulk src,dst -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk traffic ipset'
+ iptmark -p udp -m set --match-set bulk src,dst -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk traffic ipset'
+ iptables -t mangle -A dscp_mark -p udp -m set --match-set bulk src,dst -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk traffic ipset'
+ iptmark -p tcp -m connbytes --connbytes 350000: --connbytes-dir both --connbytes-mode bytes -m dscp --dscp-class CS0 -j DSCP --set-dscp-class CS1 -m comment --comment 'Downgrade CS0 to CS1 for bulk tcp traffic'
+ iptables -t mangle -A dscp_mark -p tcp -m connbytes --connbytes 350000: --connbytes-dir both --connbytes-mode bytes -m dscp --dscp-class CS0 -j DSCP --set-dscp-class CS1 -m comment --comment 'Downgrade CS0 to CS1 for bulk tcp traffic'
+ iptmark -p tcp -m connbytes --connbytes 350000: --connbytes-dir both --connbytes-mode bytes -m dscp --dscp-class CS3 -j DSCP --set-dscp-class CS1 -m comment --comment 'Downgrade CS3 to CS1 for bulk tcp traffic'
+ iptables -t mangle -A dscp_mark -p tcp -m connbytes --connbytes 350000: --connbytes-dir both --connbytes-mode bytes -m dscp --dscp-class CS3 -j DSCP --set-dscp-class CS1 -m comment --comment 'Downgrade CS3 to CS1 for bulk tcp traffic'
+ iptmark -p udp -m multiport --port 60001 -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk torrent port UDP'
+ iptables -t mangle -A dscp_mark -p udp -m multiport --port 60001 -j DSCP --set-dscp-class CS1 -m comment --comment 'bulk torrent port UDP'
root@OpenWrt:~# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1024
    link/ether 62:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1024
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
6: ifb0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 32
    link/ether aa:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
7: ifb1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 32
    link/ether e2:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
8: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 5a:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
11: teql0: <NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 100
    link/void
12: br-guest: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
13: eth0.3@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-guest state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
14: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
15: eth0.1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
16: eth1.2@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 62:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
17: pppoe-wan: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc cake state UNKNOWN mode DEFAULT group default qlen 3
    link/ppp
18: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
19: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-lan state UP mode DEFAULT group default qlen 1000
    link/ether 60:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
21: wlan1-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-guest state UP mode DEFAULT group default qlen 1000
    link/ether 62:38:e0:b6:72:18 brd ff:ff:ff:ff:ff:ff
22: wlan0-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br-guest state UP mode DEFAULT group default qlen 1000
    link/ether 62:3xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
37: ifb4pppoe-wan: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc cake state UNKNOWN mode DEFAULT group default qlen 32
    link/ether 72:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
39: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN mode DEFAULT group default qlen 100
    link/none
40: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether fe:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
41: veth1@veth0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-lan state UP mode DEFAULT group default qlen 1000
    link/ether f6:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
42: veth2@veth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 3e:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
43: veth3@veth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-guest state UP mode DEFAULT group default qlen 1000
    link/ether b6:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
1 Like

Now veth is there.
you can do other things.
i think you created the file using windows and you transferred to your router

1 Like

Yes, I've created my first DSCP.sh file with my windows machine.
Now I'm trying to setup the correct SQM interfaces and test it. Thanks for being so patient with me!

1 Like

windows is using another file encoding(UTF-8) which is not compatible with linux shell.

You are welcome, let us know how it will going!

So far it's looking good but I'm not sure if I've configured the SQM interfaces correctly.

Here is my current config:

config queue 'eth1'
	option ingress_ecn 'ECN'
	option egress_ecn 'ECN'
	option interface 'pppoe-wan'
	option debug_logging '0'
	option verbosity '5'
	option qdisc 'cake'
	option script 'layer_cake.qos'
	option qdisc_advanced '1'
	option squash_dscp '0'
	option squash_ingress '0'
	option linklayer 'ethernet'
	option overhead '34'
	option linklayer_advanced '1'
	option tcMTU '2047'
	option tcTSIZE '128'
	option tcMPU '64'
	option linklayer_adaptation_mechanism 'default'
	option enabled '1'
	option upload '35375'
	option download '102150'
	option qdisc_really_really_advanced '0'

config queue
	option debug_logging '0'
	option verbosity '5'
	option ingress_ecn 'ECN'
	option tcMTU '2047'
	option tcTSIZE '128'
	option linklayer_adaptation_mechanism 'default'
	option interface 'veth0'
	option download '0'
	option upload '97000'
	option qdisc 'cake'
	option script 'layer_cake.qos'
	option qdisc_advanced '1'
	option squash_dscp '0'
	option squash_ingress '0'
	option egress_ecn 'ECN'
	option qdisc_really_really_advanced '0'
	option linklayer 'ethernet'
	option overhead '34'
	option linklayer_advanced '1'
	option tcMPU '64'
	option enabled '1'

config queue
	option debug_logging '0'
	option verbosity '5'
	option ingress_ecn 'ECN'
	option tcMTU '2047'
	option tcTSIZE '128'
	option linklayer_adaptation_mechanism 'default'
	option interface 'veth2'
	option download '0'
	option upload '97000'
	option qdisc 'cake'
	option script 'layer_cake.qos'
	option qdisc_advanced '1'
	option squash_dscp '0'
	option squash_ingress '0'
	option egress_ecn 'ECN'
	option qdisc_really_really_advanced '0'
	option linklayer 'ethernet'
	option overhead '34'
	option linklayer_advanced '1'
	option tcMPU '64'
	option enabled '1'

I always had the following options in my SQM config (pppoe-wan) but I don't know if I can still use the with the new vethx config (those 2 options always worked great on my setup when it comes down to share the bandwith):

option iqdisc_opts 'nat dual-dsthost ingress'
option eqdisc_opts 'nat dual-srchost'
1 Like

that looks more or less good. my own preference is to give guests considerably less than the full download but that's up to you obviously. the less they have the less they can perturb the main LAN.

Currently I do have some IOT devices in my Guest Network but I'm planing to create 1-2 more vlans just for my personal IOT devices and also limit the real guest network bandwith wise.
Btw, it was crucial to add veth2 to my guest interface, otherwise guest clients don't have internet connection.

It would be great if one of you SQM gurus could help me a little bit with my SQM settings. My plan was to limit bittorrent downloads so my Latency remains low and stable in multiplayer games while download torrents. With the current config my latency is still not stable while running qBittorent on one of my Windows machines.

Thanks for your help so far! :slight_smile:

hisham uses port 60001 as a stand-in here for torrent ports. Either set your torrent thing to use this port, or change this line in the DSCP tagger script to use the port your torrenter actually uses. Voila!

also my understanding is that the bulk data is typically transferred over TCP not UDP, so you might need a similar rule like this for TCP port xxxx which you set your torrent client to use.

1 Like

IPV4 VS IPV6, what's the major benefit if we use it from the script above?

well if you have ipv6 you should include a bunch of ipv6 rules doing the same stuff...

I've rebooted my router this morning and completly lost access to it...
Then I performed a reset and configured everything once again but after I added veth2 to the Guest Interface and veth0 to the Lan Interface + reboot I lost access to my router again. Pings and GUI access are working for a couple of seconds but then I loose every kind of access.

When there is no usage of my network later on I'll try to figure out whats wrong but currently I have no real idea bu it must be a firewall related problem.

Enable forwarding for both wan, lan and guest, also in general settings.
don't add the /root/DSCP.sh to startup, do it later when everything is ok

It's uses udp at the same time.

I thought it is configurable whether torrent apps use UDP or TCP? Sure their default protocol ĀµTP is based on UDP, but since UDP is relatively often disabled or rate-limited, I would assume that client and server can use both, so torrent rules probably deserve to exist for both UDP and TCP, no?

Hmm, by default all of bittorrent clients is using tcp and udp, mostly they prefer UDP.
it's also depend on peer or seeder if they use UDP only?, then you can't download from them if you have
TCP only?

It's preferable.

I'll try this tomorrow. Btw, is there no way to make SQM aware of DSCP at pppoe-wan @ingress without the veth method?

My qBittorent is set to TCP and uTP. I think thats default...

the other method requires nftables

1 Like