📜 ⬆️ ⬇️

Mikrotik: Balancing in the CPSU and the observance of speed limits

In this article, I want to share my balancing solution using the Classifier by Network Connections (Per Connection Classificator) and traffic marking for QoS.

Foreword


In the open spaces of Habr and the Internet, I met many implementations of balancing, including PPC, however, in a number of these implementations, not all of course, there were moments of a completely foolish type:

MUM article, though not very recent
Bandwidth-based load-balancing
with failover. The easy way.
/ip firewall address-list add address=1.1.1.0/24 list=Connected add address=2.2.2.0/24 list=Connected add address=192.168.22.0/24 list=Connected add address=192.168.22.0/24 list=LAN /ip firewall mangle add chain=prerouting src-address-list=Connected dst-address-list=Connected action=accept 


Well and besides, connecting it with QoS is not a trivial task.

Introduction to Policy Base Routing


Very briefly: we create additional routes that work for our routing tables. The traffic goes along these routes if the corresponding route tag is hung on it.
')

Routing tables


We will use a recursive route scan in conjunction with an integrated availability checker. So, we will check the liveliness of the route for several purposes:

 /ip route #      ,      add comment="ISP1: Check target1" distance=1 dst-address=77.88.8.8/32 \ gateway=rrrr scope=10 add comment="ISP1: Check target2" distance=1 dst-address=8.8.8.8/32 gateway=\ rrrr scope=10 #   "" ,       \ # ,       , #       "",     add check-gateway=ping comment="ISP1: Virtual route1" distance=2 dst-address=\ 127.1.0.1/32 gateway=77.88.8.8 scope=10 add check-gateway=ping comment="ISP1: Virtual route2" distance=2 dst-address=\ 127.2.0.1/32 gateway=8.8.8.8 scope=10 #         ,  \ # ,  ,      add comment="ISP1: Default route" distance=3 gateway=127.1.0.1 routing-mark=\ ISP1 add comment="ISP1: Default route" distance=3 gateway=127.2.0.1 routing-mark=\ ISP1 #    ISP1    ,     IP, \ #  ,        .  ,  \ #      ;) add comment="ISP1: Neighbor net route" distance=1 dst-address=\ nnnn/n gateway=V-603 pref-src=aaaa routing-mark=ISP1 \ scope=10 #     ,     main,  \ #    failover  ,    \ #     add check-gateway=ping comment="ISP1: Virtual backup route1" distance=2 \ dst-address=127.1.1.1/32 gateway=77.88.8.8 scope=10 add check-gateway=ping comment="ISP1: Virtual backup route2" distance=2 \ dst-address=127.2.1.1/32 gateway=8.8.8.8 scope=10 #        main.    \ # distance   ,      \ #  . add comment="ISP1: Backup Default route" distance=201 gateway=127.1.1.1 add comment="ISP1: Backup Default route" distance=201 gateway=127.2.1.1 #      add comment="ISP2: Check target1" distance=1 dst-address=77.88.8.1/32 \ gateway=RRRR scope=10 add comment="ISP2: Check target2" distance=1 dst-address=8.8.4.4/32 gateway=\ RRRR scope=10 # add check-gateway=ping comment="ISP2: Virtual route1" distance=2 dst-address=\ 127.1.0.2/32 gateway=77.88.8.1 scope=10 add check-gateway=ping comment="ISP2: Virtual route2" distance=2 dst-address=\ 127.2.0.2/32 gateway=8.8.4.4 scope=10 # add comment="ISP2: Default route" distance=3 gateway=127.1.0.2 routing-mark=\ ISP2 add comment="ISP2: Default route" distance=3 gateway=127.2.0.2 routing-mark=\ ISP2 add comment="ISP2: Neighbor net route" distance=1 dst-address=\ NNNN/N gateway=ether2 pref-src=AAAA routing-mark=ISP2 \ scope=10 # add check-gateway=ping comment="ISP2: Virtual backup route1" distance=2 \ dst-address=127.1.1.2/32 gateway=77.88.8.1 scope=10 add check-gateway=ping comment="ISP2: Virtual backup route2" distance=2 \ dst-address=127.2.1.2/32 gateway=8.8.4.4 scope=10 # add comment="ISP2: Backup Default route" distance=202 gateway=127.2.1.2 add comment="ISP2: Backup Default route" distance=202 gateway=127.1.1.2 #           /ip route rule add routing-mark=ISP1 table=ISP1 add routing-mark=ISP2 table=ISP2 add comment=ISP1 src-address=aaaa table=ISP1 add comment=ISP2 src-address=AAAA table=ISP2 

