Instructions how to create/copy/configure/run dlakelan Gamer QoS script (or any script)

Perfect, it looks like it works. I will now tag the current version as 1.0.0 and leave it for people to try for a while.

2 Likes

@dlakelan
i m interested in the script...

about to test it

you need to have an access point plugged into your ethernet, rather than using the built-in wifi.

i figured it out

i got an error

This script prioritizes the UDP packets from / to a set of gaming
machines into a real-time HFSC queue with guaranteed total bandwidth

Based on your settings:

Game upload guarantee = 3700 kbps
Game download guarantee = 3700 kbps

Download direction only works if you install this on a *wired* router
and there is a separate AP wired into your network, because otherwise
there are multiple parallel queues for traffic to leave your router
heading to the LAN.

Based on your link total bandwidth, the **minimum** amount of jitter
you should expect in your network is about:

UP = 1 ms

DOWN = 1 ms

In order to get lower minimum jitter you must upgrade the speed of
your link, no queuing system can help.

Please note for your display rate that:

at 30Hz, one on screen frame lasts:   33.3 ms
at 60Hz, one on screen frame lasts:   16.6 ms
at 144Hz, one on screen frame lasts:   6.9 ms

This means the typical gamer is sensitive to as little as on the order
of 5ms of jitter. To get 5ms minimum jitter you should have bandwidth
in each direction of at least:

7200 kbps

The queue system can ONLY control bandwidth and jitter in the link
between your router and the VERY FIRST device in the ISP
network. Typically you will have 5 to 10 devices between your router
and your gaming server, any of those can have variable delay and ruin
your gaming, and there is NOTHING that your router can do about it.

Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
adding fq_codel qdisc for non-game traffic
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth0"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
adding fq_codel qdisc for non-game traffic
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"
Cannot find device "veth1"

We are going to add classification rules via iptables to the
FORWARD chain. You should actually read and ensure that these
rules make sense in your firewall before running this script.

why did it say cannot find device veth and veth0?

i did a fresh reset and did it...

I installed kmod-veth too...

Do i need to do the ip link set veth0 up?

or is it i just change veth0 and veth1 to pppoe-wan and br-lan?

it's just set up for veth out of the box because that's how I was testing it, you need to replace veth0 and veth1 with the names of your real interfaces.

i did that and checked...

DSCP showed....

sqm didnt configure on its own? i need to configure myself?

this script replaces sqm, you need to turn off sqm

there are a number of packages you need to install

turn off sqm?

i had it not configured when i did it... just the way u get when u install it

i installed these
kmod-netem kmod-ipt-ipopt kmod-nf-nathelper-extra kmod-sched kmod-sched-cake ip-full ipset iptables-mod-conntrack-extra iptables-mod-extra iptables-mod-ipopt iptables-mod-nat-extra

@dlakelan for some reason i think these lines are not working for me

tc qdisc del dev "$DEV" root > /dev/null 2>&1

case $LINKTYPE in
    "atm")
	tc qdisc replace dev "$DEV" handle 1: root stab mtu 2047 tsize 512 mpu 68 overhead ${OH} linklayer atm hfsc default 13
	;;
    "DOCSIS")
	tc qdisc replace dev $DEV stab overhead 25 linklayer ethernet handle 1: root hfsc default 13
	;;
    *)
	tc qdisc replace dev $DEV stab overhead 40 linklayer ethernet handle 1: root hfsc default 13
	;;
esac
     

DUR=$((5*1500*8/RATE))
if [ $DUR -lt 25 ]; then
    DUR=25
fi

# if we're on the LAN side, create a queue just for traffic from the
# router, like LUCI and DNS lookups
if [ $DIR = "lan" ]; then
    tc class add dev "$DEV" parent 1: classid 1:2 hfsc ls m1 50000kbit d "${DUR}ms" m2 10000kbit
fi


#limit the link overall:
tc class add dev "$DEV" parent 1: classid 1:1 hfsc ls m2 "${RATE}kbit" ul m2 "${RATE}kbit"


# high prio realtime class
tc class add dev "$DEV" parent 1:1 classid 1:11 hfsc rt m1 "$((RATE*97/100))kbit" d "${DUR}ms" m2 "${gamerate}kbit"

# fast non-realtime
tc class add dev "$DEV" parent 1:1 classid 1:12 hfsc ls m1 "$((RATE*70/100))kbit" d "${DUR}ms" m2 "$((RATE*30/100))kbit"

