QOS for VoIP - Confirmation

Hi everyone,

I am trying to set up QoS to make sure Voice packets have priority in my network for a specific application. I am not sure I am doing everything in the right order but this is what I came up with. What is your opinion regarding this matter? Is there something too much or missing?

Basically I have a list of 6 IP address added in a list (here I just put one as example. I then create the mangle rules: one with TCP protocol (only used for signaling the calls by the app) and one with UDP protocol (used while calling). I then create the queue tree. Let’s say I have 22Mb/s up and down, I take off 10% for security and dedicate 25% of my bandwidth to these packets. I’ll then have 5Mb/s for this app (divided into 4 for the udp and 1 for the tcp protocols, even though I could probably take less for the TCP) and 15Mb/s for the rest. It is connected through ether0 port.
This is what I am doing:

/ip firewall address-list
Add address=xx.xxx.xxx.xxx/xx list=List_IP

/ip firewall mangle
add chain=forward dst-address-list=List_IP protocol=tcp port=5060,5061,5063,5080 action=mark-connection new-connection-mark=Voice-c
add chain=forward src-address-list=List_IP protocol=tcp port=5060,5061,5063,5080 action=mark-connection new-connection-mark=Voice-c
add chain=forward dst-address-list=List_IP protocol=udp port=10000-20000 action=mark-connection new-connection-mark=Voice
add chain=forward src-address-list=List_IP protocol=udp port=10000-20000 action=mark-connection new-connection-mark=Voice
add chain=forward connection-mark=Voice-SIP action=mark-packet new-packet-mark=Voice_c
add chain=forward connection-mark=Voice action=mark-packet new-packet-mark=Voice_P

/queue tree
add limit-at=20Mb max-limit=20Mb name=Up parent=ether0 queue=default
add limit-at=4Mb max-limit=4Mb name=Voice_Up packet-mark=Voice_P parent=Up priority=1 queue=default
add limit-at=1Mb max-limit=1Mb name=Voice_Up packet-mark=Voice_c parent=Up priority=1 queue=default
add name=Rest_Up parent=Up priority=8 queue=default

add limit-at=20Mb max-limit=20Mb name=Down parent=ether0 queue=default
add limit-at=4Mb max-limit=4Mb name=Aircall_Down packet-mark=Voice_P parent=Down priority=1 queue=default
add limit-at=1Mb max-limit=1Mb name=Aircall_Down packet-mark=Voice_c parent=Down priority=1 queue=default
add name=Rest_Down parent=Down priority=8 queue=default

I believe now I have part of my connection dedicated to that specific app. Does that seem correct to you ? One of my biggest misunderstanding here is the position in the chain. I chose forward but I am not sure at all. What should I base my choice on ? I have only this router, all the computers are connected via ethernet.
On a side note, I know that all the packets coming in and out of that application are automatically marked with DSCP tag 46. Could I have done something simpler relying on this ?

Thanks you very much for your help guys!
Cheers

Hey guys,

Can anyone help me on this ? I am really not sure of what I am doing to be honest…
Thanks!

Hi

This could work, but some remarks:

  • only mark connection if connection mark is empty
  • I usually mark packets at the last possible moment in postrouting just before going to interface
  • I wouldn’t separate tcp & udp of voip, they are one application, one will not function without the other, => single voip queue
  • instead of reserving bandwidth, you could also define priorities only → bw will be distributed as available according to prio

And a more general, if the application is doing 46 dscp tagging, a single role in postrouting chain of mangle table would have been enough: if tag 46 → mark packet for voip queue

Hi Sebastia, would you mind to elaborate on above, how do you achieve this?

By specifying additional condition:

/ip firewall mangle
add connection-mark=no-mark action=mark-connection new-connection-mark=...

To goal is not to override some specific logic applied earlier.

Please read through some of the other topics first before requesting a personal course from fellow forum members!
There are topics on how to setup QoS with DSCP which should work fine (you don’t need to prioritize everything coming from a VoIP device, only the voice data).

Gotcha, thank you

Thanks for your answers, it is clearer now!
So since the packets hold DSCP tag 46 already, and if I don’t want to split my bandwidth but just rely on priority, the following will be enough. Am I correct?

/ip firewall mangle
add connection-mark=no-mark chain=postrouting dscp=46 action=mark-packet new-packet-mark=Voice passthrough=no

/queue tree
add max-limit=[90% Download max ligne] name=Down parent=[Connection entrance] queue=default
add name=Voice_D parent=Down priority=1 packet-mark=Voice queue=default
add name=Rest_Down parent=Down priority=8 queue=default

add max-limit=[90% Upload max ligne] name=Up parent=[Connection entrance] queue=default
add name=Voice_U parent=Up priority=1 packet-mark=Voice queue=default
add name=Rest_Up parent=Up priority=8 queue=default

Would it be better to specify in the queue tree that priority 8 is given to packets with no mark, so it doesn’t only split between 46 DSCP tagged packets and the rest and override anything?
Thanks again for your help!

This is the leanest indeed. Just verify that packets coming from internet do have 46 tag set. You can verify that easily based on counts: if they increase for Download-Voice you’re all set.

You must assign “no-mark” to some queue, for you Rest_xx, if you don’t they will bypass queue tree!
I would also recommend to use SFQ or PCQ for “Rest” as queue type.

Fantastic, thank you very much for your help Sebastia!

This is the way to do it, but please understand that you really cannot set the priority on download traffic.
For upload direction this method works perfectly, for download you really are at the mercy of your ISP.

By putting a queue on your internal interface you throttle the speed at which they receive their download
traffic, but it does this by dropping packets that you already received over your internet line, so there already
has been congestion at the ISP end of the line.

How bad it is, depends on the equipment and settings at the ISP. When you have bad luck, they have tuned
everything optimal for speedtesting and they have a large FIFO buffer on the line. With good luck, the buffer
is small and they use “fair queue” or even act upon DSCP to improve VoIP the same way as on your upload.

Thanks for the precision pe1chl.
Just to clarify then, in your opinion it is better not to do anything on download traffic? Is there a risk that setting a queue in the direction would have the opposite effect as the expected one, meaning would cause delay instead of improving this specific voice traffic ?

Yes, when you only do VoIP vs other traffic and no further classification of high/low priority normal traffic that you can limit to very low rates, it is likely that shaping the download traffic does not bring any advantage but does bring some reduction of the normal bandwidth.
Not really an opposite effect, but no improvement either.
Try it first with those rules disabled.
When you observe problems with incoming audio when downloading, it is time to investigate again.
But for upload, this kind of configuration really works! It brings a lot of improvement.

Great, thank you again for your help pe1chl ! Everything is much more clear now!

I do disagree with that statement, and for the following reason:
Bulk of traffic to / from internet is TCP based. TCP is using transmission window for controlling the throughput of the connection, and has an algorithm baked into it to auto-shape the window size for best results, which boils down to (over-simplifying here):

  1. if all is received fine, increase window
    2 if errors occur, back down

With queue on the “download” interface, this second action can be utilised to make any tcp connection scale its bandwidth to within boundaries. By limiting total bandwidth to given value, a reserve bandwidth can be maintained for priority data or for sudden traffic surges. When bandwidth is always available, no buffering will occur at ISP, and low latency can be guaranteed for platforms like VOIP.

So, by reducing the usable bandwidth, we are gaining low latency instead. That is the advantage.

In practice this does not work so well, because TCP implementations today do not focus on this bandwidth control but rather are optimized for best throughput using ridiculously large windows.
Dropping single packets results in fast re-transmit behaviour. This is the same behaviour that makes it break down when packets are not received in sequence.
Also, because you are dropping packets downstream (rather than at the ISP), you require multiple transmissions of the same data over the already overburdened line.

It would be better when the queue would be able to interfere with the TCP window size (advertising a smaller size to the upstream by modification of the ACK packets), but I don’t think it can do that on RouterOS.
The best results are obtained from correct settings at the ISP: fair queueing, small queue, and preferably some priority for DSCP=46 packets.

Based on my and others experience, it works quite well. Download traffic is limited to within limits and low latency is achieved.

There are numerous testimonials to that on this very forum.

@pe1chl
Who said anything about dropping packets? In download queue, we’re shaping traffic, that’s delaying and not dropping.
imho, this is an effective way to keep total tcp throughput under control, leaving room for VOIP traffic