Creating DSCP markings with iptables?

Hi Everyone,

New to setting up on how to create dscp marking on specific mac address or potentially a port? This is just outgoing.

I have a torrentbox I just wont to go in to the bulk category the whole device it has a static ip of 10.0.2.236 and anything can go to bulk.

I would like all traffice from my dns sever to go in to the voice category (I use a pihole) or simply the dns port of 53. I use unbound on this device for dns resolution ipv4/ipv6.

How could someone set this up through iptables to route this traffice through layer cake with the proper markings?

Thanks!

You're not alone in caring about this...

A few months ago the OpenWrt gained the ability to match and set DSCP marks in the firewall with commit https://github.com/openwrt/openwrt/commit/03e5dcbf10b1f67a463735efd8db3386f91473fd. I don't think there's support yet for this in Luci, but hopefully soon :wink:.

You could also dig through the specific fw3 commit for more details.

For the current stable versions, you could create custom user firewall rules in the GUI, or follow @jow's earlier advice:

Cheers and take care...

Thanks for that @guidosarducci

Looks like I can just switch from wan in to lan in and wan out? I am looking an just shaping my upload, whatever comes in is what comes in and figure that is just the wild west.

I'm using code like this in my firewall.user script. requires iptables-mod-ipopt package.

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 CS5
iptables -t mangle -A dscp_mark  -p icmp -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p icmpv6 -j DSCP --set-dscp-class CS5

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

## valve games use these ports (at least)

iptables -t mangle -A dscp_mark  -p udp --sport 27000:27200 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --sport 27000:27200 -j DSCP --set-dscp-class CS5

iptables -t mangle -A dscp_mark  -p udp --dport 27000:27200 -j DSCP --set-dscp-class CS5
ip6tables -t mangle -A dscp_mark -p udp --dport 27000:27200 -j DSCP --set-dscp-class CS5

4 Likes

It seems a bit counter intuitive to prioritize all ICMP packets, as this basically makes ping only measure the priority tier that claims CS5. I MHO gnu ping allows the (root?) user to set the TOS/DSCP bits from the command-line, hence not automatically re-mapping ICMP (which will override the user-configured DSCP) does seem counter-intuitive to me. Also if my ISP would do something like that, I would be unhappy and mumble about net-neutrality violations.
I also note that even for the other arguably more important ICMP types, big irob routers typically use de-prioritization and rate-limiting...

My philosophy on bufferbloat is somewhat different from the cake one. My custom shaper using hfsc allows 100ms of delay on normal and cs1 traffic in exchange for slamming VoIP and game traffic down the pipe at up to 900mbps briefly to achieve less than 5ms delay. So when I run a dslreports test I'm looking for the bufferbloat experienced by my high priority traffic. Since I can't control tags on those packets so easily I went the lazy way.

Edit, also this is only on my APs so it affects wireless traffic only.

Mileage may vary

Ah, I guess that makes some sense. I should have been assuming that you had a good rationale behind that :wink:
I too often use ping on the commandline for that to be a convenient solution (or put differently I mostly use the dscp=0 tier and want by default probe that).

Sidenote: I am not 100% sure that dslreports actually uses ICMP probes for its bufferbloat measurements; at least I see way fewer ICMP packets in a capture than bufferbloat probes in the bufferbloat plots and those ICMP packets are not even interleaved with the TCP measurement periods of the test. I realize that this is orthogonal to your rationale. (I really just want to avoid people putting ping into a high priority tier without understanding the consequences ; ) )

1 Like

It brings up a good point though, which is that when it comes to explicit prioritization, there can never be a one-size-fits-all scenario. Business offices with tens or hundreds of VoIP phones will be different from gamers at home who don't use VoIP at all. Guest networks will be different from "main" networks. IoT devices will be different from desktops under your complete control... It's all about achieving high "utility" which is inherently an individualized concept. Cake does a great job because many people just want "everything to be not too delayed". But the call center company with 200 VoIP phones might well want to delay the off duty employees surfing Facebook by quite a lot :wink:

Yes thanks for pointing it out. And yes, I was kinda suspicious of dslreports pings. I'm confident that my code above fits pretty well with my personal requirements, but anyone doing DSCP tagging should think out their own requirements rather than copy and paste.

EDIT: Also I've taken to tagging everything CS2 by default. It works better with low end switches such as TP-Link which tend to assume they can treat DSCP as a monotone increasing priority number. Most people treat CS0 and CS1 correctly, but these low end switches will actually prioritize the CS1 scavenging traffic over the normal traffic. So I just bump all CS0 to CS2 as it transits the router inbound.

1 Like

+1, IMHO the idea to not use dscp 0 for bulk/background is misguided. Or put differently declaring CS0 to be the new background will reward people actually change the dscp values and maintains a sane mapping of priority to number (and a mapping simple enough for hardware manufactures to nor screw up), But I note that there is https://tools.ietf.org/html/draft-ietf-tsvwg-le-phb-02 which basically argues to not use CS1 as background, but rather a DSCP that lives inside CS0 so that non-compliant network nodes will just treat bulk as best effort instead of giving it priority over DSCP 0...

I think the big problem with declaring CS0 a background tier is that huge quantities of non-techies will never be altering their DSCP and then things potentially suffer on grandma's network. On the other hand, as of today, I don't see any harm in having ISP provided devices automatically switch CS0 to CS2 on ingress. That seems sane.

This is actually the charm of rededicating CS0 for background, now there potentially is something to be gained by actively changing the dscp :wink: Now really if one wants to encourage change in behaviour a bit of "carrot and stick" often can help.

I suppose you're right, but I'm not at all confident it would be done sanely. Like Linksys or TP-Link might just put a rule in their firmware: "remark every packet CS2" thereby killing all DSCP and causing DSCP to be a worthless endeavor for almost everyone.

Per this I could set a

iptables -t mangle -A dscp_mark -p tcp -sport 55555:55555 -j DSCP --set-dscp-class cs0

And this would mark port 55555 (torrent box) as bulk?

Again I only care about shaping outgoing.

You need to do all the stuff that sets up the dscp_mark chain, and I think use just the one port not a range but basically yes.

Also CS0 is normal priority CS1 is low by most people's schemes.

Great examples!

I recently got an Archer C59 and i tried your script but it breaks my 5Ghz wifi... your script works great with a dlink 835.. any ideas of why it breaks the 5ghz??

After setting the script I can connect to the 5Ghz but i dont have internet in any device.

Weird, I have no idea why that would be.

damn.. i wanted to upgrade from 5ghz N (my DIR835) to AC (arher c59) I copied all the config (sqm and other configs) and everything was working correctly until I added the dscp markings... the internet slows down right away to the point nothing opens even putty disconnects from the router's ssh session.

What could be the problem?..

2.4Ghz Wifi works fine.

And this doesn't happen with DSCP on your other router? DSCP does affect the use of WMM and also can be interpreted by your ISP, but if it doesn't happen when you use your other router, then it's probably not the ISP. Are you using my script as posted, or doing something of your own modifications? Perhaps you're putting DSCP marks that are being interpreted by the AC driver differently and it's stalling something?

But i'd expect it to just slow down, not actually stall completely.

I did some modifications to my setup, I'm not sure if it has to do with the ISP, it work well in 2ghz.. in the dir835 it works flawless 5ghz and dscp marking, the archer c59 is the one giving trouble...

this is how i have my dscp markings :

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 CS1
ip6tables -t mangle -A dscp_mark -p icmpv6 -j DSCP --set-dscp-class CS1

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

## web y youtube

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

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 CS3
ip6tables -t mangle -A dscp_mark -p tcp --sport 443:443 -j DSCP --set-dscp-class CS3
iptables -t mangle -A dscp_mark  -p tcp --dport 443:443 -j DSCP --set-dscp-class CS3
ip6tables -t mangle -A dscp_mark -p tcp --dport 443:443 -j DSCP --set-dscp-class CS3

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

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

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

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

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

I gave udp ports prioritity because of gaming, only udp 443 has less priority because youtube uses it and it is only buffering.