# QoS help

## Akaihiryuu

Basically, I'm trying to stop things like torrents and Steam downloads from lagging online games.  I've determined that the game in question uses TCP 1119 and 3724.  I'm basically just trying to set up some simple HTB rules to prioritize this.  It's helping, but it's not nearly enough and I'm still getting 1200+ms latency when Steam downloads are going which is completly unacceptable.  I consider anything over 100ms unacceptable.

Here's what I've got so far (split up into two places).  I'm doing HTB stuff with TC, and classifying with iptables mangle.  My upstream is supposed to be 1mbps, but in practice I get 800 or less, so I've set the upstream pretty conservatively.  Does anyone see anything that I missed or anything obviously wrong that would cause this to not have as much of an effect as it should?

```
#!/bin/bash

TC="/sbin/tc"

DEV="eth1"

UP=768

tc qdisc del dev ${DEV} root 2> /dev/null > /dev/null

if [ "$1" = "stop" ]

then

        exit

fi

${TC} qdisc add dev ${DEV} root handle 1: htb default 12

${TC} class add dev ${DEV} parent 1: classid 1:1 htb rate ${UP}kbit ceil ${UP}kbit

${TC} class add dev ${DEV} parent 1:1 classid 1:10 htb rate $((UP / 2))kbit ceil ${UP}kbit prio 1

${TC} class add dev ${DEV} parent 1:1 classid 1:11 htb rate $((UP / 4))kbit ceil ${UP}kbit prio 2

${TC} class add dev ${DEV} parent 1:1 classid 1:12 htb rate $((UP / 4))kbit ceil $((UP * 3 / 4))kbit prio 3

${TC} filter add dev ${DEV} parent 1: protocol ip prio 1 handle 1 fw classid 1:10

${TC} filter add dev ${DEV} parent 1: protocol ip prio 2 handle 2 fw classid 1:11

${TC} filter add dev ${DEV} parent 1: protocol ip prio 3 handle 3 fw classid 1:12

${TC} qdisc add dev ${DEV} parent 1:11 handle 110: sfq perturb 10

${TC} qdisc add dev ${DEV} parent 1:12 handle 120: sfq perturb 10
```

```
#!/bin/bash

MGL="/sbin/iptables -t mangle"

${MGL} -F PREROUTING

${MGL} -F OUTPUT

if  [ "$1" = "stop" ]

then

        exit

fi

${MGL} -A PREROUTING -p icmp -j MARK --set-mark 0x1

${MGL} -A PREROUTING -p icmp -j RETURN

${MGL} -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1

${MGL} -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

${MGL} -A PREROUTING -p tcp --dport 1119 -j MARK --set-mark 0x1

${MGL} -A PREROUTING -p tcp --dport 1119 -j RETURN

${MGL} -A PREROUTING -p tcp --dport 3724 -j MARK --set-mark 0x1

${MGL} -A PREROUTING -p tcp --dport 3724 -j RETURN

${MGL} -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 0x1

${MGL} -A PREROUTING -m tos --tos Minimize-Delay -j RETURN

${MGL} -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 0x2

${MGL} -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN

${MGL} -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 0x3

${MGL} -A PREROUTING -m tos --tos Minimize-Cost -j RETURN

${MGL} -A PREROUTING -j MARK --set-mark 0x3

${MGL} -A OUTPUT -p icmp -j MARK --set-mark 0x1

${MGL} -A OUTPUT -p icmp -j RETURN

${MGL} -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1

${MGL} -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

${MGL} -A OUTPUT -m tos --tos Minimize-Delay -j MARK --set-mark 0x1

${MGL} -A OUTPUT -m tos --tos Minimize-Delay -j RETURN

${MGL} -A OUTPUT -m tos --tos Maximize-Throughput -j MARK --set-mark 0x2

${MGL} -A OUTPUT -m tos --tos Maximize-Throughput -j RETURN

${MGL} -A OUTPUT -m tos --tos Minimize-Cost -j MARK --set-mark 0x3

${MGL} -A OUTPUT -m tos --tos Minimize-Cost -j RETURN

${MGL} -A OUTPUT -j MARK --set-mark 0x3
```

----------

## frostschutz

SFQ queues packets which in turn causes lag. Try without. Then check if your packets really do end up in the right classes at all or not. It's odd for games to be TCP based...

