Hello all,
First, I have built a custom script for my main routers to serve our home for years now. First was a tomato based firmware and the current one is Padavan in which I made a script based on my tomato config. It works well at achieving my goal. 50mbit 20mbit up with my QoS script uses 70-80% CPU on my cheap asus router. Now our plan is going to be upgraded in a few months from 50mbit to 100/40 and concerns about CPU of router is imminent and need to buy a new router.
So got TP-Link C2 AC900 v3 and hooked up OpenWRT and installed SQM. However that does not achieve my goal. Have a on-demand bandwidth when I want to stream on Youtube or Facebook. So I updated my QoS script for OpenWRT with IFB and IPTABLES.
Packages:
opkg install tc kmod-sched-core kmod-sched kmod-ifb kmod-ipt-ipopt iptables-mod-ipopt
My QoS Script (set to run during firewall change event)
# Updated: 12062019t0749
# OpenWRT Custom QoS Script
# Reference: https://openwrt.org/docs/guide-user/network/traffic-shaping/packet.scheduler
# Based on: https://wiki.gentoo.org/wiki/Traffic_shaping
# Migrating code to be compatible with OpenWRT
### ============================= ###
### ===== IFB SCRIPT SIMPLE ===== ###
### ============================= ###
### Features: ###
### - 2 Class Ingress ###
### - Improve performance ###
### ============================= ###
############### Edit parameters here! ####################
# Download and upload speed in KiloBITS. Speedtest speed should be provided as script will calculate overhead for you.
# Plan: Globe at Home 2499 @ 50mbps down / 20mbps up
DOWNLOAD=50400
UPLOAD=20200
################# DO NOT EDIT BELOW! ######################
ext=$(uci get network.wan.ifname) # Get active WAN interface
ext_ingress=ifb0
# ext_mtu=$(cat /sys/class/net/$ext/mtu) # Get MTU of WAN
logger 'Initializing...'
logger 'Clearing queue disciplines and iptables.. Please wait.'
sed -n 's/ *\(.*\):.*/\1/p' /proc/net/dev | while read INTERFACE; do
tc qdisc del dev $INTERFACE root >&- 2>&-
tc qdisc del dev $INTERFACE ingress >&- 2>&-
done
iptables -t mangle -F
iptables -t mangle -X
# Create ingress on external interface
logger 'Creating ingress interface'
tc qdisc add dev $ext handle ffff: ingress
ip link set ifb0 up
tc filter add dev $ext parent ffff: protocol all u32 match u32 0 0 action mirred egress redirect dev ifb0
logger 'Setting parameters'
DOWNLOAD=$((DOWNLOAD*96/100))
UPLOAD=$((UPLOAD*92/100))
logger 'Setting QoS with Download of ${DOWNLOAD}kbit and Upload of ${UPLOAD}kbit'
# DOWNLOAD QOS
logger 'Setting up download qos..'
tc qdisc add dev ifb0 root handle 1: htb default 11
tc class add dev ifb0 parent 1: classid 1:1 htb rate ${DOWNLOAD}kbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate $((DOWNLOAD*4/10))kbit ceil ${DOWNLOAD}kbit
tc class add dev ifb0 parent 1:1 classid 1:11 htb rate $((DOWNLOAD*6/10))kbit ceil ${DOWNLOAD}kbit
tc qdisc add dev ifb0 parent 1:10 handle 10: fq_codel ecn
tc qdisc add dev ifb0 parent 1:11 handle 11: fq_codel ecn
# Filter HTTPS
tc filter add dev ifb0 parent 1: protocol ip u32 match ip protocol 6 0xff match ip sport 443 0xffff flowid 1:10
## UPLOAD QOS
logger 'Setting up upload qos..'
UMAX=$((UPLOAD-600))
tc qdisc add dev $ext root handle 1: htb default 12
tc class add dev $ext parent 1: classid 1:1 htb rate ${UPLOAD}kbit
tc class add dev $ext parent 1:1 classid 1:10 htb rate 600kbit
tc class add dev $ext parent 1:1 classid 1:11 htb rate 12400kbit ceil ${UMAX}kbit
tc class add dev $ext parent 1:1 classid 1:12 htb rate $((UMAX-12500))kbit ceil ${UMAX}kbit
tc qdisc add dev $ext parent 1:10 handle 10: fq_codel quantum 300 noecn
tc qdisc add dev $ext parent 1:11 handle 11: fq_codel quantum 300 noecn
tc qdisc add dev $ext parent 1:12 handle 12: fq_codel quantum 300 noecn
tc filter add dev $ext parent 1: protocol ip u32 match ip protocol 1 0xff flowid 1:10 # ICMP
tc filter add dev $ext parent 1: protocol ip u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u16 0x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid 1:10 # ACK
tc filter add dev $ext parent 1: protocol ip u32 match ip tos 0xE0 0xff match ip protocol 11 0xff flowid 1:10 # TOS VOIP
tc filter add dev $ext parent 1: protocol ip u32 match ip tos 0xB8 0xff match ip protocol 11 0xff flowid 1:10 # TOS VOIP
tc filter add dev $ext parent 1: protocol ip handle 1 fw flowid 1:10
tc filter add dev $ext parent 1: protocol ip handle 2 fw flowid 1:11
tc filter add dev $ext parent 1: protocol ip handle 3 fw flowid 1:12
## Routing packets ##
logger 'Setting ip tables'
iptables -t mangle -N upload_chain
iptables -t mangle -A POSTROUTING -o $ext -j upload_chain
iptables -t mangle -A upload_chain -p udp -m multiport --dport 1024:65535 -m length --length :256 -j MARK --set-mark 1
iptables -t mangle -A upload_chain -p tcp -m multiport --dport 1024:65535 -m length --length :60 -j MARK --set-mark 1
# IP Match
iptables -t mangle -A upload_chain -s 192.168.1.110 -p tcp --dport 1935 -j MARK --set-mark 2
# TOS
iptables -t mangle -A upload_chain -m tos --tos Minimize-Delay -j MARK --set-mark 1
iptables -t mangle -A upload_chain -m tos --tos Minimize-Cost -j MARK --set-mark 2
iptables -t mangle -A upload_chain -m tos --tos Maximize-Throughput -j MARK --set-mark 3
exit 0
# Troubleshoot:
# iptables -t mangle -vnL
# tc qdisc show dev ifb0
# tc qdisc show dev eth2.2
My problem lies in IFB interface. I created 2 class 1 being specifically for HTTPS which makes sure services such as Youtube or Netflix won't experience problem while someone downloads. When someone downloads on say Steam or even P2P then YouTube or Netflix will just be at 8mbit at most which is I believe my ISP-side of things.
Therefore my goal is:
HTTPS(WWW, Youtube, Netflix, etc) uses class id 1:10 with 40% guaranteed BW at full capacity.
then rest on 60% guaranteed BW. with class id 1:11 being default.
No drops on ICMP when on full load while maintaining 40% CPU
I am at wits end. Any suggestions will be of great help.
Additional Info:
Internet type: GPON
Download: 50mbps
Upload: 20mbps
Edit: Forgot to add openwrt build: OpenWrt SNAPSHOT r10263-bc47285cb3
Router: TP-LINK C2 AC900 V3