If you're using a snapshot of master you can use sqm-scripts 1.4.0 (or newer) with cake and also install kmod-sched-ctinfo, kmod-sched-connmark, and kmod-sched-ipset (the latter is optional but I make use of it). I use a simple script based off of what @ldir originally posted:
#!/bin/sh
# Cero3 Shaper
# A cake shaper and AQM solution that allows several diffserv marking schemes
# for ethernet gateways
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# Copyright (C) 2012-5 Michael D. Taht, Toke Høiland-Jørgensen, Sebastian Moeller
#sm: TODO pass in the cake diffserv keyword
. ${SQM_LIB_DIR}/defaults.sh
QDISC=cake
# Default traffic classication is passed in INGRESS_CAKE_OPTS and EGRESS_CAKE_OPTS, defined in defaults.sh now
egress() {
SILENT=1 $TC qdisc del dev $IFACE root
$TC qdisc add dev $IFACE root handle cacf: $( get_stab_string ) cake \
bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} ${EQDISC_OPTS}
# put an action on the egress interface to set DSCP from the stored connmark.
# this seems counter intuitive but it ensures once the mark is set that all
# subsequent egress packets have the same stored DSCP avoiding iptables rules
# to mark every packet, ctinfo does it for us and then CAKE is happy using the
# DSCP
$TC filter add dev $IFACE protocol all prio 10 u32 match u32 0 0 action \
ctinfo dscp 0xfc000000 0x01000000
}
ingress() {
SILENT=1 $TC qdisc del dev $IFACE handle ffff: ingress
$TC qdisc add dev $IFACE handle ffff: ingress
SILENT=1 $TC qdisc del dev $DEV root
[ "$IGNORE_DSCP_INGRESS" -eq "1" ] && INGRESS_CAKE_OPTS="$INGRESS_CAKE_OPTS besteffort"
[ "$ZERO_DSCP_INGRESS" -eq "1" ] && INGRESS_CAKE_OPTS="$INGRESS_CAKE_OPTS wash"
$TC qdisc add dev $DEV root handle cace: $( get_stab_string ) cake \
bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} ${IQDISC_OPTS}
$IP link set dev $DEV up
# redirect all IP packets arriving in $IFACE to ifb0
# set DSCP from conntrack mark
$TC filter add dev $IFACE parent ffff: protocol all prio 10 u32 \
match u32 0 0 action \
ctinfo dscp 0xfc000000 0x01000000 \
mirred egress redirect dev $DEV
# Configure iptables chain to mark packets
ipt -t mangle -N QOS_MARK_${IFACE}
# Change DSCP of relevant hosts/packets
# and save the DSCP to the connmark using savedscp
#From sched_cake.c:
# /* Further pruned list of traffic classes for four-class system:
# *
# * Latency Sensitive (CS7, CS6, EF, VA, CS5, CS4)
# * Streaming Media (AF4x, AF3x, CS3, AF2x, TOS4, CS2, TOS1)
# * Best Effort (CS0, AF1x, TOS2, and those not specified)
# * Background Traffic (CS1)
# *
# * Total 4 traffic classes.
# */
#and for diffserv8:
# /* Pruned list of traffic classes for typical applications:
# *
# * Network Control (CS6, CS7)
# * Minimum Latency (EF, VA, CS5, CS4)
# * Interactive Shell (CS2, TOS1)
# * Low Latency Transactions (AF2x, TOS4)
# * Video Streaming (AF4x, AF3x, CS3)
# * Bog Standard (CS0 etc.)
# * High Throughput (AF1x, TOS2)
# * Background Traffic (CS1)
# *
# * Total 8 traffic classes.
# */
GAMING_CLASS=AF41
ipt -t mangle -A QOS_MARK_${IFACE} -m set --match-set gameset dst -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -m set --match-set bulkset dst -j DSCP --set-dscp-class CS1
ipt -t mangle -A QOS_MARK_${IFACE} -p tcp -s 192.168.1.3 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p udp -s 192.168.1.3 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p tcp -s 192.168.1.4 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p udp -s 192.168.1.4 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p tcp -s 192.168.1.166 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p udp -s 192.168.1.166 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p tcp -s 192.168.1.152 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -t mangle -A QOS_MARK_${IFACE} -p udp -s 192.168.1.152 -m multiport --dports 1024:65535 -j DSCP --set-dscp-class ${GAMING_CLASS}
ipt -A QOS_MARK_${IFACE} -t mangle -j CONNMARK --savedscp-mark 0xfc000000/0x01000000
# Send unmarked connections to the marking chain
# top 6 bits are DSCP, LSB is DSCP is valid flag
# ipt -t mangle -A PREROUTING -i $IFACE -m connmark --mark 0x00000000/0x01000000 -g QOS_MARK_${IFACE}
ipt -t mangle -A POSTROUTING -o $IFACE -m connmark --mark 0x00000000/0x01000000 -g QOS_MARK_${IFACE}
#you could just send every packet to the marking chain and update the stored DSCP for every packet
#which should work for dynamic type marking but at a cpu cost
}
sqm_prepare_script() {
do_modules
verify_qdisc $QDISC "cake" || return 1
}
I have limited upload bandwidth so I use cakes video tin rather than voice. The '--savedscp-mark' saves the DSCP marks we set to the connection and the 'ctinfo' action restores the DSCP value to the packets before cake takes them.
The patches for savedscp support weren't merged into 19.07, but I've been building my own images with it since the beginning of August and everything has been working perfectly for me. If you want a fancier script ldir has a good example here.
I use dnsmasq to populate two ipsets, but you need to use dnsmasq-full for that. One is for a couple of games that use a HTTPS connection for game traffic, the other is mainly to confine Windows/Xbox updates to the bulk tin.