# normal
tc class add dev "$DEV" parent 1:1 classid 1:13 hfsc ls m1 "$((RATE*20/100))kbit" d "${DUR}ms" m2 "$((RATE*45/100))kbit"

# low prio
tc class add dev "$DEV" parent 1:1 classid 1:14 hfsc ls m1 "$((RATE*7/100))kbit" d "${DUR}ms" m2 "$((RATE*15/100))kbit"

# bulk
tc class add dev "$DEV" parent 1:1 classid 1:15 hfsc ls m1 "$((RATE*3/100))kbit" d "${DUR}ms" m2 "$((RATE*10/100))kbit"



## set this to "drr" or "qfq" to differentiate between different game
## packets, or use "pfifo" to treat all game packets equally

## games often use a 1/64 s = 15.6ms tick rate +- if we're getting so
## many packets that it takes that long to drain at full RATE, we're
## in trouble, because then everything lags by a full tick... so we
## set our RED minimum to start dropping at 9ms of packets at full
## line rate, and then drop 100% by 3x that much, it's better to drop
## packets for a little while than play a whole game lagged by a full
## tick

REDMIN=$((RATE*MAXDEL/3/8)) 

REDMAX=$((RATE * MAXDEL/8)) 

# for fq_codel
INTVL=$((100+2*1500*8/RATE))
TARG=$((540*8/RATE+4))



case $useqdisc in
    "drr")
	tc qdisc add dev "$DEV" parent 1:11 handle 2:0 drr
	tc class add dev "$DEV" parent 2:0 classid 2:1 drr quantum 8000
	tc qdisc add dev "$DEV" parent 2:1 handle 10: red limit 150000 min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	tc class add dev "$DEV" parent 2:0 classid 2:2 drr quantum 4000
	tc qdisc add dev "$DEV" parent 2:2 handle 20: red limit 150000 min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	tc class add dev "$DEV" parent 2:0 classid 2:3 drr quantum 1000
	tc qdisc add dev "$DEV" parent 2:3 handle 30: red limit 150000  min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	## with this send high priority game packets to 10:, medium to 20:, normal to 30:
	## games will not starve but be given relative importance based on the quantum parameter
    ;;

    "qfq")
	tc qdisc add dev "$DEV" parent 1:11 handle 2:0 qfq
	tc class add dev "$DEV" parent 2:0 classid 2:1 qfq weight 8000
	tc qdisc add dev "$DEV" parent 2:1 handle 10: red limit 150000  min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	tc class add dev "$DEV" parent 2:0 classid 2:2 qfq weight 4000
	tc qdisc add dev "$DEV" parent 2:2 handle 20: red limit 150000 min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	tc class add dev "$DEV" parent 2:0 classid 2:3 qfq weight 1000
	tc qdisc add dev "$DEV" parent 2:3 handle 30: red limit 150000  min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit probability 1.0
	## with this send high priority game packets to 10:, medium to 20:, normal to 30:
	## games will not starve but be given relative importance based on the weight parameter

    ;;

    "pfifo")
	tc qdisc add dev "$DEV" parent 1:11 handle 10: pfifo limit $((PFIFOMIN+MAXDEL*RATE/8/PACKETSIZE))
	;;
    "red")
	tc qdisc add dev "$DEV" parent 1:11 handle 10: red limit 150000 min $REDMIN max $REDMAX avpkt 500 bandwidth ${RATE}kbit  probability 1.0
	## send game packets to 10:, they're all treated the same
	;;
    "fq_codel")
	tc qdisc add dev "$DEV" parent "1:11" fq_codel memory_limit $((RATE*200/8)) interval "${INTVL}ms" target "${TARG}ms" quantum $((MTU * 2))
	;;
    "netem")
	tc qdisc add dev "$DEV" parent 1:11 handle 10: netem limit $((4+9*RATE/8/500)) delay "${netemdelayms}ms" "${netemjitterms}ms" distribution "$netemdist"
	;;


esac


echo "adding fq_codel qdisc for non-game traffic"
for i in 12 13 14 15; do 
    tc qdisc add dev "$DEV" parent "1:$i" fq_codel memory_limit $((RATE*200/8)) interval "${INTVL}ms" target "${TARG}ms" quantum $((MTU * 2))
done


}


setqdisc $WAN $UPRATE $GAMEUP $gameqdisc wan

