The queuing can be used for limiting the data rate for certain IP addresses, protocols or ports. The queuing is performed for packets leaving the router through a real interface. It means that the queues should always be configured on the outgoing interface regarding the traffic flow. There are two additional virtual interfaces which are used to limit all the traffic coming to (global-in) or leaving (global-out) the router regardless of physical interface.
Stochastic Fair Queuing (SFQ) cannot limit traffic at all. Its main idea is to equalize sessions (not computer traffic, but session traffic, it is sometimes mentioned as SFQ drawback) when your link is completely full. It works in round-robin fashion, giving each session a chance to send sfq-allot bytes. Its algorithm can distinguish only 1024 sessions, and that is why several sessions can be treated as one. Each sfq-perturb seconds it drops internal table mixing all the connections and creates a new table. As it is very fast, you may want to use it as a child queue.
The normal behavior of queues is called tail-drop. Tail-drop works by queuing up to a certain amount, then dropping all traffic that 'spills over'. Random Early Detection (RED is also known as Random Early Drop because it actually works that way) statistically drops packets from flows before it reaches its hard limit. This causes a congested backbone link to slow more gracefully. It starts dropping packets when threshold reaches red-min-threshold mark randomly with increasing probability as threshold rising. Maximum probability is used when traffic reaches red-max-threshold mark. Then packets are simply thrown away. burst parameter is the number of packets allowed to burst through the interface when the link is empty (generally value of (min+min+max)/3 works fine). The minimum value that can be used here is equal to the value of red-min-threshold.
Each queue represents a virtual interface with the allowed data rate. It can be borrowed from sibling queues (queues that are children of one queue) when max-limit is greater than limit-at. If so, the queue would use over the allocated data rate whenever possible. Only when other queues are getting too long and a connection is not to be satisfied, then the borrowing queues would be limited at their allocated data rate.
When a parent is allowed to send some amount of traffic, it asks its inner queues in order of priority (priorities are processed one after another, from 1 to 8, where 1 means the highest priority). When the a queue reached its limit-at value, its priority is not to be taken in account, such a queue will be less-prioritative than the ones not reached this limit.
MikroTik RouterOS may be used to provide CIR and MIR with some contention level and priority. Here we will talk in terms of queues (which represent either real or virtual interface) and classes (children of a queue; each class has an another queue attached to it).
[admin@MikroTik] queue type> add name=CUSTOMER-def kind=red \ \... red-min-threshold=0 red-burst=0 [admin@MikroTik] queue type> print 0 name=default kind=none bfifo-limit=15000 pfifo-limit=10 red-limit=60 red-min-threshold=10 red-max-threshold=50 red-burst=20 sfq-perturb=5 sfq-allot=1514 1 name=ethernet-default kind=none bfifo-limit=15000 pfifo-limit=10 red-limit=60 red-min-threshold=10 red-max-threshold=50 red-burst=20 sfq-perturb=5 sfq-allot=1514 2 name=wireless-default kind=sfq bfifo-limit=15000 pfifo-limit=10 red-limit=60 red-min-threshold=10 red-max-threshold=50 red-burst=20 sfq-perturb=5 sfq-allot=1514 3 name=synchronous-default kind=red bfifo-limit=15000 pfifo-limit=10 red-limit=60 red-min-threshold=10 red-max-threshold=50 red-burst=20 sfq-perturb=5 sfq-allot=1514 4 name=CUSTOMER-def kind=red bfifo-limit=15000 pfifo-limit=10 red-limit=60 red-min-threshold=0 red-max-threshold=50 red-burst=0 sfq-perturb=5 sfq-allot=1514 [admin@MikroTik] queue type>
[admin@MikroTik] queue interface> print # INTERFACE QUEUE 0 ether1 default 1 prism1 default [admin@MikroTik] queue interface> set prism1 queue=wireless-default [admin@MikroTik] queue interface> print # INTERFACE QUEUE 0 ether1 default 1 prism1 wireless-default [admin@MikroTik] queue interface>
Simple queues are applied before queue trees.
Queue rules are processed in the order they appear in the list. If some packet matches the queue rule, then the queuing mechanism specified in that rule is applied to it, and no more rules are processed for that packet.
[admin@MikroTik] queue simple> add dst-address=192.168.0.0/24 interface=ether1\ \... max-limit=128000 [admin@MikroTik] queue simple> print Flags: X - disabled, I - invalid, D - dynamic 0 name="queue1" src-address=0.0.0.0/0 dst-address=192.168.0.0/24 interface=ether1 limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue simple> print
To apply queues on flows, the mangle feature should be used first to mark incomming packets.
If you have added a simple queue, it is listed as dynamic one in this list:
Simple queues are applied before queue trees.
[admin@MikroTik] queue simple> print Flags: X - disabled, I - invalid, D - dynamic 0 name="simple queue" src-address=0.0.0.0/0 dst-address=192.168.0.0/24 interface=ether1 limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue simple> .. tree [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 D name="simple queue" parent=ether1 flow="" limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue tree>
[admin@MikroTik] ip firewall mangle> add action=passthrough mark-flow=abc-http \ \... protocol=tcp src-port=80 [admin@MikroTik] ip firewall mangle> print Flags: X - disabled, I - invalid 0 src-address=0.0.0.0/0:80 in-interface=all dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=passthrough mark-flow=abc-http tcp-mss=dont-change [admin@MikroTik] ip firewall mangle>You can add queue using the /queue tree add command:
[admin@MikroTik] queue tree> add name=HTTP parent=ether1 flow=abc-http \ max-limit=128000 [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 D name="simple queue" parent=ether1 flow="" limit-at=0 queue=default priority=8 max-limit=128000 1 name="HTTP" parent=ether1 flow="abc-http" limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue tree>
Assume we want to emulate a 128k download and 64k upload line connecting IP network 192.168.0.0/24. The network is served through the Local interface of customer's router. The basic network setup is in the following diagram:
The IP addresses and routes of the MikroTik router are as follows:
[admin@MikroTik] > ip address print Flags: X - disabled, I - invalid, D - dynamic # ADDRESS NETWORK BROADCAST INTERFACE 0 10.0.0.217/24 10.0.0.217 10.0.0.255 Public 1 192.168.0.254/24 192.168.0.0 192.168.0.255 Local [admin@MikroTik] > ip route print Flags: X - disabled, I - invalid, D - dynamic, J - rejected, C - connect, S - static, R - rip, O - ospf, B - bgp # DST-ADDRESS G GATEWAY DISTANCE INTERFACE 0 S 0.0.0.0/0 r 10.0.0.1 1 Public 1 DC 192.168.0.0/24 r 0.0.0.0 0 Local 2 DC 10.0.0.0/24 r 0.0.0.0 0 Public [admin@MikroTik] >
Assume you want to limit the data rate to 128kbps on downloads and 64kbps on uploads for all hosts on the LAN. Data rate limitation is done by applying queues for outgoing interfaces regarding the traffic flow. It is enough to add two queues at the MikroTik router:
[admin@MikroTik] queue simple> add name=Down interface Local max-limit 128000 [admin@MikroTik] queue simple> add name=UP interface Public max-limit 64000 [admin@MikroTik] queue simple> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Down" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Local limit-at=0 queue=default priority=8 max-limit=128000 1 name="UP" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Public limit-at=0 queue=default priority=8 max-limit=64000 [admin@MikroTik] queue simple> .. tree print Flags: X - disabled, I - invalid, D - dynamic 0 D name="Down" parent=Local flow="" limit-at=0 queue=default priority=8 max-limit=128000 1 D name="UP" parent=Public flow="" limit-at=0 queue=default priority=8 max-limit=64000 [admin@MikroTik] queue simple>
Leave all other parameters as set by default. The limit is approximately 128kbps going to the LAN and 64kbps leaving the client's LAN. Please note, that the queues have been added for the outgoing interfaces regarding the traffic flow.
To monitor the traffic flow through the interface while doing file transfer, use the /interface monitor-traffic command:
[admin@MikroTik] interface> monitor-traffic Public once received-packets-per-second: 9 received-bits-per-second: 4.32kbps sent-packets-per-second: 6 sent-bits-per-second: 65.58kbps [admin@MikroTik] interface> monitor-traffic Public once received-packets-per-second: 7 received-bits-per-second: 3.36kbps sent-packets-per-second: 10 sent-bits-per-second: 65.15kbps [admin@MikroTik] interface> monitor-traffic Public once received-packets-per-second: 11 received-bits-per-second: 5.66kbps sent-packets-per-second: 7 sent-bits-per-second: 52.70kbps [admin@MikroTik] interface>
If you want to exclude the server from being limited, add two queues for it with max-limit=0 (no limit) and move them to the top:
[admin@MikroTik] queue simple> add name=Serv_D interface=Local \ \... dst-address=192.168.0.17/32 max-limit=0 [admin@MikroTik] queue simple> add name=Serv_U interface Public \ \... src-address=192.168.0.17/32 max-limit=0 [admin@MikroTik] queue simple> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Down" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Local limit-at=0 queue=default priority=8 max-limit=128000 1 name="UP" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Public limit-at=0 queue=default priority=8 max-limit=64000 2 name="Serv_D" src-address=0.0.0.0/0 dst-address=192.168.0.17/32 interface=Local limit-at=0 queue=default priority=8 max-limit=0 3 name="Serv_U" src-address=192.168.0.17/32 dst-address=0.0.0.0/0 interface=Public limit-at=0 queue=default priority=8 max-limit=0 [admin@MikroTik] queue simple> move 2 0 [admin@MikroTik] queue simple> move 3 1 [admin@MikroTik] queue simple> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Serv_D" src-address=0.0.0.0/0 dst-address=192.168.0.17/32 interface=Local limit-at=0 queue=default priority=8 max-limit=0 1 name="Serv_U" src-address=192.168.0.17/32 dst-address=0.0.0.0/0 interface=Public limit-at=0 queue=default priority=8 max-limit=0 2 name="Down" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Local limit-at=0 queue=default priority=8 max-limit=128000 3 name="UP" src-address=0.0.0.0/0 dst-address=0.0.0.0/0 interface=Public limit-at=0 queue=default priority=8 max-limit=64000 [admin@MikroTik] queue simple>
If you use simple queues, as in the previous example, the queuing rule for incoming traffic should match the customer's local addresses, whereas the rule for outgoing traffic should match the router's external address as the source address. The previous example would work fine, but you cannot exclude the server from being limited.
To apply specific queuing for the server, use /ip firewall mangle to mark the packets originated from the server:
[admin@MikroTik] ip firewall mangle> add src-address=192.168.0.17/32 \ \... action=passthrough mark-flow=Serv_Up [admin@MikroTik] ip firewall mangle> add in-interface=Local action=passthrough \ \... mark-flow=Local-all [admin@MikroTik] ip firewall mangle> print Flags: X - disabled, I - invalid 0 src-address=192.168.0.17/32:0-65535 in-interface=all dst-address=0.0.0.0/0:0-65535 protocol=all tcp-options=any icmp-options=any:any src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=passthrough mark-flow=Serv_Up tcp-mss=dont-change 1 src-address=0.0.0.0/0:0-65535 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=all tcp-options=any icmp-options=any:any src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=passthrough mark-flow=Local-all tcp-mss=dont-change [admin@MikroTik] ip firewall mangle>
Add a queue to the queue tree, which uses the flow mark:
[admin@MikroTik] queue tree> add name=Server parent=Public flow=Serv_Up [admin@MikroTik] queue tree> add name=Workst parent=Public flow=Local-all \ \... max-limit=64000 [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 name=Server parent=Public flow=Serv_Up limit-at=0 queue=default priority=8 max-limit=0 1 name=Workst parent=Public flow=Local-all limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue tree>
Thus, we used queue trees for limiting the upload. Use the same simple queues as in the previous example for limiting the download.
Assume we want to emulate a 128k download and 64k upload line connecting IP network 192.168.0.0/24 as in the previous examples. But if these speeds are the best that you can get from your Internet connection, you may want to guarantee certain speeds to the 192.168.0.17 server so that your customers could download from and upload to this server with the speeds not dependent on the other traffic using the same channel (for example, we will guarantee this server the minimum data rate of 32k for each flow direction).
First of all, you should limit the interface speed:
[admin@MikroTik] queue tree> add name=Up parent=Public max-limit=64000 [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Up" parent=Public flow="" limit-at=0 queue=default priority=8 max-limit=64000 [admin@MikroTik] queue tree>Next, mark the traffic from the FTP server. We will mark only TCP ports 20-21 because these ports are used to send and receive FTP data and control messages.
[admin@MikroTik] ip firewall mangle> add src-address=192.168.0.17/32:20-21 \ \... protocol=tcp mark-flow=Server_Up in-interface=Local [admin@MikroTik] ip firewall mangle> print Flags: X - disabled, I - invalid, D - dynamic 0 src-address=192.168.0.17/32:20-21 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Server_Up tcp-mss=dont-change [admin@MikroTik] ip firewall mangle>The second mangle rule will match the rest of the traffic from the network:
[admin@MikroTik] ip firewall mangle> add src-address=0.0.0.0/0 \ \... mark-flow=Local_Up in-interface=Local [admin@MikroTik] ip firewall mangle> print Flags: X - disabled, I - invalid, D - dynamic 0 src-address=192.168.0.17/32:20-21 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Server_Up tcp-mss=dont-change 1 src-address=0.0.0.0/0:0-65535 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Local_Up tcp-mss=dont-change [admin@MikroTik] ip firewall mangle>Finally shaping the traffic:
[admin@MikroTik] queue tree> add name=Server_Up parent=Up limit-at=32000 \ \... flow=Server_Up max-limit=64000 priority=7 [admin@MikroTik] queue tree> add name=Local_Up parent=Up limit-at=0 \ \... flow=Local_Up [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Up" parent=Public flow="" limit-at=0 queue=default priority=8 max-limit=64000 1 name="Server_Up" parent=Up flow="Server_Up" limit-at=32000 queue=default priority=7 max-limit=64000 2 name="Local_Up" parent=Up flow="Local_Up" limit-at=0 queue=default priority=8 max-limit=0 [admin@MikroTik] queue tree>Thus, we used queue trees for limiting the upload. The download speed can be limited the same way simply changing the interface names and matching the packets destinated to the server (use 'external' server address if you are using DST-NAT):
[admin@MikroTik] queue tree> add name=Down parent=Local max-limit=128000 [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Up" parent=Public flow="" limit-at=0 queue=default priority=8 max-limit=64000 1 name="Server_Up" parent=Up flow="Server_Up" limit-at=32000 queue=default priority=7 max-limit=64000 2 name="Local_Up" parent=Up flow="Local_Up" limit-at=0 queue=default priority=8 max-limit=0 3 name="Down" parent=Local flow="" limit-at=0 queue=default priority=8 max-limit=128000 [admin@MikroTik] queue tree> /ip firewall mangle [admin@MikroTik] ip firewall mangle> add dst-address=192.168.0.17/32:20-21 \ \... protocol=tcp mark-flow=Server_Down in-interface=Public [admin@MikroTik] ip firewall mangle> add dst-address=0.0.0.0/0 \ \... mark-flow=Local_Down in-interface=Public [admin@MikroTik] ip firewall mangle> print Flags: X - disabled, I - invalid, D - dynamic 0 src-address=192.168.0.17/32:20-21 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Server_Up tcp-mss=dont-change 1 src-address=0.0.0.0/0:0-65535 in-interface=Local dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Local_Up tcp-mss=dont-change 2 src-address=0.0.0.0/0:0-65535 in-interface=Public dst-address=192.168.0.17/32:20-21 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Server_Down tcp-mss=dont-change 3 src-address=0.0.0.0/0:0-65535 in-interface=Public dst-address=0.0.0.0/0:0-65535 protocol=tcp tcp-options=any icmp-options=any:any flow="" src-mac-address=00:00:00:00:00:00 limit-count=0 limit-burst=0 limit-time=0s action=accept mark-flow=Local_Down tcp-mss=dont-change [admin@MikroTik] ip firewall mangle> /queue tree [admin@MikroTik] queue tree> add name=Server_Down parent=Down limit-at=32000 \ \... flow=Server_Down max-limit=128000 priority=7 [admin@MikroTik] queue tree> add name=Local_Down parent=Down limit-at=0 \ \... flow=Local_Down [admin@MikroTik] queue tree> print Flags: X - disabled, I - invalid, D - dynamic 0 name="Up" parent=Public flow="" limit-at=0 queue=default priority=8 max-limit=64000 1 name="Server_Up" parent=Up flow="Server_Up" limit-at=32000 queue=default priority=7 max-limit=64000 2 name="Local_Up" parent=Up flow="Local_Up" limit-at=0 queue=default priority=8 max-limit=0 3 name="Down" parent=Local flow="" limit-at=0 queue=default priority=8 max-limit=128000 4 name="Server_Down" parent=Down flow="Server_Down" limit-at=32000 queue=default priority=7 max-limit=128000 5 name="Local_Down" parent=Down flow="Local_Down" limit-at=0 queue=default priority=8 max-limit=0 [admin@MikroTik] queue tree>