Creating DSCP markings with iptables?

Well as you said, it does affect the wmm setting so I disabled it and the internet started working right away... so, should i keep the dscp marking without wmm or would it be best to disable dscp and enable wmm?? honestly i feel the internet more snappy without wmm.

edit: ok no... the truth is that without wmm bandwitdh is crap, I rather disable dscp than wmm.

any ideas?

AFAIR, CS6 is mapped to AC_VO (see https://wireless.wiki.kernel.org/en/developers/documentation/mac80211/queues) and you seem toclassify a lot as CS6. Now the voice queue in WMM will not use packet aggregation and will have hence a terrible wifi-MAC-Overhead to ethernet payload ratio. You might want to try scaling back to CS5 which uses the video queue which still has higher priority than the default bulk queue (see http://wifi-insider.com/wlan/wmm.htm) but the access class voice is really only useful if used sparsely (like for VoIP calls, though in the linux default mapping these end up in AC-VI).

I tried changing CS6 to CS5 but I got the same results, no internet... for now I went back to my DIR-835 which works great, I need to find what the problem is.. BTW both are using the same snapshot compiled by me today. so the software is identically in both routers

I think what you need to do is choose DSCP tagging scheme that makes use of WMM "properly" unfortunately, that's not so trivial to do. Some day we may get control of this in OpenWrt hostapd, but for the moment, we can only use the "default" that the driver uses.

https://wireless.wiki.kernel.org/en/developers/documentation/mac80211/queues?s[]=wmm

If you can make heads or tails of that, you'll see some things, like for example CS3 and CS0 are both Best Effort, CS1 and CS2 are BULK, while CS4 and CS5 will be "video" and CS6 and CS7 will be Voice.

Your rule to tag udp almost every port as CS6 will cause websites using QUIC protocol to dominate the VOICE queue, which causes you to lose a lot of bandwidth. the VOICE queue is very good for low bandwidth latency sensitive stuff, like voice or game controls but if you put general surfing through it it will screw things up. Chrome uses QUIC, I'm not sure if other browsers do. But in general I think it's a bad idea to put all your UDP through the voice queue.

I'd suggest to start by tagging everything by default CS3, identify game and voip stuff and tag CS5, and identify bulk stuff and tag CS1. Bulk can be usually identified by conntrack bytes (total transfer statistics) any stream that transfers more than say 10 seconds worth of your full bandwidth allotment should be converted to CS1.

what games and voip type traffic do you use? If you have a console for example I'd just tag everything to or from that device CS5 as first approximation (though you could maybe do just all UDP).

EDIT: sorry, tag game and voip stuff CS6. Ideally you'd do something like CS4 for YouTube or IPTV streams, but they can be hard to identify. In order to do that stuff I use an explicitly configured squid proxy which lets it decide based on the domain name what tag it should put on the packet.

EDIT2: also, although you have the same software on your two builds, the devices use different hardware and therefore different drivers, I'm suspicious you're tickling a driver issue.

thanks for clearing me the use of CS i thought it was only increasing priorities, I didn't know that they worked in pairs...

well for gaming I normally play on switch or PC, pc games tend to give the actual ports but Nintendo just says that they use all udp ports... I will try to tag all udp only on that console and ps4 to start, for voice chat I normally use discord on my smartphone.

I have connected the archer c59 again I will try to add the sqm rules to only the wan port instead of limiting the upload with my download speed in the wifi (I saw another thread where it was recommended to get a bit lower ping)

Also I will try to better separate the CS priorities and tell you how it goes.

OK, it seems that you were right about the cs priorities.... I only started by changing the CS to what I think it would be best after your explanation and this is how I left them:

iptables -t mangle -N dscp_mark
ip6tables -t mangle -N dscp_mark
iptables -t mangle -F dscp_mark
ip6tables -t mangle -F dscp_mark

iptables -t mangle -A FORWARD -j dscp_mark
ip6tables -t mangle -A FORWARD -j dscp_mark


## icmp gets CS1
iptables -t mangle -A dscp_mark  -p icmp -j DSCP --set-dscp-class CS0
ip6tables -t mangle -A dscp_mark -p icmpv6 -j DSCP --set-dscp-class CS0

## game traffic for rocket league?
iptables -t mangle -A dscp_mark  -p udp --sport 1:442 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --sport 1:442 -j DSCP --set-dscp-class CS5
iptables -t mangle -A dscp_mark  -p udp --dport 1:442 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --dport 1:442 -j DSCP --set-dscp-class CS5
iptables -t mangle -A dscp_mark  -p udp --sport 444:65535 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --sport 444:65535 -j DSCP --set-dscp-class CS5
iptables -t mangle -A dscp_mark  -p udp --dport 444:65535 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --dport 444:65535 -j DSCP --set-dscp-class CS5

## SMB Share transfers

iptables -t mangle -A dscp_mark  -p tcp --sport 445:445 -j DSCP --set-dscp-class CS1
ip6tables -t mangle -A dscp_mark -p tcp --sport 445:445 -j DSCP --set-dscp-class CS1
iptables -t mangle -A dscp_mark  -p tcp --dport 445:445 -j DSCP --set-dscp-class CS1
ip6tables -t mangle -A dscp_mark -p tcp --dport 445:445 -j DSCP --set-dscp-class CS1

## web y youtube

iptables -t mangle -A dscp_mark  -p tcp --sport 80:80 -j DSCP --set-dscp-class CS1
ip6tables -t mangle -A dscp_mark -p tcp --sport 80:80 -j DSCP --set-dscp-class CS1
iptables -t mangle -A dscp_mark  -p tcp --dport 80:80 -j DSCP --set-dscp-class CS1
ip6tables -t mangle -A dscp_mark -p tcp --dport 80:80 -j DSCP --set-dscp-class CS1

iptables -t mangle -A dscp_mark  -p udp --sport 443:443 -j DSCP --set-dscp-class CS4
ip6tables -t mangle -A dscp_mark -p udp --sport 443:443 -j DSCP --set-dscp-class CS4
iptables -t mangle -A dscp_mark  -p udp --dport 443:443 -j DSCP --set-dscp-class CS4
ip6tables -t mangle -A dscp_mark -p udp --dport 443:443 -j DSCP --set-dscp-class CS4

#Nintendo Switch TCP

iptables -t mangle -A dscp_mark  -p tcp --sport 443:443 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 443:443 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 443:443 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 443:443 -j DSCP --set-dscp-class CS2

iptables -t mangle -A dscp_mark  -p tcp --sport 6667:6667 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 6667:6667 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 6667:6667 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 6667:6667 -j DSCP --set-dscp-class CS2

iptables -t mangle -A dscp_mark  -p tcp --sport 12400:12400 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 12400:12400 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 12400:12400 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 12400:12400 -j DSCP --set-dscp-class CS2

iptables -t mangle -A dscp_mark  -p tcp --sport 28910:28910 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 28910:28910 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 28910:28910 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 28910:28910 -j DSCP --set-dscp-class CS2

iptables -t mangle -A dscp_mark  -p tcp --sport 29900:29901 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 29900:29901 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 29900:29901 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 29900:29901 -j DSCP --set-dscp-class CS2

iptables -t mangle -A dscp_mark  -p tcp --sport 29920:29920 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --sport 29920:29920 -j DSCP --set-dscp-class CS2
iptables -t mangle -A dscp_mark  -p tcp --dport 29920:29920 -j DSCP --set-dscp-class CS2
ip6tables -t mangle -A dscp_mark -p tcp --dport 29920:29920 -j DSCP --set-dscp-class CS2

after this change the internet is ok and everything working normally, I still have to test gaming but for now everything works SQM included.

I will be doing some tests and see if it fails, now I wonder if the dscp was working correctly in the DIR835 xD

I would change this to give the Nintendo Switch a static IP reservation in your DHCP settings, then supposing that it's 192.168.1.22 you could use a rule like this:

iptables -t mangle -A dscp_mark  --src 192.168.1.22 -j DSCP --set-dscp-class CS6
iptables -t mangle -A dscp_mark --dst 192.168.1.22 -j DSCP --set-dscp-class CS6

You can do a similar thing in ipv6 by using the SLAAC address that the Nintendo Switch chooses.

@terry98

icmp gets CS1

iptables -t mangle -A dscp_mark -p icmp -j DSCP --set-dscp-class CS0
ip6tables -t mangle -A dscp_mark -p icmpv6 -j DSCP --set-dscp-class CS0

Is that supposed to be CS0 or CS1??? Your comment and code don't match...just wondering :thinking:

I personally think icmp should be best effort or better, CS4 makes decent sense. Otherwise important notification messages like fragmentation required for ipv6 could starve if they are in a background queue.

I could do that but then, browsing eshop or other things not so gaming would affect the priorities for other things... if I can use the ip address and the ports then I could try that, btw i have dhcp reserved addresses for all my devices.

I have ipv6 rules because of your post but I'm not using ipv6, I'm only using ipv4.

I was running x86-64 snapshot builds (Dec 4 and Dec 11, 2018) so I could try out TCP congestion control BBR over Cubic. For some reason the DSCP rules would not load in to the dscp_mark Chain when specifying '--src [ip]' or '--dst [ip]'. Example:

iptables -t mangle -A dscp_mark  -p udp --src 192.168.1.40 -j DSCP --set-dscp-class CS5
iptables -t mangle -A dscp_mark  -p udp --dst 192.168.1.40 -j DSCP --set-dscp-class CS5

These rules work fine in 18.06.1. Rules without the source or destination IP specified work fine, such as port or just protocol.

I was able to work around it by installing 'iptables-mod-iprange' and changing the rules with a destination and source address to:

iptables -t mangle -A dscp_mark -p udp -m iprange --src-range 192.168.1.40-192.168.1.40 -j DSCP --set-dscp-class CS5
iptables -t mangle -A dscp_mark -p udp -m iprange --dst-range 192.168.1.40-192.168.1.40 -j DSCP --set-dscp-class CS5

Does anyone know the reason why specifying the source or destination IP in the DSCP rules does not work in the snapshot builds?

Do you do that a lot on your switch?

My point is that if you have a dedicated gaming machine then prioritizing everything to or from that machine makes sense for simplicity.

Whatever works for you though, prioritization is about meeting your expectations for what's important.

I guess you're right, I don't use the switch that often, mostly on weekends.. I will try to separate the ports using dedicated IPs and hope that they work or I'll have to do something like @mj5030 was saying.

I will try when I get home tonight.

I do not have answer but thanks for this this helped me also. I needed just an IP address to go to bulk and really nothing more and noticed the same thing it just would not stick but with that package it does work as a range.

EDIT: For ip6tables should I use the 2601 address? I believe this is correct as this is the internet facing ip6 address? New to ip6 and understanding it.

You can have several public IP addresses including privacy ones that change on a regular basis, so it's hard to just tag an IP in ipv6 unless you can control the device and assign a static one or a DHCPv6 one. A better solution might be to use a MAC address match

Thanks for the response. Being new to iptables how would I specify using a MAC address?

Also the device does have a static lease like all standard devices on my network. I am seeing traffic come through on the ip6 address checking my firewall status.

http://ipset.netfilter.org/iptables-extensions.man.html

Looks like -m mac --mac-source xx:xx...
Might require a kmod install

Thanks!

This did work I am testing right now, but I did not need to install any kmod options to get this to work.

1 Like

I think you don't need any kernel module, do you see any error while running the command?

No errors in the log or when I restarted the firewall rules. So far it works just fine.