## uncomment this to do the download direction via output of LAN
setqdisc $LAN $DOWNRATE $GAMEDOWN $gameqdisc lan

it seems like the tc command is not working for me? any files i m missing for it?

you'll need to install packages related to hashlimit

after that, can you show any errors you get from running it?

I had no bug except for the tc -s qdisc portion... showing no sign of sqm set up

I tried going back to 19.07.6 to see it works, it didnt i went back to 19.07.7 again still didnt work, now i m seeing more problem, i cant run wifi on lan without bridge now...+ now wan stopped working... this is starting to give me headache

another error now

root@OpenWrt:/etc# ls
SimpleHFSCgamerscript.sh  hotplug.d                 profile
TZ                        hotplug.json              protocols
banner                    init.d                    rc.button
banner.failsafe           inittab                   rc.common
board.d                   iproute2                  rc.d
board.json                localtime                 rc.local
config                    luci-uploads              resolv.conf
crontabs                  modules-boot.d            services
device_info               modules.d                 shadow
diag.sh                   mtab                      shadow-
dnsmasq.conf              openwrt_release           shells
dropbear                  openwrt_version           sqm
dscptag.sh                opkg                      sysctl.conf
ethers                    opkg.conf                 sysctl.d
firewall.user             os-release                sysupgrade.conf
fstab                     passwd                    uci-defaults
group                     passwd-                   urandom.seed
hosts                     ppp
hotplug-preinit.json      preinit
root@OpenWrt:/etc# ./SimpleHFSCgamerscript.sh
-ash: ./SimpleHFSCgamerscript.sh: not found
root@OpenWrt:/etc#

i set the permission to 755 yet still that error

Gonna restore the recovery file completely tomorrow and try again... i think i messed up something

1 Like
This script prioritizes the UDP packets from / to a set of gaming
machines into a real-time HFSC queue with guaranteed total bandwidth

Based on your settings:

Game upload guarantee = 3700 kbps
Game download guarantee = 3700 kbps

Download direction only works if you install this on a *wired* router
and there is a separate AP wired into your network, because otherwise
there are multiple parallel queues for traffic to leave your router
heading to the LAN.

Based on your link total bandwidth, the **minimum** amount of jitter
you should expect in your network is about:

UP = 1 ms

DOWN = 1 ms

In order to get lower minimum jitter you must upgrade the speed of
your link, no queuing system can help.

Please note for your display rate that:

at 30Hz, one on screen frame lasts:   33.3 ms
at 60Hz, one on screen frame lasts:   16.6 ms
at 144Hz, one on screen frame lasts:   6.9 ms

This means the typical gamer is sensitive to as little as on the order
of 5ms of jitter. To get 5ms minimum jitter you should have bandwidth
in each direction of at least:

7200 kbps

The queue system can ONLY control bandwidth and jitter in the link
between your router and the VERY FIRST device in the ISP
network. Typically you will have 5 to 10 devices between your router
and your gaming server, any of those can have variable delay and ruin
your gaming, and there is NOTHING that your router can do about it.

adding fq_codel qdisc for non-game traffic
adding fq_codel qdisc for non-game traffic

We are going to add classification rules via iptables to the
FORWARD chain. You should actually read and ensure that these
rules make sense in your firewall before running this script.

Continue? (type y or n and then RETURN/ENTER)
Y
Check the rules and come back when you're ready.
DONE!
qdisc noqueue 0: dev lo root refcnt 2
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc fq_codel 0: dev eth0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 4Mb ecn
 Sent 1598405 bytes 10503 pkt (dropped 0, overlimits 0 requeues 3)
 backlog 0b 0p requeues 3
  maxpacket 118 drop_overlimit 0 new_flow_count 2 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc hfsc 1: dev br-lan root refcnt 2 default 13
 Sent 1450929 bytes 1059 pkt (dropped 4, overlimits 2015 requeues 0)
 backlog 0b 0p requeues 0