HTB is not particularly useful when it comes to prioritizing things for low-latency. Might try your luck with HFSC there but the parameters are not straightforward.

The simplest scheduler in this regard is PRIO. If you want to make sure your game packets get out first, you could use that; however you risk it starving all other traffic if the game ends up using too much bandwidth. PRIO will happily never send a lower priority packet as long as there is a higher priority one to be sent, so under the right circumstances, connections just die completely.

Then again, downloads are hard to shape no matter what you do... you can drop packets and hope the other side will slow down. Or you can fiddle (dynamically) with TCP windows but I don't know if there's any support for that in Linux by now.

----------

## Akaihiryuu

 *frostschutz wrote:*   

> SFQ queues packets which in turn causes lag. Try without. Then check if your packets really do end up in the right classes at all or not. It's odd for games to be TCP based...
> 
> HTB is not particularly useful when it comes to prioritizing things for low-latency. Might try your luck with HFSC there but the parameters are not straightforward.
> 
> The simplest scheduler in this regard is PRIO. If you want to make sure your game packets get out first, you could use that; however you risk it starving all other traffic if the game ends up using too much bandwidth. PRIO will happily never send a lower priority packet as long as there is a higher priority one to be sent, so under the right circumstances, connections just die completely.

 

Yes, I know SFQ can cause additional latency, which is why I am not using it on the high priority chain.  As far as the TCP thing, I checked with Netstat, and it was not making any UDP connections according to that.  If it does need UDP also...no biggie, I can just add that to my mangle rules.  I'll look into PRIO.  Games don't tend to take a whole lot of bandwidth though, so that shouldn't be an issue.

----------

## Akaihiryuu

Can you give some suggestions about how I can use PRIO for this?  Honestly, I just want to prioritize certain ports, even if it's at the expense of other network traffic.  But I can find very little documentation on PRIO.  I don't need complex traffic shaping, I just want to prevent lag in online games.

EDIT: I found a script someone made to prioritize VOIP stuff using HFSC, just substituting in the ports I want to prioritize for the VOIP ports.  It helps, but games are still hitting 250ms with Steam downloads going, which once again is totally unacceptable.  It needs to absolutely be lower than 100ms, and it's highly preferred that it be lower than 80ms.  I don't care what has to happen to other traffic to achieve this.  As far as I'm concerned, non gaming traffic is completely expendable when games are being played.

----------

## PaulBredbury

See my example for prioritizing uploads.

You need to be absolutely certain that your $UP (what I call $MAX) is definitely less than what the router can handle, otherwise the router becomes the bottleneck, rendering this useless. So reduce it, and do lots of checking, e.g.:

```
watch -n 2 "iptables -t mangle -L -x -v | tail -n +13"
```

----------

## Akaihiryuu

 *PaulBredbury wrote:*   

> See my example for prioritizing uploads.
> 
> You need to be absolutely certain that your $UP (what I call $MAX) is definitely less than what the router can handle, otherwise the router becomes the bottleneck, rendering this useless. So reduce it, and do lots of checking, e.g.:
> 
> ```
> ...

 

I'm trying a different approach.

```
#!/bin/bash

TC="/sbin/tc"

MGL="/sbin/iptables -t mangle"

DEV="eth1"

UP=896

${TC} qdisc del dev ${DEV} root 2> /dev/null

${MGL} -F PREROUTING

${MGL} -F OUTGOING

if [ "$1" = "stop" ]

then

        exit

fi

${TC} qdisc add dev ${DEV} root handle 1: tbf rate ${UP}kbit burst 4k latency 30ms

${TC} qdisc add dev ${DEV} parent 1: handle 10: prio bands 2 priomap 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

${TC} qdisc add dev ${DEV} parent 10:1 handle 100: sfq perturb 10

${TC} qdisc add dev ${DEV} parent 10:2 handle 200: tbf rate $((8 * $UP / 10)) burst 4k latency 30ms

${TC} qdisc add dev ${DEV} parent 200: handle 2000: sfq perturb 10

${TC} filter add dev ${DEV} parent 100: protocol ip prio 1 handle 1 fw classid 100:

${TC} filter add dev ${DEV} parent 2000: protocol ip prio 2 handle 2 fw classid 2000:

