Using DSCP for QoS

Here is a solution using ifb and a combination of tc and iptables.
Logic is almost the same.

egress side: iptables only.
Classify traffic on egress.
Set connmark.
Restore connmark to packet marks.
Set dscp flags on egress packets..

firewall script:
(Not all chains are used in the sqm part, but i use them for other things)

###################################################################
###  Create Custom Chains (Mangle)
###################################################################

$IPT -t mangle -F

### Prerouting
$IPT -t mangle -N zone_lan_prerouting
$IPT -t mangle -N zone_isolated_prerouting
$IPT -t mangle -N zone_wan_prerouting

$IPT -t mangle -A PREROUTING -i br-lan -j zone_lan_prerouting
$IPT -t mangle -A PREROUTING -i br-isolated -j zone_isolated_prerouting
$IPT -t mangle -A PREROUTING -i eth1 -j zone_wan_prerouting

### Forward
$IPT -t mangle -N zone_lan_forward
$IPT -t mangle -N zone_isolated_forward

$IPT -t mangle -A FORWARD -i br-lan -j zone_lan_forward
$IPT -t mangle -A FORWARD -i br-isolated -j zone_isolated_forward
###################################################################
### Make use of Cake's DiffServ4 Implementation
### by using dscp flags
###################################################################

### Setup some custom chains
$IPT -t mangle -N sqm
$IPT -t mangle -N sqm_mark_cs1
$IPT -t mangle -N sqm_mark_cs3
$IPT -t mangle -N sqm_mark_cs7
$IPT -t mangle -N sqm_set_dscp

### Since we dont know if lan users are messing around with dscp flags
### default all packets to cs0 (BE) and override later on
$IPT -t mangle -I zone_lan_prerouting -j DSCP --set-dscp-class CS0 -m comment --comment "Set DSCP CS0 as default"
$IPT -t mangle -I zone_isolated_prerouting -j DSCP --set-dscp-class CS0 -m comment --comment "Set DSCP CS0 as default"

### Only try to match traffic thats is going to be forwarded to internet
$IPT -t mangle -A zone_lan_forward -o eth1 -j sqm
$IPT -t mangle -A zone_lan_forward -o eth1 -j sqm_set_dscp
$IPT -t mangle -A zone_isolated_forward -o eth1 -j sqm
$IPT -t mangle -A zone_isolated_forward -o eth1 -j sqm_set_dscp

### match packet mark and set appropriate dscp flag
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 1 -j DSCP --set-dscp-class CS1 -m comment --comment "CS1 Background"
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 1 -j RETURN
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 3 -j DSCP --set-dscp-class CS3 -m comment --comment "CS3 Streaming"
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 3 -j RETURN
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 7 -j DSCP --set-dscp-class CS7 -m comment --comment "CS7 Latency Sensitive"
$IPT -t mangle -A sqm_set_dscp -m connmark --mark 7 -j RETURN

### set connection mark
### return back to main table/chain
$IPT -t mangle -A sqm_mark_cs1 -j CONNMARK --set-mark 1
$IPT -t mangle -A sqm_mark_cs1 -j RETURN
$IPT -t mangle -A sqm_mark_cs3 -j CONNMARK --set-mark 3
$IPT -t mangle -A sqm_mark_cs3 -j RETURN
$IPT -t mangle -A sqm_mark_cs7 -j CONNMARK --set-mark 7
$IPT -t mangle -A sqm_mark_cs7 -j RETURN

### check if packet has already been marked
### if true return to back to main table/chain
### if false set connmark based on iptables rules below
$IPT -t mangle -A sqm -m connmark ! --mark 0 -j RETURN

###################################################################
# Latency Sensitive (Voice Tin)
###################################################################

### Generic
$IPT -t mangle -A sqm -m ndpi --NTP -g sqm_mark_cs7
### Gaming
$IPT -t mangle -A sqm -m ndpi --CSGO -g sqm_mark_cs7
$IPT -t mangle -A sqm -s 10.0.1.60 -p udp -m multiport ! --dports 9000  -g sqm_mark_cs7 -m comment --comment "PS4 UDP"
$IPT -t mangle -A sqm -s 10.0.1.60 -p tcp -m multiport ! --dports 80,443  -g sqm_mark_cs7 -m comment --comment "PS4 TCP"
$IPT -t mangle -A sqm -p udp -m multiport --dports 5000:5500 -g sqm_mark_cs7 -m comment --comment "League of Legends"
$IPT -t mangle -A sqm -m ndpi --WorldOfWarcraft -g sqm_mark_cs7
### Voice
$IPT -t mangle -A sqm -m ndpi --TeamSpeak -g sqm_mark_cs7
$IPT -t mangle -A sqm -m ndpi --WhatsAppVoice -g sqm_mark_cs7

###################################################################
### Streaming Media (Video Tin)
###################################################################

$IPT -t mangle -A sqm -m ndpi --YouTube -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --NetFlix -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --Skype -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --AmazonVideo -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --Vevo -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --Twitch -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --GoogleHangout -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --Spotify -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --Deezer -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --SoundCloud -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --LastFM -g sqm_mark_cs3
### Remote Administration
$IPT -t mangle -A sqm -m ndpi --TeamViewer -g sqm_mark_cs3
$IPT -t mangle -A sqm -m ndpi --VNC -g sqm_mark_cs3

