I am new to queueing on the MikroTik and I want to replicate a solution I use on Linux, but do not see yet how to do that.
I want to use MikroTik routers to send traffic over an existing network that has limited-bandwidth pipes.
When sending more traffic than those pipes can carry, they of course drop packets. But I want to make sure that this does not happen to any random packets, but packets are handled with different priority.
For simplicity, I use only 3 priorities: above-normal, normal, and below-normal. Let’s call them high, medium and low.
The idea is that the high prio packets are always sent first, then the medium prio packets in the left-over bandwidth, and the low prio packets in what is then still left.
Most connections are in de medium prio class, but exceptions are things like VoIP in the high prio and RSYNC (for backups) in the low prio.
It is the responsibilty of the network architect to make sure that the bandwidth of the pipes is sufficient for the traffic that routinely has to be carried, so the whole mechanism is only there to set the relative prio between the packet types.
(and not, for example, to put too many customers into an overbooked network)
In the network, the priority of a packet is indicated by the IP DiffServ field. iptables rules in the (Linux) end systems set this value depending on port numbers when the original application cannot do it.
The solution I use in Linux is a queue tree like this:
on top level, a HTB qdisc to shape everything to the rate of the network pipe.
below that, a single PRIO qdisc with 3 bands, to manage the 3 different priority queues
below that, 3 PFIFO qdiscs to serve as buffers for the 3 different packet types.
There are some “tc filter” entries to match the different IP DiffServ (TOS field) values into the 3 different PRIO queues.
In the existing system this happens directly in the tc settings. However, I can do packet marking in the mangle table to set a priority to use here.
What I do not yet see is how to translate this into MikroTik queues. I see no equivalent of the PRIO qdisc. How is one supposed to do this?
I know I can allocate bandwidth in a hierarchical tree of HTB qdiscs, but note I do not really want to subdivide bandwidth here, it is just about priority. There is only a single bandwidth that is to be managed, and the 3 priorities determine what gets sent first.
Use the priority field on queue trees. Create a queue that will be the parent for the tree this queue will have the limitation of bandwidth on your case say 100 mbps. This queue must have its parent either set to the outgoing interface or global htb.
Then create your 3 additional queues setting their parent to the first one. Assign the priorities accordingly, you don’t need to assign bandwidth here. Where lower is higher priority.
Make sure you mark your traffic correctly using mangle rules so each queue can identify the traffic it’ll be serving.
This way in case of congestion, your high priority traffic will get served.
Ok thanks!
I think there was a reason why I did not use HTB priority queues but instead used PRIO queues in the existing system, but I do not remember the exact issue and the config was more complicated in the past. So the reason may no longer be valid.
Will see how it works out…
There is still something that is not very clear to me… there are so many things called “priority” and it is unclear where they all go.
In the “IP Firewall Mangle” table I can use “set priority” and base it on “top 3 bits of DSCP”.
This appears to be exactly what I need and in 1 step: just define 8 priorities from the DSCP value that is already set by the source.
However, where is that “set priority” going? Can’t it be matched in queues anywhere? Or is there a default prio queue that automatically handles those 8 levels?
It appears to be a lot of work to classify packets using 64 rules for 64 different DSCP values when in fact the only thing that matters is the top 3 bits.
It is also strange to have to copy the DSCP values to a packet mark and then again match on that packet mark.
In my existing Linux solution I just match directly on DSCP values on the outgoing packets:
tc filter add dev eth0 parent 2: protocol ip prio 1 u32 match ip tos 0x20 0xe0 flowid 2:3
this matches packets with 0x20 after anding with 0xe0.