The following script will help us to generate routes:
DHCP route script
 ############################################### :local ISPNum 1 :local rmark "ISP$ISPNum" :global DHCPSpin :local "backup-route-distance" 201 :local "check-target1" "77.88.8.8" :local "check-target2" "77.88.8.8" :local targets 1 ############ use then static ip ####################### :local "server-address" "176.57.73.41" :local "lease-address" "176.57.73.34" :local "interface" "IV-210" :local bound 1 ############################################### :local "route-num" 7 :local TTL 30 :local continue true; :local i 0 :if ( $DHCPSpin !=0 || $DHCPSpin !=1 ) do={ :set DHCPSpin 0 } :if ( $targets = 2 ) do={ :set "route-num" 11 } :if ($bound=1) do={ :local count [/ip route print count-only where comment~"^$rmark"] :if ($count = 0) do={ :while ($continue && $i < $TTL) do={ :if ( $DHCPSpin = 0 ) do={ :set DHCPSpin 1 /ip route add gateway=$"server-address" distance=1 dst-address=$"check-target1" scope=10 comment="$rmark: Check target1" :if ( $targets = 2 ) do={ /ip route add gateway=$"server-address" distance=1 dst-address=$"check-target2" scope=10 comment="$rmark: Check target2" } :local "route-var" [/ip route get [find gateway=$"interface"]] /ip route add gateway=$"interface" distance=1 dst-address=($"route-var"->"dst-address") routing-mark=$rmark scope=10 pref-src=$"lease-address" comment="$rmark: Neighbor net route" /ip route add gateway=$"check-target1" distance=2 dst-address="127.1.0.$ISPNum" scope=10 check-gateway=ping comment="$rmark: Virtual route1" :if ( $targets = 2 ) do={ /ip route add gateway=$"check-target2" distance=2 dst-address="127.2.0.$ISPNum" scope=10 check-gateway=ping comment="$rmark: Virtual route2" } /ip route add gateway=$"check-target1" distance=2 dst-address="127.1.1.$ISPNum" scope=10 check-gateway=ping comment="$rmark: Virtual backup route1" :if ( $targets = 2 ) do={ /ip route add gateway=$"check-target2" distance=2 dst-address="127.2.1.$ISPNum" scope=10 check-gateway=ping comment="$rmark: Virtual backup route2" } /ip route add gateway="127.1.0.$ISPNum" distance=3 routing-mark=$rmark comment="$rmark: Default route" :if ( $targets = 2 ) do={ /ip route add gateway="127.2.0.$ISPNum" distance=3 routing-mark=$rmark comment="$rmark: Default route" } /ip route add gateway="127.1.1.$ISPNum" distance=$"backup-route-distance" comment="$rmark: Backup Default route" :if ( $targets = 2 ) do={ /ip route add gateway="127.2.1.$ISPNum" distance=$"backup-route-distance" comment="$rmark: Backup Default route" } /ip route rule add routing-mark=$rmark table=$rmark comment="$rmark: Route mark rule" /ip route rule add src-address=$"lease-address" table=$rmark comment="$rmark: Src addr rule" :set DHCPSpin 0 :set continue false; } else={ :set i ($i + 1) delay 1 } } } else={ :if ($count = $"route-num") do={ :set i 0 :while ($continue && $i < $TTL) do={ :if ( $DHCPSpin = 0 ) do={ :set DHCPSpin 1 :local test [/ip route find where comment="$rmark: Check target1"] :if ([/ip route get $test gateway] != $"server-address") do={ /ip route set $test gateway=$"server-address" } :if ( $targets = 2 ) do={ :local test [/ip route find where comment="$rmark: Check target2"] :if ([/ip route get $test gateway] != $"server-address") do={ /ip route set $test gateway=$"server-address" } } :local test [/ip route rule find where comment=$rmark] :if ([/ip route rule get $test src-address] != $"lease-address") do={ /ip route rule set $test src-address=$"lease-address" } :local test [/ip route find where comment="$rmark: Neighbor net route"] :local "route-var" [/ip route get [find where gateway=$"interface"]] :if ([/ip route get $test pref-src] != $"lease-address") do={ /ip route set $test pref-src=$"lease-address" } :set DHCPSpin 0 :set continue false; } else={ :set i ($i + 1) delay 1 } } } else={ :error "Multiple routes found" } } } else={ :set i 0 :while ($continue && $i < $TTL) do={ :if ( $DHCPSpin = 0 ) do={ :set DHCPSpin 1 /ip route remove [find comment~"^$rmark"] /ip route rule remove [find comment~"^$rmark"] :set DHCPSpin 0 :set continue false; } else={ :set i ($i + 1) delay 1 } } } 


This script can be used in conjunction with DHCP, if you comment out the variables in the section “use then static ip”

Firewall mangle


Specifying only the routing table will not be enough for balancing, so you need to mark connections and packets in them with labels of our providers (labels are placed in the kernel data structures and do not affect real packets).

When setting up, I recommend grouping interfaces into lists. Even if the interface is one, put it in your personal list. By assigning them to lists for their intended purpose, you simplify the configuration and can make it more portable.

The idea here is quite simple: a new connection coming from the Internet is immediately marked with the label of the provider through which it came, and what is going to go in the direction of the Internet is balanced with PPC or sent to the “nailed” (Nailed) provider in accordance with the criterion.

Next, I will attach scripts that generate a specific part of the configuration. Applying a configuration containing everything at once will be redundant, the scripts will show separate, not duplicate fragments. And to understand the scripts will help these schemes:

The principal (generalized) packet passing scheme in the PreRoute table:

PreRoute (P)

Clickable



Functional diagram, each column represents a separate chain of rules:

PreRoute (F)

Clickable



Forward table schematic concept:

Forward (P)

Clickable



And actually the biggest monster, the Forward table's functional diagram:

Forward (F)

Clickable



Such perversions are needed in particular due to the fact that there is no condition like “ELSE”, and also, there can be only one label on the connection (which is an integer, for convenience, displayed as a name understandable to man). Due to the presence of a heap of QoS classes, and even routes to different providers, I had to implement "function calls with variables in the stack" in the language that is in the RoS packet filter (which is almost no different from Linux and just wrapped up in a different command wrapper). If you implement bit operations with labels, then almost all the perversions above will not be needed!

QoS


If you are looking for a universal solution: it is not. Everyone plans a policy based on the needs of their network. I relied on this article: Borderless Campus 1.0 Design Guide from Cisco, and also moved it not 1 to 1.

The very first, and most not complicated (albeit large), traffic classification script (useless without the others, there is no entry point for traffic):

