Interesting that today I was working on a simple variation of sqm-scripts that uses act_ctinfo and nftables. It just creates a simple environment to save DSCP marks using act_ctinfo and restores them on egress and ingress. Assigning DSCPs is left to the user to perform locally on individual clients or using regular firewall4 rules and custom includes.
Both DSCPClassify and cake-qos-simple are more ambitious than this script, but less can be more.
From 2d4c2e688759fa52cafee10c65dc4beeedaa9f55 Mon Sep 17 00:00:00 2001
From: dave14305 <44532942+dave14305@users.noreply.github.com>
Date: Mon, 10 Jul 2023 20:14:46 -0400
Subject: [PATCH] Introduce ctinfo_cake.qos script
---
src/ctinfo_cake.qos | 68 ++++++++++++++++++++++++++++++++++++++++
src/ctinfo_cake.qos.help | 7 +++++
src/defaults.sh | 2 ++
src/functions.sh | 16 ++++++++++
4 files changed, 93 insertions(+)
create mode 100644 src/ctinfo_cake.qos
create mode 100644 src/ctinfo_cake.qos.help
diff --git a/src/ctinfo_cake.qos b/src/ctinfo_cake.qos
new file mode 100644
index 0000000..02b0c0a
--- /dev/null
+++ b/src/ctinfo_cake.qos
@@ -0,0 +1,68 @@
+# 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
+
+nft_setup() {
+ nft -f - <<EOF
+add table inet sqm_ctinfo_cake
+delete table inet sqm_ctinfo_cake
+add table inet sqm_ctinfo_cake
+add chain inet sqm_ctinfo_cake sqm_ctinfo_postrouting { type filter hook postrouting priority mangle + 1; policy accept; }
+add chain inet sqm_ctinfo_cake sqm_store_dscp
+add rule inet sqm_ctinfo_cake sqm_ctinfo_postrouting oifname $IFACE ct mark & 64 == 0 jump sqm_store_dscp
+add rule inet sqm_ctinfo_cake sqm_store_dscp ct mark set ip dscp
+add rule inet sqm_ctinfo_cake sqm_store_dscp ct mark set ip6 dscp
+add rule inet sqm_ctinfo_cake sqm_store_dscp ct mark set ct mark or 64 counter
+EOF
+}
+
+egress() {
+ SILENT=1 $TC qdisc del dev $IFACE root
+ $TC qdisc add dev $IFACE root $( get_stab_string ) cake \
+ bandwidth ${UPLINK}kbit $( get_cake_lla_string ) ${EGRESS_CAKE_OPTS} diffserv4 ${EQDISC_OPTS}
+ # restore saved DSCP on egress
+ $TC filter add dev $IFACE matchall action ctinfo dscp 63 64
+
+}
+
+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 $( get_stab_string ) cake \
+ bandwidth ${DOWNLINK}kbit $( get_cake_lla_string ) ${INGRESS_CAKE_OPTS} diffserv4 ${IQDISC_OPTS}
+
+ $IP link set dev $DEV up
+
+ # restore saved DSCP on ingress and
+ # redirect all IP packets arriving in $IFACE to ifb
+
+ $TC filter add dev $IFACE parent ffff: matchall action ctinfo dscp 63 64 \
+ mirred egress redirect dev $DEV
+}
+
+sqm_prepare_script() {
+ do_modules
+ verify_qdisc $QDISC "cake" || return 1
+ nft_setup
+}
diff --git a/src/ctinfo_cake.qos.help b/src/ctinfo_cake.qos.help
new file mode 100644
index 0000000..5f25ebc
--- /dev/null
+++ b/src/ctinfo_cake.qos.help
@@ -0,0 +1,7 @@
+This uses the cake qdisc to manage traffic flows and uses the act_ctinfo
+module to restore DSCP marks on ingress and egress traffic after an initial
+DSCP assignment process. DSCP can be assigned on individual clients or
+managed through the sqm host's nftables ruleset. CAKE is configured with
+diffserv4 to allow bulk, besteffort, video and voice tins for classification.
+This script requires that cake is selected as qdisc, and forces its usage.
+See: http://www.bufferbloat.net/projects/codel/wiki/Cake for more information
diff --git a/src/defaults.sh b/src/defaults.sh
index 6298266..cf70d5e 100644
--- a/src/defaults.sh
+++ b/src/defaults.sh
@@ -38,6 +38,8 @@
[ -z "$IP6TABLES_BINARY" ] && IP6TABLES_BINARY=$(command -v ip6tables)
[ -z "$IP6TABLES_BINARY" ] && IP6TABLES_BINARY=$(command -v ip6tables-nft)
[ -z "$IPTABLES_ARGS" ] && IPTABLES_ARGS="-w 1"
+[ -z "$NFT" ] && NFT=nft_wrapper
+[ -z "$NFT_BINARY" ] && NFT_BINARY=$(command -v nft)
# Try modprobe first, fall back to insmod
diff --git a/src/functions.sh b/src/functions.sh
index 21efa26..6461507 100644
--- a/src/functions.sh
+++ b/src/functions.sh
@@ -190,6 +190,22 @@ verify_iptables()
return $ret
}
+# wrapper to call nft to allow debug logging
+nft_wrapper(){
+ cmd_wrapper nft ${NFT_BINARY} "$@"
+}
+
+verify_nft(){
+ local ret
+ ret=0
+
+ if [ -z "$NFT_BINARY"]; then
+ sqm_error "No nft binary found, please install 'nftables-json' or 'nftables-nojson' to use this script"
+ ret=1
+ fi
+ return $ret
+}
+
# wrapper to call tc to allow debug logging
tc_wrapper(){
cmd_wrapper tc ${TC_BINARY} "$@"
--
2.34.1