${MGL} -A PREROUTING -p icmp -j MARK --set-mark 1

${MGL} -A PREROUTING -p icmp -j RETURN

${MGL} -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 1

${MGL} -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

${MGL} -A PREROUTING -p tcp --dport 1119 -j MARK --set-mark 1

${MGL} -A PREROUTING -p tcp --dport 1119 -j RETURN

${MGL} -A PREROUTING -p tcp --dport 3724 -j MARK --set-mark 1

${MGL} -A PREROUTING -p tcp --dport 3724 -j RETURN

${MGL} -A PREROUTING -j MARK --set-mark 2

${MGL} -A OUTPUT -p icmp -j MARK --set-mark 1

${MGL} -A OUTPUT -p icmp -j RETURN

${MGL} -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 1

${MGL} -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN

${MGL} -A OUTPUT -j MARK --set-mark 2
```

This should have everything defaulting to the second PRIO chain which is rate limited to 80%.  But I want to be able to use iptables to mark things to go in my first PRIO chain (which is not rate limited).  I'm really hoping the tc filter commands I put in will let me mark things with iptables.  I have no idea if I got the syntax of that right though.  If that looks like it will do what I'm intending, I can obviously play around with the UP speed until I get it right.

EDIT: For some reason, this works for exactly 20 seconds, and then all network access stops.  Fortunately I'm not doing anything on eth0 so I can still access the server and turn it off, but I've got no clue why it's doing that.

----------

## trippels

First of all you should really use fq_codel for this issue.

I got good results on my OpenWrt router by using fq_codel in combination with hfsc. 

Also note that iptables mangling doesn't work for incoming traffic.

You'll have to use tc filters directly in that case.

Here's what I use for incoming traffic (rtorrent listens on port 55555):

```

tc filter add dev ifb0 protocol ip parent 1:0 pref 1 u32 match ip protocol 1 0xff classid 1:10

tc filter add dev ifb0 protocol ip parent 1: pref 1 u32 match ip sport 53 0xffff classid 1:10

tc filter add dev ifb0 protocol ip parent 1: pref 2 u32 match ip sport 80 0xffff classid 1:20

tc filter add dev ifb0 protocol ip parent 1: pref 3 u32 match ip dport 55555 0xffff classid 1:40
```

Here are the qdiscs to give you an idea:

```
`--# tc -s qdisc show

qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

 Sent 367693541510 bytes 404816889 pkt (dropped 0, overlimits 0 requeues 11858) 

 backlog 0b 0p requeues 11858 

qdisc hfsc 1: dev br-wan root refcnt 2 default 30 

 Sent 4098913345 bytes 20327126 pkt (dropped 0, overlimits 23868181 requeues 0) 

 backlog 0b 0p requeues 0 

qdisc pfifo 100: dev br-wan parent 1:10 limit 10p

 Sent 12156811 bytes 105772 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

qdisc fq_codel 200: dev br-wan parent 1:20 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 127034716 bytes 1694601 pkt (dropped 6937, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 393 drop_overlimit 0 new_flow_count 246055 ecn_mark 0

  new_flows_len 1 old_flows_len 5

qdisc fq_codel 300: dev br-wan parent 1:30 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 82923200 bytes 280087 pkt (dropped 1066, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 1514 drop_overlimit 0 new_flow_count 100220 ecn_mark 0

  new_flows_len 1 old_flows_len 3

qdisc fq_codel 400: dev br-wan parent 1:40 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 3876798618 bytes 18246666 pkt (dropped 175474, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 1514 drop_overlimit 0 new_flow_count 6731477 ecn_mark 0

  new_flows_len 1 old_flows_len 19

qdisc ingress ffff: dev br-wan parent ffff:fff1 ---------------- 

 Sent 42552299059 bytes 37654627 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

qdisc hfsc 1: dev ifb0 root refcnt 2 default 30 

 Sent 42787815826 bytes 32827265 pkt (dropped 0, overlimits 37789382 requeues 0) 

 backlog 0b 0p requeues 0 

qdisc pfifo 100: dev ifb0 parent 1:10 limit 10p

 Sent 8301490 bytes 45135 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

qdisc fq_codel 200: dev ifb0 parent 1:20 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 256 drop_overlimit 0 new_flow_count 0 ecn_mark 0

  new_flows_len 0 old_flows_len 0

qdisc fq_codel 300: dev ifb0 parent 1:30 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 42779514336 bytes 32782130 pkt (dropped 1431, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 1514 drop_overlimit 0 new_flow_count 10607494 ecn_mark 0

  new_flows_len 0 old_flows_len 1

qdisc fq_codel 400: dev ifb0 parent 1:40 limit 800p flows 1024 quantum 1514 target 5.0ms interval 100.0ms 

 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 

 backlog 0b 0p requeues 0 

  maxpacket 256 drop_overlimit 0 new_flow_count 0 ecn_mark 0

  new_flows_len 0 old_flows_len 0
```