Classifier
 ############################################### # by RouterOS 6.41 :if ( [/ip firewall layer7-protocol print count-only where name=rtp] = 0) do={ /ip firewall layer7-protocol add name=rtp regexp="^\\x80" } :if ( [/ip firewall layer7-protocol print count-only where name="Multimedia Streaming"] = 0) do={ /ip firewall layer7-protocol add name="Multimedia Streaming" regexp=.youtube.com|.googlevideo.com } :if ( [/ip firewall layer7-protocol print count-only where name="Viber"] = 0) do={ /ip firewall layer7-protocol add name="Viber" regexp="^..([\\x03\\x04\\x0a\\x06\\x08\\x67\\x0b])\$|^..\\x90([\\xef\\x6f\\x64\\xe4])" } /ip firewall mangle add action=mark-connection chain=ClassifyRule comment="Classify as DF" \ new-connection-mark=DF passthrough=yes add action=mark-connection chain=ClassifyRule comment="Classify as CS1" \ new-connection-mark=CS1 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF32 Multimedia Streaming" dst-port=80,443 layer7-protocol=\ "Multimedia Streaming" new-connection-mark=AF32 passthrough=yes protocol=\ tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF32 Multimedia Streaming" dst-port=80,443 layer7-protocol=\ "Multimedia Streaming" new-connection-mark=AF32 passthrough=yes protocol=\ udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF32 Multimedia Streaming" layer7-protocol=\ "Multimedia Streaming" new-connection-mark=AF32 passthrough=yes protocol=\ tcp src-port=80,443 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF32 Multimedia Streaming" layer7-protocol=\ "Multimedia Streaming" new-connection-mark=AF32 passthrough=yes protocol=\ udp src-port=80,443 add action=mark-connection chain=ClassifyRule comment="Classify as EF NTP" \ dst-port=123 new-connection-mark=EF passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as EF NTP" \ new-connection-mark=EF passthrough=yes protocol=udp src-port=123 add action=mark-connection chain=ClassifyRule comment="Classify as EF IAX2" \ dst-port=4569 new-connection-mark=EF passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as EF IAX2" \ new-connection-mark=EF passthrough=yes protocol=udp src-port=4569 add action=jump chain=ClassifyRule comment="Classify as EF RTP voice" \ dst-port=10000-20000 jump-target="RCM-(s)rtp" packet-size=50-210 \ protocol=udp add action=jump chain=ClassifyRule comment="Classify as EF RTP voice" \ jump-target="RCM-(s)rtp" packet-size=50-210 protocol=udp src-port=\ 10000-20000 add action=mark-connection chain="RCM-(s)rtp" comment=\ "Classify as EF RTP voice" layer7-protocol=rtp new-connection-mark=EF \ passthrough=yes add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Viber" dst-port=1024-65535 new-connection-mark=\ AF42 packet-size=12-210 layer7-protocol=Viber connection-mark=CS1 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 RTP Viber" new-connection-mark=AF42 packet-size=\ 12-210 layer7-protocol=Viber connection-mark=CS1 passthrough=yes protocol=udp src-port=1024-65535 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 RTP video" dst-port=10000-20000 new-connection-mark=\ AF42 packet-size=211-65535 layer7-protocol=rtp connection-mark=CS1 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 RTP video" new-connection-mark=AF42 packet-size=\ 211-65535 layer7-protocol=rtp connection-mark=CS1 passthrough=yes protocol=udp src-port=10000-20000 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Hangouts" dst-port=19302-19309 new-connection-mark=AF42 \ passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Hangouts" new-connection-mark=AF42 passthrough=yes \ protocol=udp src-port=19302-19309 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Viber" dst-port=5242,4244 new-connection-mark=AF42 \ passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Viber" new-connection-mark=AF42 passthrough=yes \ protocol=tcp src-port=5242,4244 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Viber" dst-port=7985,5243,9785,7985 \ new-connection-mark=AF42 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 Viber" new-connection-mark=AF42 passthrough=yes \ protocol=udp src-port=7985,5243,9785,7985 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 WhatsApp" dst-port=50318,59234,3478,45395 \ new-connection-mark=AF42 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 WhatsApp" new-connection-mark=AF42 passthrough=yes \ protocol=udp src-port=50318,59234,3478,45395 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 WhatsApp" dst-port=4244,5222-5223,5228,5242,50318,59234 \ new-connection-mark=AF42 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF42 WhatsApp" new-connection-mark=AF42 passthrough=yes \ protocol=tcp src-port=4244,5222-5223,5228,5242,50318,59234 add action=mark-connection chain=ClassifyRule comment="Classify as CS2 SSH" \ dst-port=22 new-connection-mark=CS2 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS2 SSH" \ new-connection-mark=CS2 passthrough=yes protocol=tcp src-port=22 add action=mark-connection chain=ClassifyRule comment="Classify as CS2 Winbox" \ dst-port=8291 new-connection-mark=CS2 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS2 Winbox" \ new-connection-mark=CS2 passthrough=yes protocol=tcp src-port=8291 add action=mark-connection chain=ClassifyRule comment="Classify as CS2 SNMP" \ dst-port=161,162 new-connection-mark=CS2 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS2 SNMP" \ new-connection-mark=CS2 passthrough=yes protocol=udp src-port=161,162 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 TELNET" dst-port=23,992 new-connection-mark=CS2 \ passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 TELNET" new-connection-mark=CS2 passthrough=yes \ protocol=tcp src-port=23,992 add action=mark-connection chain=ClassifyRule comment="Classify as CS2 TFTP" \ dst-port=69 new-connection-mark=CS2 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS2 TFTP" \ new-connection-mark=CS2 passthrough=yes protocol=udp src-port=69 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 Syslog" dst-port=514 new-connection-mark=CS2 \ passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 Syslog" new-connection-mark=CS2 passthrough=yes \ protocol=tcp src-port=514 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 Syslog" dst-port=514 new-connection-mark=CS2 \ passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS2 Syslog" new-connection-mark=CS2 passthrough=yes \ protocol=udp src-port=514 add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ dst-port=3002,9300,17988,17990 new-connection-mark=CS7 passthrough=yes \ protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ new-connection-mark=CS7 passthrough=yes protocol=tcp src-port=\ 3002,9300,17988,17990 add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ dst-port=623 new-connection-mark=CS7 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ new-connection-mark=CS7 passthrough=yes protocol=tcp src-port=623 add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ dst-port=623 new-connection-mark=CS7 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS7 ILO" \ new-connection-mark=CS7 passthrough=yes protocol=udp src-port=623 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 FTP" \ dst-port=21 new-connection-mark=AF12 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as AF 12 FTP" \ new-connection-mark=AF12 passthrough=yes protocol=tcp src-port=21 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 FTP" \ connection-state=established,related connection-type=ftp \ new-connection-mark=AF12 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ dst-port=1024-65535 new-connection-mark=AF12 passthrough=yes protocol=udp \ src-port=137 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ dst-port=137 new-connection-mark=AF12 passthrough=yes protocol=udp \ src-port=1024-65535 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ dst-port=135,137-139,445 new-connection-mark=AF12 passthrough=yes \ protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ new-connection-mark=AF12 passthrough=yes protocol=udp src-port=\ 135,137-139,445 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ dst-port=135,139,445 new-connection-mark=AF12 passthrough=yes protocol=\ tcp add action=mark-connection chain=ClassifyRule comment="Classify as AF12 SMB" \ new-connection-mark=AF12 passthrough=yes protocol=tcp src-port=\ 135,139,445 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF12 EMAIL" dst-port=143,993,110,995,25,465,587 \ new-connection-mark=AF12 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF12 EMAIL" new-connection-mark=AF12 passthrough=yes \ protocol=tcp src-port=143,993,110,995,25,465,587 add action=mark-connection chain=ClassifyRule comment="Classify as AF12 DCC" \ dst-port=6277 new-connection-mark=AF12 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as AF12 DCC" \ new-connection-mark=AF12 passthrough=yes protocol=udp src-port=6277 add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF12 IPMI Virtual Media, Secure (Dell)" dst-port=3668,3669 \ new-connection-mark=AF12 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as AF12 IPMI Virtual Media, Secure (Dell)" new-connection-mark=\ AF12 passthrough=yes protocol=tcp src-port=3668,3669 add action=mark-connection chain=ClassifyRule comment="Classify as AF32 DAAP" \ dst-port=3689 new-connection-mark=AF32 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as AF32 DAAP" \ new-connection-mark=AF32 passthrough=yes protocol=udp src-port=3689 add action=mark-connection chain=ClassifyRule comment="Classify as AF32 DAAP" \ dst-port=3689 new-connection-mark=AF32 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as AF32 DAAP" \ new-connection-mark=AF32 passthrough=yes protocol=tcp src-port=3689 add action=mark-connection chain=ClassifyRule comment="Classify as CS6 OSPF" \ new-connection-mark=CS6 passthrough=yes protocol=ospf add action=mark-connection chain=ClassifyRule comment="Classify as CS6 RIP" \ dst-port=520 new-connection-mark=CS6 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS6 RIP" \ new-connection-mark=CS6 passthrough=yes protocol=udp src-port=520 add action=mark-connection chain=ClassifyRule comment="Classify as CS6 IKE" \ dst-port=500 new-connection-mark=CS7 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS6 IKE" \ new-connection-mark=CS7 passthrough=yes protocol=udp src-port=500 add action=mark-connection chain=ClassifyRule comment="Classify as CS6 BGP" \ dst-port=179 new-connection-mark=CS6 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS6 BGP" \ new-connection-mark=CS6 passthrough=yes protocol=tcp src-port=179 add action=mark-connection chain=ClassifyRule comment="Classify as CS4 RDP" \ dst-port=3389-3400 new-connection-mark=CS4 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS4 RDP" \ dst-port=3389-3400 new-connection-mark=CS4 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS4 RDP" \ new-connection-mark=CS4 passthrough=yes protocol=tcp src-port=3389-3400 add action=mark-connection chain=ClassifyRule comment="Classify as CS4 RDP" \ new-connection-mark=CS4 passthrough=yes protocol=udp src-port=3389-3400 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 VNC\\Aten\\AMI" dst-port=5900,5901,7578 \ new-connection-mark=CS4 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 VNC\\Aten\\AMI" new-connection-mark=CS4 passthrough=yes \ protocol=tcp src-port=5900,5901,7578 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 Citrix/ICA" dst-port=1604 new-connection-mark=CS4 \ passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 Citrix/ICA" new-connection-mark=CS4 passthrough=yes \ protocol=udp src-port=1604 add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 Citrix/ICA" dst-port=1494,2598 new-connection-mark=CS4 \ passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment=\ "Classify as CS4 Citrix/ICA" new-connection-mark=CS4 passthrough=yes \ protocol=tcp src-port=1494,2598 add action=mark-connection chain=ClassifyRule comment="Classify as CS3 SIP" \ dst-port=5060 new-connection-mark=CS3 passthrough=yes protocol=udp add action=mark-connection chain=ClassifyRule comment="Classify as CS3 SIP" \ new-connection-mark=CS3 passthrough=yes protocol=udp src-port=5060 add action=mark-connection chain=ClassifyRule comment="Classify as CS3 SIP" \ dst-port=5061 new-connection-mark=CS3 passthrough=yes protocol=tcp add action=mark-connection chain=ClassifyRule comment="Classify as CS3 SIP" \ new-connection-mark=CS3 passthrough=yes protocol=tcp src-port=5061 


