Simple prio traffic control sanity check

Hi there!
So, i'm fooling around with traffic control to understand and learn stuff, and I thought of using a very simple rudimentary scheduler similar to pfifo_fast, but instead of using dscp markings and stuff, it simply separates traffic into two: 1) packets less than 300 bytes go first 2) catch-all

(i'm aware that a flood of small packets on 1 will cause starvation on 2, etc etc)

So, following the example cited here (match acks the hard way): https://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.adv-filter.u32.html I managed to arrive at this:

tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match u16 0x0000 0xfed4 at 2 flowid 1:0
tc filter add dev eth0 protocol all parent 1: prio 2 u32 match u32 0 0 flowid 1:1

The theory being the prio 1 goes to packet length field and checks if its <300 bytes

Yet my test results are inconclusive, which makes me wonder: is this correct? or tc filter has no concept of something being less or more than x bytes?

Thanks, have a nice day.

May I suggest to mark the interesting packets in mangle table and then use that mark to classify them in tc?

1 Like

@trendy Good idea

I had to opkg install iptables-mod-ipopt otherwise the length is not recognized in iptables, and arrived at this:

iptables --table mangle --append PREROUTING --protocol all --match length --length 0:300 --jump MARK --set-mark 1
iptables --table mangle --append PREROUTING --protocol all --match length --length 301:1500 --jump MARK --set-mark 2

tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol all parent 1: prio 1 handle 1 fw flowid 1:0
tc filter add dev eth0 protocol all parent 1: prio 2 handle 2 fw flowid 1:1

But when doing a iperf or speedtest while pinging, in theory ping should be low response time since the smaller packets are being processed first, but in practice I still experience ping spikes

perhaps my syntax is wrong.

Are you pinging from the OpenWrt or some lan host? PREROUTING applies for ingress traffic.

I've managed to spin up a virtual environment to check, it looks like this

                         Proxmox 7.x                        
+----------------------------------------------------------+
|                         OpenWRT 21                       |
|   Debian 10 <------>  LAN        WAN  <------> Internet  |
|   Client              br-lan     eth1                    |
+----------------------------------------------------------+

When applying prio to eth1, and running a speedtest with parallel ping on client, still experience latency spikes. Which makes me believe that its not working, I suspect something is wrong with the syntax or maybe the logic in iptables is wrong (apply somewhere else instead of prerouting maybe?)

I'll read more.

One thing to help you troubleshoot is iptables-save -c -t mangle | grep MARK
At the beginning of the lines you'll have the packet and byte counters. This will verify that packets are marked correctly.

Ok I figured it out

This is what I did

                                                                                                                       
 tc qdisc add dev eth0 root handle 1: prio                                                                             
                   |                                                                                                   
                   |                    -                                                                              
                   +--> tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match u16 0x0000 0xfed4 at 2 flowid 1:0
                   |                                                                                                   
                   |                                                                                                   
                   +--> tc filter add dev eth0 protocol all parent 1: prio 2 u32 match u32 0 0 flowid 1:1              
                                                                                                

And this is what I should have done

  tc qdisc replace dev eth0 root handle 1: prio                                                                                                     
                        |                                                                                                                           
                        |                                                                                                                           
                        +--> tc qdisc add dev eth0 parent 1:1 pfifo                                                                                 
                        |                       |                                                                                                   
                        |                       |                                                                                                   
                        |                       +--> tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match u16 0x0000 0xFE0C at 2 flowid 1:1
                        |                                                                                                                           
                        |                                                                                                                           
                        +--> tc qdisc add dev eth0 parent 1:2 pfifo                                                                                 
                                                |                                                                                                   
                                                |                                                                                                   
                                                +--> tc filter add dev eth0 protocol all parent 1: prio 2 u32 match u32 0 0 flowid 1:2 

So I read on some cisco doc that interactive traffic is around 500 bytes, so I changed that from (300), and tc -s qdisc shows segregation of traffic

So I use a work-conserving pfifo qdisc for the first lane, changed second lane to a non-work conserving fq_codel for the bulk traffic, some tweaks here and there and baby I got a stew going!

Thanks for the help trendy.

1 Like

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.