Dscpclassify
An nftables based service for applying DSCP classification to connections.
Install / Use
/learn @jeverley/DscpclassifyREADME
What is DSCP Classify? ⭐
DSCP Classify is a service for applying DSCP class to connection packets (supporting OpenWrt 22.03 and above).
It can be used with SQM layer cake QoS to manage priority of client connections (VoIP/gaming/downloads/P2P etc) and reduce Bufferbloat.
The service supports both automatic and user rule classification of connections.
DSCP Classify can mark LAN destined packets with WMM mapped classes to improve transmit prioritisation with 3rd party WiFi access points and switches, see the wmm_mark_lan service configuration option.
Users of layer-cake SQM should install the layer_cake_ct SQM script for setting DSCP marks on inbound packets, see SQM Configuration❗
User Rules 📝
You can create rules to classify new connections in the service config file.
These use a similar syntax to the OpenWrt firewall config and can match source and destination ports, addresses, sets, firewall zones etc.
More information and examples can be found in the rules section.
Automatic Classification 🪄
Connections that don't match a rule will be automatically classified by the service using one of the below methods.
Client class adoption ✨
The service can automatically adopt the DSCP mark supplied by a non-WAN client.
By default this ignores classes CS6 and CS7 to avoid abuse from clients such as IoT devices.
Bulk client detection for P2P traffic 🌎
These connections are one of the largest causes of Bufferbloat, as a result they are classified as Low Effort (LE) by default and therefore prioritised below Best Effort (BE/DF/CS0) traffic when using the layer-cake qdisc.
High Throughput service detection for Steam downloads, cloud storage etc 🚛
Services such as Steam make use of parralel connections to maximise download bandwith, this can also cause bufferbloat and so these connections are classified as High-Throughput (AF13) by default and prioritised as follows by cake:
- diffserv8: prioritised below Best Effort (BE/DF/CS0) traffic and above Low Effort (LE) traffic
- diffserv3/4: prioritised equal to Best Effort (BE/DF/CS0) traffic
Service Architecture 🏗️
The dscpclassify service uses the last 8 bits of the conntrack mark (0x000000ff), leaving the remaining bits for use by other applications.
<img src="https://user-images.githubusercontent.com/46714706/188151111-9167e54d-482e-4584-b43b-0759e0ad7561.png" width="80%">Service Installation ⚙️
To install dscpclassify via command line you can use the following sets of commands.
dscpclassify
repo="https://raw.githubusercontent.com/jeverley/dscpclassify/main"
mkdir -p "/etc/dscpclassify.d"
if [ ! -f "/etc/config/dscpclassify" ]; then
wget "$repo/etc/config/dscpclassify" -O "/etc/config/dscpclassify"
else
wget "$repo/etc/config/dscpclassify" -O "/etc/config/dscpclassify_git"
fi
wget "$repo/etc/dscpclassify.d/main.nft" -O "/etc/dscpclassify.d/main.nft"
wget "$repo/etc/dscpclassify.d/maps.nft" -O "/etc/dscpclassify.d/maps.nft"
wget "$repo/etc/dscpclassify.d/verdicts.nft" -O "/etc/dscpclassify.d/verdicts.nft"
wget "$repo/etc/hotplug.d/iface/21-dscpclassify" -O "/etc/hotplug.d/iface/21-dscpclassify"
wget "$repo/etc/init.d/dscpclassify" -O "/etc/init.d/dscpclassify"
chmod +x "/etc/init.d/dscpclassify"
/etc/init.d/dscpclassify enable
/etc/init.d/dscpclassify start
layer_cake_ct.qos
Ingress DSCP marking for SQM cake requires installation and configuration of 'layer_cake_ct.qos' and the package 'kmod-sched-ctinfo'❗
repo="https://raw.githubusercontent.com/jeverley/dscpclassify/main"
opkg update
opkg install kmod-sched-ctinfo
wget "$repo/usr/lib/sqm/layer_cake_ct.qos" -O "/usr/lib/sqm/layer_cake_ct.qos"
wget "$repo/usr/lib/sqm/layer_cake_ct.qos.help" -O "/usr/lib/sqm/layer_cake_ct.qos.help"
Configuration ⚙️
The service configuration is located in '/etc/config/dscpclassify'.
A working default configuration is provided with the service which should work for most users.
Section "service"
|Name | Type | Required | Default | Description|
|--- | --- | --- | --- | ---|
|class_low_effort | string | no | le <sup>1</sup> | The default DSCP class applied to low effort connections |
|class_high_throughput | string | no | af13 | The default DSCP class applied to high-throughput connections |
|wmm_mark_lan | boolean | no | 0 | Mark packets going out of LAN interfaces with DSCP values respective of WMM (RFC-8325) |
|Advanced | | | | The below options are typically only required on non-standard setups |
|lan_zone | list | no | lan | Used to specify LAN firewall zones (lan/guest etc) |
|wan_zone | list | no | wan | Used to specify WAN firewall zones |
|lan_device | list | no | | Used to specify LAN network interfaces (L3 physical interface i.e. br-lan) |
|wan_device | list | no | | Used to specify WAN network interfaces (L3 physical interface) |
1. When running on older OpenWrt releases with kernels < 5.13 the service defaults to class CS1 for low effort connections
Section "client_class_adoption"
|Name | Type | Required | Default | Description| |--- | --- | --- | --- | ---| |enabled | boolean | no | 1 | Adopt the DSCP class supplied by a non-WAN client | |exclude_class | list | no | cs6, cs7 | Classes to ignore from client class adoption | |src_ip | list | no | | Include/Exclude source IPs / sets for class adoption, preface excluded IPs with ! | |src_mac | list | no | | Include/Exclude source MACs / sets for class adoption, preface excluded MACs with ! |
Section "bulk_client_detection"
|Name | Type | Required | Default | Description| |--- | --- | --- | --- | ---| |enabled | boolean | no | 1 | Detect and classify bulk client connections (i.e. P2P)| |class | string | no | | Override the service level class_high_throughput setting | |Advanced | | | | The default configuration for the below should work for most users | |min_connections | number | no | 10 | Minimum established connections for a client port to be considered as bulk | |min_bytes | number | no | 10000 | Minimum bytes before a client port is classified as bulk |
Section "high_throughput_service_detection"
|Name | Type | Required | Default | Description| |--- | --- | --- | --- | ---| |enabled | boolean | no | 1 | Detect and classify high throughput service connections (i.e. Windows Update/Steam downloads) | |class | string | no | | Override the service level class_high_throughput setting | |Advanced | | | | The default configuration for the below should work for most users | |min_connections | number | no | 3 | Minimum established connections for a service to be considered as high-throughput | |min_bytes | number | no | 1000000 | Minimum bytes before the connection is classified as high-throughput |
Section "rule"
The rule sections in /etc/config/dscpclassify use the same syntax as OpenWrt's firewal, the class option is used to specified the desired DSCP.
The OpenWrt fw4 rule syntax is outlined in the OpenWrt Wiki, dscpclassify default rules can be viewed here'.
|Name | Type | Required | Default | Description|
|--- | --- | --- | --- | ---|
|enabled | boolean | no | 1 | Enable or disable rule. |
|class | string | yes | | The class to apply to connections matching this rule. |
|name | string | no | | Name of the rule. |
|family | string | no | | Specifies the address family (ipv4, ipv6 or any) for which the rules are generated. |
|proto | list | no | | Match traffic using the given protocol. Can be one (or several when using list syntax) of tcp, udp, udplite, icmp, esp, ah, sctp, or all. A protocol name from /etc/protocols is also allowed. |
|dest | list | no | | Specifies the traffic destination firewall zone. Refers to one of the defined zone names. |
|dest_ip | list | no | | Match traffic directed to the specified destination IP address, CIDR notations can be used. Set names can be specified with the @ prefix<sup>1</sup>. |
|dest_mac | list | no | | Match traffic directed to the specified destination MAC address. Set names can be specified with the @ prefix<sup>1</sup>. |
|dest_port | list | no | | Match traffic to the specified source port or port range. |
|src | list | no | | Specifies the traffic source firewall zone. Refers to one of the defined zone names. |
|src_ip | list | no | | Match traffic from the specified source IP address, CIDR notations can be used. Set names can be specified with the @ prefix<sup>1</sup>. |
|src_mac | list | no | | Match traffic from the specified source MAC address. Set names can be specified with the @ prefix<sup>1</sup>. |
|src_port | list | no | | Match traffic from the specified source port or port range. |
|device | string | no | | Match traffic going in/out of a particular L3 device. |
|direction | string | no | | Must be used in conjunction with device, specifies whether to match traffic travelling in or out. |
|counter | boolean | no | 0 | Enables an nft counter that counts connections matched by the rule. |
1. Vervsions ≥ 2.0 allow a mix of sets, MAC, ipv4 and ipv6 addresses.
Example user rule 📃
config rule
option name 'DNS'
list proto 'tcp'
list proto 'udp'
list dest_port '53'
list dest_port '853'
list dest_port '5353'
list dest_ip '8.8.8.8'
list dest_ip '2001:4860:4860::8888'
list dest_ip '@DoH'
list dest_ip '@DoH6'
option class 'cs5'
option counter '0'
Section "set"
The set sections in `/etc/config/ds
Related Skills
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