----------

## szatox

AFAIK you can't shape incoming traffic, but you can loop it over virtual interface thus turning it outgoing at some point. It seems you know how to choke expendables there.

----------

## Akaihiryuu

 *szatox wrote:*   

> AFAIK you can't shape incoming traffic, but you can loop it over virtual interface thus turning it outgoing at some point. It seems you know how to choke expendables there.

 

You can *sort of* shape incoming traffic.  You can't directly control it, but you can drop packets if the inbound rate is too fast, and that will cause TCP/IP to slow it down to the rate you specify.  I don't really have any need to do that on my setup though.

----------

## micmac

Hello!

I'm running the following on OpenWrt. It reduces the WAN bandwidth (upload and download) so any buffering is done on the router, not at the provider. It uses tc, not iptables, so it won't interfere with any firewall rules.

I started out with the script that qos-scripts in OpenWrt runs, then changed it so that marking with iptables is not used but instead filters from tc.

The script prioritizes packets I "like" (HTTP, ICMP, small UDP packets, DNS). Everything else gets treated as bulk traffic. Adding your gaming rules should be straightforward.

Even when I max out the connection (FTP or downloading mails with attachments) ping times are good - almost as if there was no load - and HTTP video streaming (newscasts etc.) still works well - streams don't pause to buffer.