qdisc fq_codel 800b: dev br-lan parent 1:13 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 1450739 bytes 1058 pkt (dropped 4, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 1530 drop_overlimit 0 new_flow_count 20 ecn_mark 0
  new_flows_len 1 old_flows_len 2
qdisc fq_codel 800d: dev br-lan parent 1:15 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc netem 10: dev br-lan parent 1:11 limit 53 delay 1.0ms  7.0ms
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc fq_codel 800a: dev br-lan parent 1:12 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc fq_codel 800c: dev br-lan parent 1:14 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc noqueue 0: dev eth0.1 root refcnt 2
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc noqueue 0: dev eth0.2 root refcnt 2
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc hfsc 1: dev pppoe-wan root refcnt 2 default 13
 Sent 39265 bytes 319 pkt (dropped 0, overlimits 2 requeues 0)
 backlog 0b 0p requeues 0
qdisc fq_codel 8007: dev pppoe-wan parent 1:13 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 39265 bytes 319 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 1577 drop_overlimit 0 new_flow_count 14 ecn_mark 0
  new_flows_len 0 old_flows_len 1
qdisc fq_codel 8009: dev pppoe-wan parent 1:15 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc netem 10: dev pppoe-wan parent 1:11 limit 53 delay 1.0ms  7.0ms
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc fq_codel 8006: dev pppoe-wan parent 1:12 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc fq_codel 8008: dev pppoe-wan parent 1:14 limit 10240p flows 1024 quantum 3000 target 4.0ms interval 101.0ms memory_limit 550000b ecn
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  maxpacket 0 drop_overlimit 0 new_flow_count 0 ecn_mark 0
  new_flows_len 0 old_flows_len 0
qdisc noqueue 0: dev wlan1 root refcnt 2
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
qdisc noqueue 0: dev wlan0 root refcnt 2
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0

the sqm doesnt configure on its own...
after the execution of the script

root@OpenWrt:~# uci show sqm
sqm.eth1=queue
sqm.eth1.enabled='0'
sqm.eth1.interface='eth1'
sqm.eth1.download='85000'
sqm.eth1.upload='10000'
sqm.eth1.qdisc='fq_codel'
sqm.eth1.script='simple.qos'
sqm.eth1.qdisc_advanced='0'
sqm.eth1.ingress_ecn='ECN'
sqm.eth1.egress_ecn='ECN'
sqm.eth1.qdisc_really_really_advanced='0'
sqm.eth1.itarget='auto'
sqm.eth1.etarget='auto'
sqm.eth1.linklayer='none'

But keep in mind, that hash limit seems to employ a harsh policer, so make sure no interactive latency sensitive traffic comes in contact with such rules... These are fine for bulk transfers and stuff, but there is a reason for employing a real AQM for interactive traffic :wink:

You can use tc -s qdisc to see whether SQM is still running.
On the shell use SQM_DEBUG=1 SQM_VERBOSITY_MAX=8 /etc/init.d/sqm start or SQM_DEBUG=1 SQM_VERBOSITY_MAX=8 /etc/init.d/sqm stop to manually enable/disable sqm with extended verbodity; can be handy for testing

i think u misunderstood...

case $LINKTYPE in
    "atm")
	tc qdisc replace dev "$DEV" handle 1: root stab mtu 2047 tsize 512 mpu 68 overhead ${OH} linklayer atm hfsc default 13
	;;
    "DOCSIS")
	tc qdisc replace dev $DEV stab overhead 25 linklayer ethernet handle 1: root hfsc default 13
	;;
    *)
	tc qdisc replace dev $DEV stab overhead 40 linklayer ethernet handle 1: root hfsc default 13
	;;
esac

i saw that in the .sh file... isnt that suppose to create a set of rules for shaper on sqm like the way we do from openwrt router web?

if that creates the sqm rules then mine is not working i guess?

Ah, @dlakelan's scrips are full replacements for SQM, I just wanted to document how to check that SQM is not running, and in case it is, how to disable it...

my bad sorry, seems the script doesnt require manual setup of sqm like the usual way... i didnt know it works on its own...
thanks for making me realize that @moeller0
i feel like an idiot now....

@dlakelan please include that on the instruction too... it's a bit confusing

I'm using it for my ack decimation strategy. Since most acks are highly redundant and the policing is above hundreds a second it seems to be ok. So far testing seemed to be ok.

Yes, as expected you use the available tools quite clever and appropriately, my comment was more directed at the genera audience that might think, why not use hash limits for everything....

That said, I am not a big fan of ACK decimation, but then my link is reasonably well balanced (shaped to 95/36) and not really bursty, so I am in a luxury position in regards to ACK-filtering; unlike many users of your scripts.

I don't understand why we would ever want to send more than about 300 acks a second. They just seem hugely wasteful.