This classifier assigns a class label for various types of traffic, I took the main set from Shorewall, if you don’t need so much, feel free to cut it down. There are two simple rules, all traffic is first marked as DF (Default), and then, all UDP is marked as CS1 (Scavenger, “garbage” traffic, with which we fill in the remnants of bandwidth). And after that, all traffic is re-allocated to other classes.

Thus, the torrent automatically becomes either CS1 or DF (if TCP), and a bunch of other traffic can also receive such classes if you don’t select them yourself.

It is important to note that Web traffic, whose connections are “long”, is then remarked to AF12 (for various downloads, etc.). Thus, surfing is fast (at DF priority 7), and when the download starts, it automatically enters AF12 (with priority 8), thus, it is not possible to block the download channel.

Separately, there are all sorts of YouTube. We catch their traffic using Layer7 (not the most reliable option, but quite working).

Next comes the script responsible for routing:

Routing
 ############################################### :local ISPNum 6 #:local UserType [:toarray ("ViP","LoPri","Guest","Norm")] :local UserType [:toarray ("Norm")] :local DNSNat [:toarray ("local.domain")] :local DNSNatIP [:toarray ("172.16.24.94")] :local ClassifyLocal true :local Balancing true :local BalancingWeigh [:toarray (2,2,2,2,6,1)] # by RouterOS 6.41 :if ( [/interface list print count-only where name=ISP] = 0) do={ /interface list add name=ISP } :if ( [/interface list print count-only where name=TUN] = 0) do={ /interface list add name=TUN } :if ( [/interface list print count-only where name=LAN-IF] = 0) do={ /interface list add name=LAN-IF } :if ( [/interface list print count-only where name=GST-IF] = 0) do={ /interface list add name=GST-IF } :if ( [/interface list print count-only where name=GRE] = 0) do={ /interface list add name=GRE } :local isp "" :local tun "" :for i from=1 to=$ISPNum step=1 do={ :if ( [/interface list print count-only where name=("ISP".$i)] = 0) do={ /interface list add name=("ISP".$i) } :if ( [/interface list print count-only where name=("TUN".$i)] = 0) do={ /interface list add name=("TUN".$i) } :if ( [/interface list print count-only where name=("ISP".$i."TUN")] = 0) do={ /interface list add include=("ISP".$i.",TUN".$i) name=("ISP".$i."TUN") } :set isp ($isp."ISP".$i.",") :set tun ($tun."TUN".$i.",") } /interface list set ISP include=$isp :foreach t in=$DNSNat do={ :if ( [/ip firewall layer7-protocol print count-only where name=$t] = 0) do={ /ip firewall layer7-protocol add name=$t regexp=(".".$t) comment=("DNS Nat ".$t) } } /ip firewall mangle :local i 0 :foreach t in=$DNSNat do={ add action=mark-packet chain=prerouting comment=("mark dns ".$t) dst-port=53 \ in-interface-list=LAN-IF layer7-protocol=$t new-packet-mark=\ ("dns-".$t) passthrough=yes protocol=udp dst-address-type=local add action=mark-packet chain=prerouting comment=("mark dns ".$t) dst-port=53 \ in-interface-list=LAN-IF layer7-protocol=$t new-packet-mark=\ ("dns-".$t) passthrough=yes protocol=tcp dst-address-type=local /ip firewall nat add action=dst-nat chain=dstnat comment=("DST-NAT dns ".$t) dst-port=53 \ in-interface-list=LAN-IF packet-mark=("dns-".$t) protocol=udp \ to-addresses=([:pick $DNSNatIP $i]) /ip firewall nat add action=dst-nat chain=dstnat comment=("DST-NAT dns ".$t) dst-port=53 \ in-interface-list=LAN-IF packet-mark=("dns-".$t) protocol=tcp \ to-addresses=([:pick $DNSNatIP $i]) /ip firewall nat add action=masquerade chain=srcnat comment=("mask dns ".$t) dst-port=53 \ packet-mark=("dns-".$t) protocol=udp /ip firewall nat add action=masquerade chain=srcnat comment=("mask dns ".$t) dst-port=53 \ packet-mark=("dns-".$t) protocol=tcp :set i ($i + 1) } add action=jump chain=prerouting comment="PreRoute: Catch New Connections" \ connection-state=new jump-target=PR-New add action=jump chain=prerouting comment="PreRoute: Catch packets with ConnMark from LAN" \ connection-mark=!no-mark in-interface-list=!ISP jump-target=PR-RouteMark dst-address-list=!LAN-IP src-address-list=LAN-IP :if ( $Balancing = true ) do={ :local CommDen 0 :foreach t in=$BalancingWeigh do={ :set CommDen ($CommDen + $t) } :for i from=1 to=$ISPNum step=1 do={ add action=mark-connection chain=PR-New comment=\ ("ISP".$i.": PreRoute: marking conn from ISP".$i) dst-address-list=!LAN-IP \ in-interface-list=("ISP".$i) new-connection-mark=("ISP".$i) passthrough=yes \ src-address-list=!LAN-IP } add action=jump chain=PR-New comment="PreRoute: prepare for balancing" \ dst-address-list=!LAN-IP in-interface-list=!ISP \ jump-target=PR-Nailed src-address-list=LAN-IP src-address-type=!local :for i from=1 to=$ISPNum step=1 do={ add action=mark-connection chain=PR-Nailed comment=\ ("ISP".$i.": PreRoute: Nailed appropriate connection to ISP".$i) \ new-connection-mark=("ISP".$i) passthrough=yes src-address-list=("ISP".$i."-Nailed") } add action=jump chain=PR-Nailed comment="PreRoute: Go to balancing" \ connection-mark=no-mark jump-target=PR-Balancing :local w 0 :for i from=1 to=$ISPNum step=1 do={ :for j from=1 to=[:pick $BalancingWeigh ($i-1)] step=1 do={ add action=mark-connection chain=PR-Balancing comment=\ ("ISP".$i.": PreRoute: PCC for ISP".$i) new-connection-mark=("ISP".$i) passthrough=yes \ per-connection-classifier=("both-addresses:".$CommDen."/".$w) :set w ($w + 1) } } :for i from=1 to=$ISPNum step=1 do={ add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for unclassifying ISP".$i." connection") \ connection-mark=("ISP".$i) new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for unclassifying ISP".$i." connection") \ connection-mark=("ISP".$i."-DF") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for EF ISP".$i." connection") \ connection-mark=("ISP".$i."-EF") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for AF12 ISP".$i." connection") \ connection-mark=("ISP".$i."-AF12") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i." PreRoute: set route-mark for AF32 ISP".$i." connection") \ connection-mark=("ISP".$i."-AF32") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for AF42 ISP".$i." connection") \ connection-mark=("ISP".$i."-AF42") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for CS1 ISP".$i." connection") connection-mark=\ ("ISP".$i."-CS1") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for CS2 ISP".$i." connection") connection-mark=\ ("ISP".$i."-CS2") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for CS3 ISP".$i." connection") connection-mark=\ ("ISP".$i."-CS3") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for CS4 ISP".$i." connection") connection-mark=\ ("ISP".$i."-CS4") new-routing-mark=("ISP".$i) passthrough=yes add action=mark-routing chain=PR-RouteMark comment=\ ("ISP".$i.": PreRoute: set route-mark for CS6 ISP".$i." connection") connection-mark=\ ("ISP".$i."-CS6") new-routing-mark=("ISP".$i) passthrough=yes } } else={ add action=mark-connection chain=PR-New comment=\ "ISP1: PreRoute: marking conn from ISP1" dst-address-list=!LAN-IP \ in-interface-list=ISP1 new-connection-mark=ISP1 passthrough=yes \ src-address-list=!LAN-IP add action=mark-connection chain=PR-New comment=\ "ISP1: PreRoute: marking conn from ISP1" dst-address-list=!LAN-IP \ in-interface-list=!ISP new-connection-mark="ISP1" passthrough=yes \ src-address-list=LAN-IP } add action=jump chain=forward comment="Forward: Catch New Connections" \ connection-state=new jump-target=F-PreClassify add action=jump chain=input comment="Input: Catch New Connections" \ connection-state=new connection-mark=no-mark jump-target=I-PreClassify add action=jump chain=output comment="Output: Catch New Connections" \ connection-state=new connection-mark=no-mark jump-target=O-PreClassify :for i from=1 to=$ISPNum step=1 do={ add action=mark-connection chain=F-PreClassify comment=\ ("ISP".$i.": Forward: remark connection by ISP".$i." for effective route") \ new-connection-mark=("ISP".$i) out-interface-list=("ISP".$i) passthrough=yes add action=mark-connection chain=F-PreClassify comment=\ ("Forward: associate TUN connection with ISP".$i) in-interface-list=("TUN".$i) \ new-connection-mark=("ISP".$i) connection-mark=no-mark passthrough=yes add action=mark-connection chain=F-PreClassify comment=\ ("Forward: associate TUN connection with ISP".$i) new-connection-mark=("ISP".$i) \ out-interface-list=("TUN".$i) connection-mark=no-mark passthrough=yes add action=jump chain=F-PreClassify comment=\ ("ISP".$i.": Forward: prepare for ISP".$i." classifying") connection-mark=("ISP".$i) \ jump-target=("ISP".$i."-Classify") add action=jump chain=I-PreClassify comment=\ ("ISP".$i.": Input: prepare for ISP".$i." classifying") in-interface-list=("ISP".$i) \ jump-target=("ISP".$i."-Classify") add action=jump chain=O-PreClassify comment=\ ("ISP".$i.": Output: prepare for ISP".$i." classifying") out-interface-list=("ISP".$i) \ jump-target=("ISP".$i."-Classify") } :if ( $ClassifyLocal = true ) do={ add action=jump chain=F-PreClassify comment=\ "Forward: Classifying LAN connection" connection-mark=no-mark \ in-interface-list=LAN-IF jump-target=ClassifyRule add action=jump chain=F-PreClassify comment=\ "Forward: Classifying LAN connection" connection-mark=no-mark \ jump-target=ClassifyRule out-interface-list=LAN-IF } 