```
insmod cls_u32 >&- 2>&-

insmod em_u32 >&- 2>&-

#insmod act_connmark >&- 2>&-

insmod act_mirred >&- 2>&-

insmod sch_ingress >&- 2>&-

#insmod cls_fw >&- 2>&-

insmod sch_hfsc >&- 2>&-

insmod sch_fq_codel >&- 2>&-

ifconfig pppoe-wan up txqueuelen 5 >&- 2>&-

tc qdisc del dev pppoe-wan root >&- 2>&-

#tc qdisc add dev pppoe-wan root handle 1: hfsc default 30

# Use the same line as above except default to the bulk class 1:40

tc qdisc add dev pppoe-wan root handle 1: hfsc default 40

tc class add dev pppoe-wan parent 1: classid 1:1 hfsc sc rate 650kbit ul rate 650kbit

tc class add dev pppoe-wan parent 1:1 classid 1:10 hfsc rt m1 379kbit d 1201us m2 65kbit ls m1 379kbit d 1201us m2 361kbit ul rate 650kbit

tc class add dev pppoe-wan parent 1:1 classid 1:20 hfsc rt m1 345kbit d 3004us m2 325kbit ls m1 345kbit d 3004us m2 180kbit ul rate 650kbit

tc class add dev pppoe-wan parent 1:1 classid 1:30 hfsc ls m1 0kbit d 100000us m2 90kbit ul rate 650kbit

tc class add dev pppoe-wan parent 1:1 classid 1:40 hfsc ls m1 0kbit d 200000us m2 18kbit ul rate 650kbit

tc qdisc add dev pppoe-wan parent 1:10 handle 100: fq_codel

tc qdisc add dev pppoe-wan parent 1:20 handle 200: fq_codel

tc qdisc add dev pppoe-wan parent 1:30 handle 300: fq_codel

tc qdisc add dev pppoe-wan parent 1:40 handle 400: fq_codel

#tc filter add dev pppoe-wan parent 1: prio 1 protocol ip handle 1/0xff fw flowid 1:10

#tc filter add dev pppoe-wan parent 1: prio 2 protocol ip handle 2/0xff fw flowid 1:20

#tc filter add dev pppoe-wan parent 1: prio 3 protocol ip handle 3/0xff fw flowid 1:30

#tc filter add dev pppoe-wan parent 1: prio 4 protocol ip handle 4/0xff fw flowid 1:40

ifconfig ifb0 up txqueuelen 5 >&- 2>&-

tc qdisc del dev ifb0 root >&- 2>&-

#tc qdisc add dev ifb0 root handle 1: hfsc default 30

# Use the same line as above except default to the bulk class 1:40

tc qdisc add dev ifb0 root handle 1: hfsc default 40

tc class add dev ifb0 parent 1: classid 1:1 hfsc sc rate 8500kbit ul rate 8500kbit

tc qdisc del dev pppoe-wan ingress >&- 2>&-

tc qdisc add dev pppoe-wan ingress

#tc filter add dev pppoe-wan parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb0

# Use the same line as above except remove the connmark action

tc filter add dev pppoe-wan parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

tc class add dev ifb0 parent 1:1 classid 1:10 hfsc rt m1 1926kbit d 229us m2 850kbit ls m1 1926kbit d 229us m2 4722kbit ul rate 8500kbit

tc class add dev ifb0 parent 1:1 classid 1:20 hfsc rt m1 4429kbit d 229us m2 4250kbit ls m1 4429kbit d 229us m2 2361kbit ul rate 8500kbit

tc class add dev ifb0 parent 1:1 classid 1:30 hfsc ls m1 0kbit d 100000us m2 1180kbit ul rate 8500kbit

tc class add dev ifb0 parent 1:1 classid 1:40 hfsc ls m1 0kbit d 200000us m2 236kbit ul rate 8500kbit

tc qdisc add dev ifb0 parent 1:10 handle 100: fq_codel

tc qdisc add dev ifb0 parent 1:20 handle 200: fq_codel

tc qdisc add dev ifb0 parent 1:30 handle 300: fq_codel

tc qdisc add dev ifb0 parent 1:40 handle 400: fq_codel

#tc filter add dev ifb0 parent 1: prio 1 protocol ip handle 1/0xff fw flowid 1:10

#tc filter add dev ifb0 parent 1: prio 2 protocol ip handle 2/0xff fw flowid 1:20

#tc filter add dev ifb0 parent 1: prio 3 protocol ip handle 3/0xff fw flowid 1:30

#tc filter add dev ifb0 parent 1: prio 4 protocol ip handle 4/0xff fw flowid 1:40

# Filtering

# ICMP will be put into the priority class 1:10; we can use a tc shorthand for

# this

# Note: The tc shorthands assume a constant IPv4 header length; for stuff that

# is within the first 20 Bytes of the IPv4 header, e.g. the IP protocol, this

# works, but for stuff that is behind the first 20 Bytes (e.g.  TCP/UDP ports)

# we better use more complex filters just to be safe (and for that we'll need

# hash tables and handles) 

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 match ip protocol 1 0xff classid 1:10

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 match ip protocol 1 0xff classid 1:10

# Hash Tables (ht) need to be created before they can be used

# Here is the ht for small TCP packets; use it for ACK and SYN filtering on

# select packets

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 handle 1: u32 divisor 1

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 handle 1: u32 divisor 1

# Here is the ht for TCP packets that are either bigger than 128 Bytes or come

# out of ht 1: unclassified

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 handle 2: u32 divisor 1

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 handle 2: u32 divisor 1

# Here is the ht for UDP packets:

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 handle 3: u32 divisor 1

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 handle 3: u32 divisor 1

# Now, this is copied & pasted from "cls_u32.txt" (found it online); according

# to "russell" "it does calculate the position of the second header in an IP

# packet"; this means that the *next* filter, which we *jump* to using "link",

# will not start at the IP header of the packet, but instead it will start at

# the next protocol's header, i.e. the TCP or UDP header.

# Put all small TCP packets (up to 128 Bytes) into ht 1: for further filtering

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 link 1: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 6 0xff match u16 0x0000 0xff80 at 2

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 link 1: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 6 0xff match u16 0x0000 0xff80 at 2

# Next we put all bigger (and small but unclassified) TCP packets into ht 2:

# for further filtering

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 link 2: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 6 0xff

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 link 2: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 6 0xff

# Same for UDP (protocol 17); put them into ht 3:

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 link 3: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 17 0xff

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 link 3: offset at 0 mask 0f00 shift 6 plus 0 eat match ip protocol 17 0xff

# Now we add specific filters

# Filters for ht 1:0; ACK and SYN packets from HTTP and HTTPS traffic are put

# into class 1:10

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 80 0xffff match u8 0x10 0xff at 13

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 80 0xffff match u8 0x02 0xff at 13

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 443 0xffff match u8 0x10 0xff at 13

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 443 0xffff match u8 0x02 0xff at 13

# RTMP (TCP/port 1935):

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 1935 0xffff match u8 0x10 0xff at 13

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp dst 1935 0xffff match u8 0x02 0xff at 13

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 80 0xffff match u8 0x10 0xff at 13

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 80 0xffff match u8 0x02 0xff at 13

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 443 0xffff match u8 0x10 0xff at 13

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 443 0xffff match u8 0x02 0xff at 13

# RTMP

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 1935 0xffff match u8 0x10 0xff at 13

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 1:0 match tcp src 1935 0xffff match u8 0x02 0xff at 13

# Filters for ht 2:0; HTTP and HTTPS are put into class 1:30

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp dst 80 0xffff

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp dst 443 0xffff

# RTMP

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp dst 1935 0xffff

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp src 80 0xffff

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp src 443 0xffff

# RTMP

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:30 ht 2:0 match tcp src 1935 0xffff

# Now UDP

# Filters for ht 3:0, DNS traffic is put into the priority class 1:10:

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 classid 1:10 ht 3:0 match udp dst 53 0xffff

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 classid 1:10 ht 3:0 match udp src 53 0xffff

# Last but not least: put all yet unclassified UDP packets up to 500 bytes into

# the express class 1:20:

# Egress

tc filter add dev pppoe-wan parent 1: protocol ip prio 1 u32 match ip protocol 17 0xff match u16 0x0000 0xfe0c at 2 classid 1:20

# Ingress

tc filter add dev ifb0      parent 1: protocol ip prio 1 u32 match ip protocol 17 0xff match u16 0x0000 0xfe0c at 2 classid 1:20

#insmod ipt_multiport >&- 2>&-

#insmod ipt_CONNMARK >&- 2>&-

#insmod ipt_length >&- 2>&-

#iptables -t mangle -N qos_Default >&- 2>&-

#iptables -t mangle -N qos_Default_ct >&- 2>&-

#iptables -t mangle -A qos_Default_ct -m mark --mark 0/0xff -m tcp -p tcp -m multiport --ports 22,53 -j MARK --set-mark 1/0xff

#iptables -t mangle -A qos_Default_ct -m mark --mark 0/0xff -p udp -m udp -m multiport --ports 22,53 -j MARK --set-mark 1/0xff

#iptables -t mangle -A qos_Default_ct -j CONNMARK --save-mark --mask 0xff

#iptables -t mangle -A qos_Default -j CONNMARK --restore-mark --mask 0xff

#iptables -t mangle -A qos_Default -m mark --mark 0/0xff -j qos_Default_ct

# I didn't try to implement the following two rules with u32

#iptables -t mangle -A qos_Default -m mark --mark 1/0xff -m length --length 400: -j MARK --set-mark 0/0xff

#iptables -t mangle -A qos_Default -m mark --mark 2/0xff -m length --length 800: -j MARK --set-mark 0/0xff

#iptables -t mangle -A qos_Default -m mark --mark 0/0xff -p udp -m length --length :500 -j MARK --set-mark 2/0xff

#iptables -t mangle -A qos_Default -p icmp -j MARK --set-mark 1/0xff

#iptables -t mangle -A qos_Default -m mark --mark 0/0xff -p tcp -m tcp -m multiport --ports 20,21,465,563,873,995 -j MARK --set-mark 4/0xff

#iptables -t mangle -A qos_Default -p tcp -m length --length :128 -m mark ! --mark 4/0xff -m tcp --tcp-flags ALL SYN -j MARK --set-mark 1/0xff

#iptables -t mangle -A qos_Default -p tcp -m length --length :128 -m mark ! --mark 4/0xff -m tcp --tcp-flags ALL ACK -j MARK --set-mark 1/0xff

#iptables -t mangle -A OUTPUT -o pppoe-wan -j qos_Default

#iptables -t mangle -A FORWARD -o pppoe-wan -j qos_Default
```

----------

