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β
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.
Connections that don't match a rule will be automatically classified by the service using one of the below methods.
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.
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.
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
The dscpclassify service uses the last 8 bits of the conntrack mark (0x000000ff), leaving the remaining bits for use by other applications.
To install dscpclassify via command line you can use the following sets of commands.
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
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"
The service configuration is located in '/etc/config/dscpclassify'.
A working default configuration is provided with the service which should work for most users.
Name | Type | Required | Default | Description |
---|---|---|---|---|
class_low_effort | string | no | le 1 | 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
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 ! |
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 |
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 |
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 @ prefix1. |
|
dest_mac | list | no | Match traffic directed to the specified destination MAC address. Set names can be specified with the @ prefix1. |
|
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 @ prefix1. |
|
src_mac | list | no | Match traffic from the specified source MAC address. Set names can be specified with the @ prefix1. |
|
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.
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'
The set sections in /etc/config/dscpclassify
use a similar syntax to OpenWrt's firewall, they can be used in conjunction with rules to allow re-use of addresses or dynamic list population from external sources.
DSCP classify's default rules can be viewed here.
Sets must not must not contain multiple address types (i.e. IPv4 and IPv6 addresses in the same set is unsupported). Sets should be referenced using dest_ip/src_ip/dest_mac/src_mac, with the set name name prefixed with '@'.
Name | Type | Required | Default | Description |
---|---|---|---|---|
enabled | boolean | no | 1 | Allows to disable the declaration of the set without the need to delete the section. |
name | string | yes | Name of the set. | |
entry | list | no | IP/MAC address or CIDR notation. | |
loadfile | string | no | A path URL on the openwrt filesystem to a file containing a list of addresses or CIDRs. | |
Advanced | The below config options are not required by most users | |||
comment | string | no | A user defined comment associated with the set. | |
family | string | no | Specifies the address family (ipv4 , ipv6 ) for the set, if absent the service identifies this from the address entries1. |
|
maxelem | uint | no | Limits the number of entries that can be added to the set. | |
timeout | uint | no | Specifies the default timeout for entries added to the set. A value of 0 enables the timeout capability flag on the set, but does not put a timeout on entries. |
1. Vervsions β₯ 2.0 will attempt to autodetect a set's family if the option is not specified.
config set
option name 'ms_teams'
list entry '13.107.64.0/18'
list entry '52.112.0.0/14'
list entry '52.122.0.0/15'
config set
option name 'ms_teams6'
option family 'ipv6'
list entry '2603:1063::/39'
config rule
option name 'Microsoft Teams Voice'
option proto 'udp'
option src_port '50000-50019'
option dest_port '3478-3481'
list dest_ip '@ms_teams'
list dest_ip '@ms_teams6'
option class 'ef'
The 'layer_cake_ct.qos' queue setup script must be selected for your wan device in SQM setup,
It is important that Ignore DSCP on ingress is Allow in SQM setup otherwise cake will ignore the service's DSCP classes.
Config parameter | Value |
---|---|
qdisc_advanced | 1 |
squash_dscp | 0, to ensure cake does not remove ingress packet DSCP values |
squash_ingress | 0, to ensure cake looks at packet marks on ingress |
qdisc_really_really_advanced | 1 |
iqdisc_opts | nat dual-dsthost ingress diffserv4 |
eqdisc_opts | nat dual-srchost ack-filter diffserv4 |
script | layer_cake_ct.qos |
To remove dscpclassify via command line you can use the following commands.
/etc/init.d/dscpclassify stop
/etc/init.d/dscpclassify disable
rm -rf "/etc/dscpclassify.d"
rm -f "/etc/hotplug.d/iface/21-dscpclassify"
rm -f "/etc/init.d/dscpclassify"