( 6-), , DNS DNS , ( «» , «»). , , .

LAN-IP. .

, :

 ############################################### :local ISPNum 6 #:local UserType [:toarray ("ViP","LoPri","Guest","Norm")] :local UserType [:toarray ("Norm")] :local SetDSCP true :local InOutQueues false # by RouterOS 6.41 :if ( [/interface list print count-only where name=ISP] = 0) do={ /interface list add name=ISP } :if ( [/interface list print count-only where name=TUN] = 0) do={ /interface list add name=TUN } :if ( [/interface list print count-only where name=WiFi] = 0) do={ /interface list add name=WiFi } :local isp "" :local tun "" :for i from=1 to=$ISPNum step=1 do={ :if ( [/interface list print count-only where name=("ISP".$i)] = 0) do={ /interface list add name=("ISP".$i) } :if ( [/interface list print count-only where name=("TUN".$i)] = 0) do={ /interface list add name=("TUN".$i) } :if ( [/interface list print count-only where name=("ISP".$i."TUN")] = 0) do={ /interface list add include=("ISP".$i.",TUN".$i) name=("ISP".$i."TUN") } :set isp ($isp."ISP".$i.",") :set tun ($tun."TUN".$i.",") } /interface list set ISP include=$isp /interface list set TUN include=$tun /ip firewall mangle :local PT no :if ( $SetDSCP = true ) do={ :set PT yes } :for i from=1 to=$ISPNum step=1 do={ add action=jump chain=("ISP".$i."-Classify") comment=("Jump to classify ISP".$i) \ jump-target=ClassifyRule add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-DF connmark for DF") connection-mark=DF \ new-connection-mark=("ISP".$i."-DF") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-EF connmark for EF") connection-mark=EF \ new-connection-mark=("ISP".$i."-EF") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-AF12 connmark for AF12") connection-mark=AF12 \ new-connection-mark=("ISP".$i."-AF12") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-AF32 connmark for AF32") connection-mark=AF32 \ new-connection-mark=("ISP".$i."-AF32") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-AF42 connmark for AF42") connection-mark=AF42 \ new-connection-mark=("ISP".$i."-AF42") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS1 connmark for CS1") connection-mark=CS1 \ new-connection-mark=("ISP".$i."-CS1") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS2 connmark for CS2") connection-mark=CS2 \ new-connection-mark=("ISP".$i."-CS2") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS3 connmark for CS3") connection-mark=CS3 \ new-connection-mark=("ISP".$i."-CS3") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS4 connmark for CS4") connection-mark=CS4 \ new-connection-mark=("ISP".$i."-CS4") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS6 connmark for CS6") connection-mark=CS6 \ new-connection-mark=("ISP".$i."-CS6") passthrough=yes add action=mark-connection chain=("ISP".$i."-Classify") comment=\ ("ISP".$i.": set ISP".$i."-CS7 connmark for CS7") connection-mark=CS7 \ new-connection-mark=("ISP".$i."-CS7") passthrough=yes } add action=jump chain=forward comment="Forward: Download stream ISP" \ in-interface-list=ISP jump-target=F-Download out-interface-list=!ISP add action=jump chain=forward comment="Forward: download stream from TUN" \ in-interface-list=TUN jump-target=F-Download out-interface-list=!ISP add action=jump chain=forward comment="Forward: Upload stream from ISP" \ in-interface-list=!ISP jump-target=F-Upload out-interface-list=ISP add action=jump chain=forward comment="Forward: Upload stream from TUN" \ in-interface-list=!ISP jump-target=F-Upload out-interface-list=TUN :if ( $InOutQueues = true ) do={ :for i from=1 to=$ISPNum step=1 do={ add action=jump chain=input connection-mark=!no-mark in-interface-list=("ISP".$i."TUN") \ jump-target=("ISP".$i."-".[:pick $UserType ([:len $UserType] -1 )]."-Download") packet-mark=no-mark comment=("Input: Download stream ISP".$i) add action=jump chain=output connection-mark=!no-mark out-interface-list=("ISP".$i."TUN") \ jump-target=("ISP".$i."-".[:pick $UserType ([:len $UserType] -1 )]."-Upload") packet-mark=no-mark comment=("Output: Upload stream ISP".$i) } } :foreach d in=("Download","Upload") do={ :foreach t in=$UserType do={ :if ([:pick $UserType ([:len $UserType] -1 )] != $t) do={ :if ($d = "Download") do={ add action=jump chain=("F-".$d) comment=("Forward: ".$d." from ".$t) \ dst-address-list=$t jump-target=("F-".$d.$t) } else={ add action=jump chain=("F-".$d) comment=("Forward: ".$d." from ".$t) \ src-address-list=$t jump-target=("F-".$d.$t) } } else={ add action=jump chain=("F-".$d) comment=("Forward: ".$d." from ".$t) \ jump-target=("F-".$d.$t) } } :foreach t in=$UserType do={ :for i from=1 to=$ISPNum step=1 do={ :if ($d = "Download") do={ add action=jump chain=("F-".$d.$t) comment=\ ("ISP".$i.": Forward: ".$d." from ".$t." ISP".$i) in-interface-list=("ISP".$i."TUN") \ jump-target=("ISP".$i."-".$t."-".$d) } else={ add action=jump chain=("F-".$d.$t) comment=\ ("ISP".$i.": Forward: ".$d." from ".$t." ISP".$i) out-interface-list=("ISP".$i."TUN") \ jump-target=("ISP".$i."-".$t."-".$d) } add action=jump chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Remark long DF connection") connection-bytes=524288-0 \ connection-mark=("ISP".$i."-DF") jump-target=("ISP".$i."-Remark") add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q1 for ".$t." ISP".$i." EF") connection-mark=("ISP".$i."-EF") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q1") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set DF for ISP".$i) connection-mark=("ISP".$i."-EF") new-dscp=46 \ passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q2 for ".$t." ISP".$i." CS7") connection-mark=("ISP".$i."-CS7") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q2") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS7 for ISP".$i) connection-mark=("ISP".$i."-CS7") new-dscp=\ 56 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q3 for ".$t." ISP".$i." CS6") connection-mark=("ISP".$i."-CS6") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q3") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS6 for ISP".$i) connection-mark=("ISP".$i."-CS6") new-dscp=\ 48 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q4 for ".$t." ISP".$i." CS4") connection-mark=("ISP".$i."-CS4") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q4") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS4 for ISP".$i) connection-mark=("ISP".$i."-CS4") new-dscp=\ 32 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q4 for ".$t." ISP".$i." AF42") connection-mark=\ ("ISP".$i."-AF42") new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q4") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set AF42 for ISP".$i) connection-mark=("ISP".$i."-AF42") \ new-dscp=36 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q5 for ".$t." ISP".$i." AF32") connection-mark=\ ("ISP".$i."-AF32") new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q5") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set AF32 for ISP".$i) connection-mark=("ISP".$i."-AF32") \ new-dscp=28 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q5 for ".$t." ISP".$i." CS3") connection-mark=("ISP".$i."-CS3") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q5") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS3 for ISP".$i) connection-mark=("ISP".$i."-CS3") new-dscp=\ 24 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q6 for ".$t." ISP".$i." CS2") connection-mark=("ISP".$i."-CS2") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q6") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS2 for ISP".$i) connection-mark=("ISP".$i."-CS2") new-dscp=\ 16 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q7 for ".$t." ISP".$i." DF") connection-mark=("ISP".$i."-DF") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q7") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set DF for ISP".$i) connection-mark=("ISP".$i."-DF") new-dscp=0 \ passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q7 for ".$t." ISP".$i." Unclassify") connection-mark=("ISP".$i) \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q7") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set DF for ISP".$i) connection-mark=("ISP".$i) new-dscp=0 \ passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q8 for ".$t." ISP".$i." AF12") connection-mark=\ ("ISP".$i."-AF12") new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q8") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set AF12 for ISP".$i) connection-mark=("ISP".$i."-AF12") \ new-dscp=12 passthrough=no } add action=mark-packet chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: PacketMark Q8 for ".$t." ISP".$i." CS1") connection-mark=("ISP".$i."-CS1") \ new-packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q8") passthrough=$PT :if ( $SetDSCP = true ) do={ add action=change-dscp chain=("ISP".$i."-".$t."-".$d) comment=\ ("ISP".$i.": Forward: DSCP Set CS1 for ISP".$i) connection-mark=("ISP".$i."-CS1") \ new-dscp=8 passthrough=no } } } } :for i from=1 to=$ISPNum step=1 do={ add action=mark-connection chain=("ISP".$i."-Remark") comment=\ ("ISP".$i.": Remark DF to AF12 Bulk") connection-bytes=524288-0 dst-port=80,443 \ new-connection-mark=("ISP".$i."-AF12") passthrough=yes protocol=tcp add action=mark-connection chain=("ISP".$i."-Remark") comment=\ ("ISP".$i.": Remark DF to AF12 Bulk") connection-bytes=524288-0 \ new-connection-mark=("ISP".$i."-AF12") passthrough=yes protocol=tcp src-port=\ 80,443 add action=mark-connection chain=("ISP".$i."-Remark") comment=\ ("ISP".$i.": Remark to Scavenger") connection-bytes=524288-0 \ new-connection-mark=("ISP".$i."-CS1") passthrough=yes protocol=tcp } add action=set-priority chain=postrouting new-priority=from-dscp-high-3-bits out-interface-list=WiFi passthrough=yes comment="Set Priority for WiFi" 