###################################################################
# Background Traffic (Bulk Tin)
###################################################################
### Mail
$IPT -t mangle -A sqm -m ndpi --SMTP -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --SMTPS -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --IMAP -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --IMAPS -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --POP3 -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --POPS -g sqm_mark_cs1
### P2P
$IPT -t mangle -A sqm -m ndpi --BitTorrent -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --eDonkey -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Thunder -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --AppleJuice -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Soulseek -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Gnutella -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --DirectConnect -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --FastTrack -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Stealthnet -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Filetopia -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Usenet -g sqm_mark_cs1
### Cloud
$IPT -t mangle -A sqm -m ndpi --Dropbox -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --GoogleDrive -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --MS_OneDrive -g sqm_mark_cs1
### Other
$IPT -t mangle -A sqm -m ndpi --PlayStore -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --GoogleDocs -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --YouTubeUpload -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --WhatsAppFiles -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --FTP_DATA -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --Git -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --RSYNC -g sqm_mark_cs1
$IPT -t mangle -A sqm -m ndpi --WindowsUpdate -g sqm_mark_cs1

# Consider "large" HTTP/S traffic (out/in) as Bulk
# Need some better solution for this
# But should work for most use cases
$IPT -t mangle -A sqm -p tcp -m connbytes --connbytes 10485760: --connbytes-dir reply --connbytes-mode bytes -m multiport --dports 80,443 -g sqm_mark_cs1
$IPT -t mangle -A sqm -p tcp -m connbytes --connbytes 1048576: --connbytes-dir original --connbytes-mode bytes -m multiport --dports 80,443 -g sqm_mark_cs1

ingress:
restore connmark to fwmark/packet mark
match marks to set tos/dscp flags

this one goes into layer cake script:

	# Set default class to best effort
	$TC filter add dev $IFACE parent ffff: protocol ip prio 10 u32 \
    match u32 0 0 flowid :1 \
	action pedit munge ip tos set 0 \
	pipe csum ip continue
	
    # restore connection's mark value into the packet's fwmark.
	$TC filter add dev $IFACE parent ffff: protocol ip prio 20 u32 \
    match u32 0 0 flowid :1 \
	action connmark continue
	
	# match fwmarks and set tos flag in ip header
	# fix checksum
	# immediately redirect to ifb4eth1 to avoid further unnecessary packet matching
	
	# CS1
    $TC filter add dev $IFACE parent ffff: protocol ip prio 30 u32 \
    match mark 0x1 0xf flowid :1 \
	action pedit munge ip tos set 32 \
	pipe csum ip \
	pipe mirred egress redirect dev $DEV
	
	# CS3
    $TC filter add dev $IFACE parent ffff: protocol ip prio 40 u32 \
    match mark 0x3 0xf flowid :1 \
	action pedit munge ip tos set 96 \
	pipe csum ip \
	pipe mirred egress redirect dev $DEV
	
	# CS7
    $TC filter add dev $IFACE parent ffff: protocol ip prio 50 u32 \
    match mark 0x7 0xf flowid :1 \
	action pedit munge ip tos set 224 \
	pipe csum ip \
	pipe mirred egress redirect dev $DEV
	
	# Redirect everything else to ifb4eth1
    $TC filter add dev $IFACE parent ffff: protocol all prio 100 u32 \
	match u32 0 0 flowid :1 \
	action mirred egress redirect dev $DEV

To make this work, following changes are needed also:

diff --git a/package/kernel/linux/modules/netsupport.mk b/package/kernel/linux/modules/netsupport.mk
index ff76720636..c245d36678 100644
--- a/package/kernel/linux/modules/netsupport.mk
+++ b/package/kernel/linux/modules/netsupport.mk
@@ -695,7 +695,7 @@ $(eval $(call KernelPackage,mppe))
 
 
 SCHED_MODULES = $(patsubst $(LINUX_DIR)/net/sched/%.ko,%,$(wildcard $(LINUX_DIR)/net/sched/*.ko))
-SCHED_MODULES_CORE = sch_ingress sch_fq_codel sch_hfsc sch_htb sch_tbf cls_fw cls_route cls_flow cls_tcindex cls_u32 em_u32 act_mirred act_skbedit
+SCHED_MODULES_CORE = sch_ingress sch_fq_codel sch_hfsc sch_htb sch_tbf cls_fw cls_route cls_flow cls_tcindex cls_u32 em_u32 act_mirred act_pedit act_csum act_skbedit
 SCHED_MODULES_FILTER = $(SCHED_MODULES_CORE) act_connmark sch_netem
 SCHED_MODULES_EXTRA = $(filter-out $(SCHED_MODULES_FILTER),$(SCHED_MODULES))
 SCHED_FILES = $(patsubst %,$(LINUX_DIR)/net/sched/%.ko,$(filter $(SCHED_MODULES_CORE),$(SCHED_MODULES)))
@@ -704,6 +704,7 @@ SCHED_FILES_EXTRA = $(patsubst %,$(LINUX_DIR)/net/sched/%.ko,$(SCHED_MODULES_EXT
 define KernelPackage/sched-core
   SUBMENU:=$(NETWORK_SUPPORT_MENU)
   TITLE:=Traffic schedulers
+  DEPENDS:=+kmod-lib-crc32c
   KCONFIG:= \
        CONFIG_NET_SCHED=y \
        CONFIG_NET_SCH_HFSC \
@@ -719,6 +720,8 @@ define KernelPackage/sched-core
        CONFIG_NET_CLS_TCINDEX \
        CONFIG_NET_CLS_U32 \
        CONFIG_NET_ACT_MIRRED \
+       CONFIG_NET_ACT_PEDIT \
+       CONFIG_NET_ACT_CSUM \
        CONFIG_NET_ACT_SKBEDIT \
        CONFIG_NET_EMATCH=y \
        CONFIG_NET_EMATCH_U32

1 Like