RouterOS是一款非常灵活的路由器,功能上也可以代替运营商bras,大喵在2012年使用到至今;家里的手机电脑越来越多,这个家用动态限速方案比什么限速小包优先效果都好。

mikrotik routeros家用动态限速方案

第一步

  • 首先,需要将内网中,在线的主机IP,都保存到/ip firewall address-lists里面,下面会有用到,timeout就设为10分钟吧。

第二步

  • 再增加同一网段的所有IP的标记,in-interface src-address和out-interface dst-address分别设置。所有标记都启用,并且关掉passthrough。

    :for item from=1 to=254 do={/ip firewall mangle;add chain=forward src-address="192.168.88.$item" in-interface=Lan action=mark-packet new-packet-mark="192.168.88.$item" passthrough=no comment="192.168.88.$item";add chain=forward dst-address="192.168.88.$item" out-interface=Lan action=mark-packet new-packet-mark="_192.168.88.$item" passthrough=no comment="_192.168.88.$item";}

第三步

  • 然后再在queue tree里面,增加同一网段所有IP的queue包含up和down,一共254*2+2个队列需要增加。每一queue的包标记使用对应的包名称。 增加好后除了down和up这两个主队列,其它都先禁用。主队列使用paren=global,max-limit=你的最大带宽。所有子队列的max-limit=最大带宽*0.8。

    /queue tree;add name=down parent=global max-limit=100000000;add name=up parent=global max-limit=2000000;:for item from=1 to=254 do={add name="_192.168.88.$item" parent=down max-limit=80000000 packet-mark="_192.168.88.$item" disable=yes;add name="192.168.88.$item" parent=up max-limit=1600000 packet-mark="192.168.88.$item" disable=yes}

第四步

  • 最后一部分就是限速部分,需要system scripts和scheduler来完成。计划写两个脚本,其中一个总开关检查功能。先介绍总开关功能,总开关将声明一个全局变量,用来存放上一次执行时的在线主机IP列表。总开关每三十秒运行一次(scheduler定时执行),每次运行都获取一次在线主机IP列表,将这列表与全局变量保存的IP列表对比,判断新旧在线主机IP列表是否有变化,是否有下线的主机IP(若有下线的,直接执行disable=yes关了对应的queue),若IP列表有变化,运行另外一个执行脚本,剩余的事都交给另外一个脚本了。 介绍第二个脚本功能,第二个脚本功能获取当前在线主机IP的数量,用来计算一会要使用到的limit值。建议limit=最大带宽*0.7/当前在线主机数量。
  • 事实上脚本的实际写法要比上文的介绍要复杂一些,多了一些判断什么的,但是全介绍出来的话太累人了,自行看脚本吧。
  • 代码如下:

    /system script;add name=onlineAddressChack source=":global onlineAddressBak;:local onlineAddressObj [/ip firewall address-list find list=onlineAddress];:local onlineAddress \"\";:foreach item in=\$onlineAddressObj do={:set onlineAddress (\$onlineAddress . \",\" . [/ip firewall address-list get \$item address]);};:set onlineAddress [:toarray \$onlineAddress];:local Tswitch 0;:if ([:typeof \$onlineAddressBak] = \"array\") do={:if (\$onlineAddress != \$onlineAddressBak) do={:set Tswitch 1;:foreach item in=\$onlineAddressBak do={:local Sswitch 1;:foreach item2 in=\$onlineAddress do={:if (\$item = \$item2) do={:set Sswitch 0;};};:if (\$Sswitch = 1) do={:local tempAddress [:tostr \$item];/queue tree set [find name=\$tempAddress] disable=yes;/queue tree set [find name=\"_\$tempAddress\"] disable=yes;:set Tswitch 1;};};};} else={:set Tswitch 1;};:if (\$Tswitch = 1) do={:set onlineAddressBak \$onlineAddress;/system script run [find name=onlineAddressChange];};";add name=onlineAddressChange source=":global onlineAddressBak;:local numOfOnlineAddress [:len \$onlineAddressBak];:local limitUp (1400000 / \$numOfOnlineAddress);:local limitDown (70000000 / \$numOfOnlineAddress);:foreach item in=\$onlineAddressBak do={/queue tree set [find name=\$item] dis=no limit-at=\$limitUp;:delay 500ms;/queue tree set [find name=\"_\$item\"] dis=no limit-at=\$limitDown;:delay 500ms;}";
  • 第二个脚本中,每执行一次queue操作,后面都有一个delay 500ms。 若各位在线设备大于30台,建议此延时值改小一点,例如400ms? 最低不要低于100ms,除非你CPU真的挺强的。
  • 最后记得手动添加scheduler定时执行。
Last modification:March 4, 2019
If you think my article is useful to you, please feel free to appreciate