, «»: DSCP ( , , , ).

TUN<>, , . QoS, ( ), .

WiFi WiFi ( WMM) DSCP.

, :

 # by RouterOS 6.41 :local ISPNum 6 #:local UserType [:toarray ("ViP","Norm","LoPri","Guest")] :local UserType [:toarray ("Norm")] :local VoIPChanels 6 :local G711 84 :local Max [:toarray (10000,10000,10000,10000,30000,4800)] :local Reserv 5 :local genOnly -1 :local R $Reserv /queue tree :foreach d in=("Download","Upload") do={ :for i from=1 to=$ISPNum step=1 do={ :if ( $genOnly = -1 || $genOnly = $i ) do={ :if (([:pick $Max ($i-1)] * $Reserv / 100) > 500) do={ :set R 500 } else={ :set R ([:pick $Max ($i-1)] * $Reserv / 100) } add max-limit=([:pick $Max ($i-1)]."k") name=("ISP".$i."-".[:pick $d 0]."R") parent=global :local prio (9-[:len $UserType]) :foreach t in=$UserType do={ add name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) parent=("ISP".$i."-".[:pick $d 0]."R") priority=$prio add limit-at=(($G711 * $VoIPChanels)."k") max-limit=([:pick $Max ($i-1)]."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q1") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q1") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=1 add limit-at=(([:pick $Max ($i-1)] * 20 / 100)."k") max-limit=(([:pick $Max ($i-1)] - $R)."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q2") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q2") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=2 queue=pcq-download-default add limit-at=100k max-limit=1M name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q3") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q3") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=2 queue=default add limit-at=(([:pick $Max ($i-1)] * 30 / 100)."k") max-limit=([:pick $Max ($i-1)]."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q4") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q4") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=3 queue=pcq-download-default add limit-at=(([:pick $Max ($i-1)] * 15 / 100)."k") max-limit=([:pick $Max ($i-1)]."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q5") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q5") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=4 queue=pcq-download-default add limit-at=(([:pick $Max ($i-1)] * 10 / 100)."k") max-limit=([:pick $Max ($i-1)]."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q6") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q6") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=4 queue=pcq-download-default add limit-at=(([:pick $Max ($i-1)] * 15 / 100)."k") max-limit=(([:pick $Max ($i-1)] - $R)."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q7") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q7") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=4 queue=pcq-download-default :local LA ([:pick $Max ($i-1)] - ([:pick $Max ($i-1)] * 90 / 100 + $G711 * $VoIPChanels + 100)) :if ( $LA < ([:pick $Max ($i-1)] /10) ) do={ :set LA ([:pick $Max ($i-1)] /10) } add limit-at=($LA."k") max-limit=(([:pick $Max ($i-1)] - $R)."k") name=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q8") packet-mark=("ISP".$i."-".[:pick $d 0].[:pick $t 0]."Q8") parent=("ISP".$i."-".[:pick $d 0].[:pick $t 0]) priority=4 queue=pcq-download-default :set prio ($prio + 1) } } } } 


, , , . VoIP , ( ). Reserv « » ( , 500\). genOnly , (-1 , 0).

Conclusion


: , - , . , DSCP , . . , , , ! , RB951G 52 \ DSCP. RB1100x4 8%, 60 \ ( ).

, , fasttrack ( , ).

Source: https://habr.com/ru/post/331544/


All Articles