Previous articles have discussed the configuration on a Mikrotik Router as I have experienced it -- the initial configuration and succeeding LAN provisions, like DHCP and DNS. I have had this configuration working for me and had tested it to work.
The concept of QoS in this article is "Q-on-Q" in the Mikrotik linggo. There are a lot of ways to configure this and mine is not the only way. I have not tested the other configurations out there. This is the first one I have tested as this seems to be the easiest to implement and test (at least in my point of view).
There are two (2) components to this -- a queue tree and sets of mangle rules.
Queue Tree. The best analogy I could come up with for the concept of queue trees is the highway. Have a separate lane for faster and higher priority vehicles and leave the rest for vehicles that require roads to get through. The difference is QoS only kicks in when congestion happens. And in order for the configuration to kick in, at about 90% bandwidth utilization, I create an artificial congestion for this configuration to start to take control in anticipation of the real world actual congestion.
I was given an internet bandwidth of 20MBps up and 20MBps down to play with. Following the concept above, I created two (2) queues -- one queue for critical traffic with a CIR of 3MBps and another for best effort queue with a CIR of 15MBps. In effect, the artificial congestion at 90% utilization of 18MBps aggregated at the parent queue. QoS settings take over when bandwidth utilization for those queues are saturated as well as on their parent queues. The committed information rate or CIR (limit-at value) for that specific queue assures it that bandwidth, if required. Bandwidth for a particular queue that is unused can be "borrowed" by other queues.
I mirrored the same configs for both upload queues and download queues since my bandwidth is symmetrical. The queue tree configuration follows below.
/queue tree add comment="----- uploads -----" max-limit=25M name=UPLDQ parent=global \ priority=1 queue=ethernet-default add comment="----- low priority -----" limit-at=15M max-limit=25M name=\ UPLD_BEFF parent=UPLDQ priority=5 queue=ethernet-default add comment="---- high priority -----" limit-at=3M max-limit=25M name=\ UPLD_CRIT parent=UPLDQ priority=1 queue=ethernet-default add name=upld_pr1_crit packet-mark=upld_pr1_crit parent=UPLD_CRIT \ priority=1 queue=ethernet-default add name=upld_pr2_crit packet-mark=upld_pr2_crit parent=UPLD_CRIT \ priority=2 queue=ethernet-default add name=upld_pr7_crit packet-mark=upld_pr7_crit parent=UPLD_CRIT \ priority=7 queue=ethernet-default add name=upld_pr1_beff packet-mark=upld_pr1_beff parent=UPLD_BEFF \ priority=1 queue=ethernet-default add name=upld_pr2_beff packet-mark=upld_pr2_beff parent=UPLD_BEFF \ priority=2 queue=ethernet-default add name=upld_pr4_beff packet-mark=upld_pr4_beff parent=UPLD_BEFF \ priority=4 queue=ethernet-default add name=upld_pr6_beff packet-mark=upld_pr6_beff parent=UPLD_BEFF \ priority=6 queue=ethernet-default add name=upld_pr7_beff packet-mark=upld_pr7_beff parent=UPLD_BEFF \ priority=7 queue=ethernet-default add name=upld_pr8_beff packet-mark=upld_pr8_beff parent=UPLD_BEFF \ queue=ethernet-default add max-limit=6M name=upl_pr8_ratelimited packet-mark=upld_pr8_lmtd \ parent=UPLD_BEFF queue=ethernet-default add comment="----- downloads -----" max-limit=25M name=DNLDQ \ parent=global priority=1 queue=ethernet-default add comment="----- low priority ----" limit-at=15M max-limit=25M \ name=DNLD_BEFF parent=DNLDQ priority=5 queue=ethernet-default add comment="---- high priority ----" limit-at=3M max-limit=25M \ name=DNLD_CRIT parent=DNLDQ priority=1 queue=ethernet-default add name=dnld_pr1_crit packet-mark=dnld_pr1_crit parent=DNLD_CRIT priority=1 queue=ethernet-default add name=dnld_pr2_crit packet-mark=dnld_pr2_crit parent=DNLD_CRIT \ priority=2 queue=ethernet-default add name=dnld_pr7_crit packet-mark=dnld_pr7_crit parent=DNLD_CRIT \ priority=7 queue=ethernet-default add name=dnld_pr1_beff packet-mark=dnld_pr1_beff parent=DNLD_BEFF \ priority=1 queue=ethernet-default add name=dnld_pr2_beff packet-mark=dnld_pr2_beff parent=DNLD_BEFF \ priority=2 queue=ethernet-default add name=dnld_pr4_beff packet-mark=dnld_pr4_beff parent=DNLD_BEFF \ priority=4 queue=ethernet-default add name=dnld_pr6_beff packet-mark=dnld_pr6_beff parent=DNLD_BEFF \ priority=6 queue=ethernet-default add name=dnld_pr7_beff packet-mark=dnld_pr7_beff parent=DNLD_BEFF \ priority=7 queue=ethernet-default add name=dnld_pr8_beff packet-mark=dnld_pr8_beff parent=DNLD_BEFF \ queue=ethernet-default add max-limit=6M name=dnld_pr8_lmtd packet-mark=dnld_pr8_lmtd \ parent=DNLD_BEFF queue=ethernet-default
As seen from above, I adopted a naming convention for the queues (and their corresponding packet-marks). Packet-marks take the name of the queue names; whereas queue names have a specific naming concatenated from their function (dnld for download; upld for upload), priority (pr1 for priority 1 and so on..) and parent queue (beff for best effort; crit for critical or high priority queue). It helps me identify the queue assignment when classifying packets based on the kind of traffic they belong to).
Mangle Rules. Now that the queues are made, let's classify traffic by marking the packets. These packet marks or tags identify them as to which particular queue they would go to. Do you see now how these two components go hand in hand?
Note that these packet marks are only applicable within the Mikrotik router. The order of the rules are based on traffic volume. This gives me efficiency as the rules are evaluated from top to bottom. When the top rules are hit first, rules further down need no execution. The procedure below moves everything to Priority 4, and other packets are reclassified to lower or higher priority from that baseline. By default all packets have Priority 8. Below are the mangle rules I use.
/ip firewall mangle add action=mark-connection chain=prerouting comment=">>>>> INTRANET TRAFFIC" \ disabled=yes new-connection-mark=no-mark add action=jump chain=forward dst-address=10.0.0.0/8 jump-target=local-net \ src-address=10.0.0.0/8 add action=mark-connection chain=local-net new-connection-mark=local-net \ passthrough=yes add action=fasttrack-connection chain=local-net connection-mark=local-net add action=accept chain=local-net connection-mark=local-net add action=return chain=local-net add action=accept chain=prerouting comment=">>>>> SEPARATOR (DO NOT ENABLE)" \ disabled=yes add action=mark-packet chain=prerouting in-interface=all-ethernet \ new-packet-mark=dnld_pr4_beff add action=mark-packet chain=postrouting new-packet-mark=upld_pr4_beff \ out-interface=all-ethernet add action=accept chain=prerouting comment=">>>>> SEPARATOR (DO NOT ENABLE)" \ disabled=yes add action=jump chain=prerouting comment="NEW CONNECTIONS" connection-state=\ new in-interface=all-ethernet jump-target=crit-dnld-pr1 add action=jump chain=postrouting connection-state=new jump-target=\ crit-upld-pr1 out-interface=all-ethernet add action=jump chain=prerouting jump-target=crit-dnld-pr1 port=53 protocol=udp add action=jump chain=prerouting comment="BIG BYTES (IN)" connection-bytes=\ 2500000-0 connection-rate=2500-1G in-interface=ether1 jump-target=\ beff-bulk-download protocol=tcp add action=mark-packet chain=beff-bulk-download new-packet-mark=\ dnld_pr8_beff passthrough=no add action=return chain=beff-bulk-download add action=jump chain=postrouting comment="BIG BYTES (OUT)" connection-bytes=\ 2500000-0 connection-rate=2500-1G jump-target=beff-bulk-upload \ out-interface=ether1 protocol=tcp add action=mark-packet chain=beff-bulk-upload new-packet-mark=\ upld_pr8_beff passthrough=no add action=return chain=beff-bulk-upload add action=jump chain=prerouting comment="WEB TRAFFIC - INBOUND" \ in-interface=ether1 jump-target=beff-http-down port=80,443 protocol=tcp add action=jump chain=prerouting in-interface=ether1 jump-target=\ beff-http-down port=80,443 protocol=udp add action=jump chain=beff-http-down connection-bytes=2500000-0 \ jump-target=beff-bulk-download protocol=tcp add action=mark-packet chain=beff-http-down new-packet-mark=\ dnld_pr6_beff passthrough=no add action=return chain=beff-http-down add action=jump chain=prerouting comment="SYN PACKETS" in-interface=ether1 \ jump-target=crit-dnld-pr2 protocol=tcp tcp-flags=syn add action=jump chain=postrouting jump-target=crit-upld-pr2 out-interface=\ ether1 protocol=tcp tcp-flags=syn add action=jump chain=forward comment="PR1 - RTP conn/packet" \ jump-target=crit-dnld-pr1 port=10000-20000 protocol=udp add action=jump chain=forward comment="PR1 -- FACETIME" jump-target=\ crit-dnld-pr2 port=5223,4080,3478 protocol=tcp add action=mark-connection chain=forward comment="DSCP 46 (VoIP)" \ connection-mark=no-mark dscp=46 new-connection-mark=VoIP-conn \ passthrough=yes add action=jump chain=prerouting comment="PR2 -- SIP (VoIP)" jump-target=\ crit-dnld-pr1 port=5060-5061 protocol=tcp add action=jump chain=prerouting jump-target=crit-dnld-pr1 port=5060-5061 \ protocol=udp add action=jump chain=forward comment="PR8 -- P2P conn/packet" jump-target=\ beff-p2p p2p=all-p2p src-address=10.0.0.0/8 add action=mark-packet chain=beff-p2p new-packet-mark=dnld_pr8_lmtd \ passthrough=no add action=return chain=beff-p2p add action=accept chain=prerouting comment=">>>>> SEPARATOR (DO NOT ENABLE)" \ disabled=yes add action=mark-packet chain=crit-dnld-pr1 new-packet-mark=dnld_pr1_crit \ passthrough=no add action=return chain=crit-dnld-pr1 add action=mark-packet chain=crit-dnld-pr2 new-packet-mark=dnld_pr2_crit \ passthrough=no add action=return chain=crit-dnld-pr2 add action=mark-packet chain=crit-upld-pr1 new-packet-mark=upld_pr1_crit \ passthrough=no add action=return chain=crit-upld-pr1 add action=mark-packet chain=crit-upld-pr2 new-packet-mark=upld_pr2_crit \ passthrough=no add action=return chain=crit-upld-pr2
With the configuration above, packets are re-classified according to traffic type. Even if someone is browsing the web and somebody else is uploading files through popular cloud storage like Dropbox or Google Drive, VoIP calls are still as clear as they need to be. My internal customers are satisfied with the speed of their internet and cloud experience.
RELATED: LAN Configuration of a Mikrotik Virtual Router
If you find something amiss in my configuration or if you found a way to improve it, I would appreciate some feedback. Hope this helps.