RouterOS脚本,PCQ流量自适应,小包、HTTP优先

75次阅读

本脚本在 RouterOS 7.20.7 系统,家庭(几台设备,单电信出口)/单位(几百台设备,多电信出口)上测试,效果良好。

优点:

1.多ISP(即多出口)可以一次性完成配置,可以自适应流量控制,下载流量不抢占网页流量等资源,最大化利用带宽。

2.只限制所设置的出口WAN的流量,如果有内部专网(城域网或教育专网)时,专网的流量不会有限制。(网上部分脚本会限制网桥或LAN口的总速率,造成不需要限速的专网也被限制)

3.小包、实时通讯、网络游戏的部分端口优先级最高。

4.网页 HTTP/HTTPS 流量优先级次之。

5.大文件、长流量传输的优先级较低。

6.UDP大包(一般用于P2P传输)优先级最低。

使用方法:

1.下载 queue_tree 脚本文件,解压后得到 queue_tree.rsc

2.用记事本打开 queue_tree.rsc 文件,配置 外网接口 与 内网接口名称,再配置宽带的最大上行与下行速率,一般可在最高能跑到的速率再低10-20M左右为佳,这样可以预留一定的冗余给需要的流量,同时单种类型的流量也基本能跑满带宽。

3.将原有的 Mangle 标记先清理干净。(因为使用到 Mangle 标记,所以不能开启 fasttrack 功能

4.将 queue_tree.rsc 上传到 RouterOS 中,打开 New Terminal 命令行窗口,使用 import file-name=queue_tree.rsc 来导入。(或者在 System->Scripts 中创建一个脚本,将内容复制进去,然后运行该脚本。)

RouterOS脚本,PCQ流量自适应,小包、HTTP优先

# 在这里设置您的外网接口列表名称(所设置外网接口必须存在,如果有多个则用逗号分隔,比如:WAN1,WAN2)
:local pppoeInterfaces "pppoe-out1"

# 设置网关所在接口名称(用于下载队列根,一般为bridge1或内网接口名)
:local bridgeInterface "bridge1"

# 最大下载带宽与最大上传带宽,一般可在最高能跑到的速率再低10-20M左右为佳,这样可以预留一定的冗余给需要的流量,同时单种类型的流量也基本能跑满带宽。
# 设置最大下载带宽,请根据实际网络带宽修改。(单位:Mbps,如果外网接口有多个,也可以设置多个速度,中间用逗号分开)
:local maxDownloadMbps 220

# 设置最大上传带宽,请根据实际网络带宽修改。(单位:Mbps,如果外网接口有多个,也可以设置多个速度,中间用逗号分开)
:local maxUploadMbps 100

:local interfaceList [:toarray $pppoeInterfaces]
:local speedDownloadList [:toarray $maxDownloadMbps]
:local speedUploadList [:toarray $maxUploadMbps]

:local defaultDownloadSpeed ($speedDownloadList->0)
:local defaultUploadSpeed ($speedUploadList->0)

# ==================== 检查接口是否存在 ====================
# 检查pppoeInterfaces中的每个接口
:foreach i in=$interfaceList do={
    :log info "正在检查接口 $i 是否存在..."
    :if ([/interface find name=$i] = "" && [/interface list member find list=$i] = "") do={
        :error "Interface  '$i' not found"
    }
}

# 检查桥接接口
:if ([/interface find name=$bridgeInterface] = "") do={
    :error "Interface  '$bridgeInterface' not found"
}

# 清空 Mangle 列表(IPv4)
:log info "正在清理 Mangle(IPv4) 列表原有标记。"
/ip firewall mangle remove [find comment~"Mark|Download|Upload"]

# 首先创建所有连接标记规则(只需要创建一次)
/ip firewall mangle
add action=mark-connection chain=prerouting comment="Mark HTTP Connections" dst-port=80,8080,8000,8081,443,8443 new-connection-mark=http_conn protocol=tcp
add action=mark-connection chain=prerouting comment="Mark TCP Connections" connection-mark=!http_conn new-connection-mark=tcp_conn protocol=tcp

# 将接口列表转换为数组并遍历
:foreach interface in=$interfaceList do={
    # 下载方向规则
    add action=mark-packet chain=forward comment="Download Real-time UDP Packets ($interface)" src-port=53,3478,3479,3659,5060,27000-27050 in-interface=$interface new-packet-mark="dl_realtime($interface)" passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download UDP Small Packets ($interface)" in-interface=$interface new-packet-mark="dl_udp_small($interface)" packet-size=0-512 passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download UDP Large Packets ($interface)" in-interface=$interface new-packet-mark="dl_udp_large($interface)" passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download Large File Packets ($interface)" connection-bytes=5000000-0 in-interface=$interface new-packet-mark="dl_large_file($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download HTTP Packets ($interface)" connection-mark=http_conn in-interface=$interface new-packet-mark="dl_http($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download TCP Small Packets ($interface)" connection-mark=tcp_conn in-interface=$interface new-packet-mark="dl_tcp_small($interface)" packet-size=0-128 passthrough=no protocol=tcp 
    add action=mark-packet chain=forward comment="Download Other TCP Packets($interface)" in-interface=$interface new-packet-mark="dl_other_tcp($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download ICMP Packets($interface)" in-interface=$interface new-packet-mark="dl_icmp($interface)" passthrough=no protocol=icmp

    # 上传方向规则
    add action=mark-packet chain=forward comment="Upload Real-time UDP Traffic Packets ($interface)" dst-port=53,3478,3479,3659,5060,27000-27050 new-packet-mark="up_realtime($interface)" out-interface=$interface passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload UDP Small Packets ($interface)" new-packet-mark="up_udp_small($interface)" out-interface=$interface packet-size=0-512 passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload UDP Large Packets ($interface)" new-packet-mark="up_udp_large($interface)" out-interface=$interface passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload Large File Traffic Packets ($interface)" connection-bytes=5000000-0 new-packet-mark="up_large_file($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload HTTP Traffic Packets ($interface)" connection-mark=http_conn new-packet-mark="up_http($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload TCP Small Packets ($interface)" connection-mark=tcp_conn new-packet-mark="up_tcp_small($interface)" out-interface=$interface packet-size=0-128 passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload Other TCP Packets ($interface)" new-packet-mark="up_other_tcp($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload ICMP Packets($interface)" out-interface=$interface new-packet-mark="up_icmp($interface)" passthrough=no protocol=icmp
    :log info "接口 $interface 上的 Mangle(IPv4) 标记创建完成。"
}
:log info "所有接口 $pppoeInterfaces 上的 Mangle(IPv4) 标记已经创建完成。"


# 清空 Mangle 列表(IPv6)
:log info "正在清理 Mangle(IPv6) 列表原有标记。"
/ipv6 firewall mangle remove [find comment~"Mark|Download|Upload"]

# 首先创建所有连接标记规则(只需要创建一次)
/ipv6 firewall mangle
add action=mark-connection chain=prerouting comment="Mark HTTP Connections" dst-port=80,8080,8000,8081,443,8443 new-connection-mark=http_conn protocol=tcp
add action=mark-connection chain=prerouting comment="Mark TCP Connections" connection-mark=!http_conn new-connection-mark=tcp_conn protocol=tcp

# 将接口列表转换为数组并遍历
:foreach interface in=$interfaceList do={
    # 下载方向规则
    add action=mark-packet chain=forward comment="Download Real-time UDP Packets ($interface)" src-port=53,3478,3479,3659,5060,27000-27050 in-interface=$interface new-packet-mark="dl_realtime($interface)" passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download UDP Small Packets ($interface)" in-interface=$interface new-packet-mark="dl_udp_small($interface)" packet-size=0-512 passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download UDP Large Packets ($interface)" in-interface=$interface new-packet-mark="dl_udp_large($interface)" passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Download Large File Packets ($interface)" connection-bytes=5000000-0 in-interface=$interface new-packet-mark="dl_large_file($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download HTTP Packets ($interface)" connection-mark=http_conn in-interface=$interface new-packet-mark="dl_http($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download TCP Small Packets ($interface)" connection-mark=tcp_conn in-interface=$interface new-packet-mark="dl_tcp_small($interface)" packet-size=0-128 passthrough=no protocol=tcp 
    add action=mark-packet chain=forward comment="Download Other TCP Packets($interface)" in-interface=$interface new-packet-mark="dl_other_tcp($interface)" passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Download ICMP Packets($interface)" in-interface=$interface new-packet-mark="dl_icmp($interface)" passthrough=no protocol=icmp

    # 上传方向规则
    add action=mark-packet chain=forward comment="Upload Real-time UDP Traffic Packets ($interface)" dst-port=53,3478,3479,3659,5060,27000-27050 new-packet-mark="up_realtime($interface)" out-interface=$interface passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload UDP Small Packets ($interface)" new-packet-mark="up_udp_small($interface)" out-interface=$interface packet-size=0-512 passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload UDP Large Packets ($interface)" new-packet-mark="up_udp_large($interface)" out-interface=$interface passthrough=no protocol=udp
    add action=mark-packet chain=forward comment="Upload Large File Traffic Packets ($interface)" connection-bytes=5000000-0 new-packet-mark="up_large_file($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload HTTP Traffic Packets ($interface)" connection-mark=http_conn new-packet-mark="up_http($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload TCP Small Packets ($interface)" connection-mark=tcp_conn new-packet-mark="up_tcp_small($interface)" out-interface=$interface packet-size=0-128 passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload Other TCP Packets ($interface)" new-packet-mark="up_other_tcp($interface)" out-interface=$interface passthrough=no protocol=tcp
    add action=mark-packet chain=forward comment="Upload ICMP Packets($interface)" out-interface=$interface new-packet-mark="up_icmp($interface)" passthrough=no protocol=icmp
    :log info "接口 $interface 上的 Mangle(IPv6) 标记创建完成。"
}
:log info "所有接口 $pppoeInterfaces 上的 Mangle(IPv6) 标记已经创建完成。"


# ==================== 清理现有配置 ====================
:log info "开始清理现有的队列配置..."
/queue type remove [find name~"PCQ-"]
/queue tree remove [find]
:log info "队列配置清理完成"
# ==================== 创建队列类型 ====================
:log info "创建队列类型..."
/queue type
add kind=pcq name=PCQ-Download pcq-classifier=dst-address
add kind=pcq name=PCQ-Upload pcq-classifier=src-address
# 如果内网用户较多时,比较学校等机构中,10000KiB可以适当再改大
set [find name="PCQ-Download"] pcq-total-limit=10000KiB
set [find name="PCQ-Upload"] pcq-total-limit=10000KiB

# ==================== 为每个PPPoE接口创建队列树 ====================
# 将接口列表转换为数组并遍历
:for idx from=0 to=([:len $interfaceList] - 1) do={
    :local interface ($interfaceList->$idx)

    :if ($idx < [:len $speedDownloadList]) do={
        :set defaultDownloadSpeed ($speedDownloadList->$idx)
    }
    :if ($idx < [:len $speedUploadList]) do={
        :set defaultUploadSpeed ($speedUploadList->$idx)
    }

    :log info "为接口 $interface 创建队列树配置..."
    #=================== 计算出常用的带宽 =================
    :local  downloadMbps100  ($defaultDownloadSpeed . "M")
    :local  downloadMbps75   ((($defaultDownloadSpeed *3 / 4 +5)/10*10) . "M")
    :local  downloadMbps50   ((($defaultDownloadSpeed / 2 +5)/10*10) . "M")
    :local  downloadMbps25   ((($defaultDownloadSpeed / 4 +5)/10*10) . "M")

    :local  uploadMbps100  ($defaultUploadSpeed . "M")
    :local  uploadMbps75  ((($defaultUploadSpeed *3 / 4 +5) /10*10) . "M")
    :local  uploadMbps50  ((($defaultUploadSpeed  / 2 +5) /10*10) . "M")
    :local  uploadMbps25  ((($defaultUploadSpeed  / 4 +5) /10*10) . "M")
    # ==================== 下载队列树 ====================
    /queue tree
    # 下载根队列(所有下载流量共享同一个根,基于桥接接口)
    add name="download_root($interface)" parent=$bridgeInterface priority=1 queue=default
    
    # TCP小包(最高优先级)
    add burst-limit=$downloadMbps75 burst-threshold=$downloadMbps25 burst-time=30s limit-at=2M max-limit=\
        $downloadMbps50 name="tcp_small_dl($interface)" packet-mark="dl_tcp_small($interface)" parent="download_root($interface)" \
        priority=1 queue=default
    
    # 实时UDP流量(最高优先级)
    add burst-limit=$downloadMbps75 burst-threshold=$downloadMbps25 burst-time=30s limit-at=2M \
        max-limit=$downloadMbps50 name="realtime_dl($interface)" packet-mark="dl_realtime($interface)" parent=\
        "download_root($interface)" priority=1 queue=default
    
    # UDP小包(高优先级)
    add burst-limit=$downloadMbps75 burst-threshold=$downloadMbps25 burst-time=30s limit-at=2M \
        max-limit=$downloadMbps50 name="udp_small_dl($interface)" packet-mark="dl_udp_small($interface)" parent=\
        "download_root($interface)" priority=2 queue=default

    # ICMP(高优先级)
    add burst-limit=$downloadMbps75 burst-threshold=$downloadMbps25 burst-time=30s limit-at=2M \
        max-limit=$downloadMbps50 name="icmp_dl($interface)" packet-mark="dl_icmp($interface)" parent=\
        "download_root($interface)" priority=2 queue=default
    
    # HTTP流量(中优先级)
    add limit-at=5M max-limit=$downloadMbps100 name="http_dl($interface)" packet-mark="dl_http($interface)" \
        parent="download_root($interface)" priority=3 queue=PCQ-Download
    
    # 大文件流量(中低优先级)
    add limit-at=5M max-limit=$downloadMbps100 name="large_file_dl($interface)" packet-mark="dl_large_file($interface)" \
        parent="download_root($interface)" priority=6 queue=PCQ-Download
    
    # UDP大包(低优先级)
    add limit-at=5M max-limit=$downloadMbps100 name="udp_large_dl($interface)" packet-mark="dl_udp_large($interface)" \
        parent="download_root($interface)" priority=7 queue=PCQ-Download
    
    # 其他TCP流量(中低优先级)
    add limit-at=2M max-limit=$downloadMbps100 name="other_tcp_dl($interface)" packet-mark="dl_other_tcp($interface)" \
        parent="download_root($interface)" priority=5 queue=PCQ-Download
    
    # ==================== 上传队列树 ====================
    # 上传根队列 - 直接使用接口名称作为parent
    add name="upload_root($interface)" parent=$interface priority=1 queue=default
    
    # TCP小包上传(最高优先级)
    add limit-at=1M max-limit=$uploadMbps50 name="tcp_small_ul($interface)" packet-mark="up_tcp_small($interface)" \
        parent="upload_root($interface)" priority=1 queue=default
    
    # 实时UDP流量上传(最高优先级)
    add limit-at=1M max-limit=$uploadMbps50 name="realtime_ul($interface)" packet-mark=\
        "up_realtime($interface)" parent="upload_root($interface)" priority=1 queue=default
    
    # UDP小包上传(高优先级)
    add limit-at=1M max-limit=$uploadMbps50 name="udp_small_ul($interface)" packet-mark="up_udp_small($interface)" \
        parent="upload_root($interface)" priority=2 queue=default

    # ICMP(高优先级)
    add limit-at=1M max-limit=$uploadMbps50 name="icmp_ul($interface)" packet-mark="up_icmp($interface)" \
        parent="upload_root($interface)" priority=2 queue=default
    
    # HTTP流量上传(中优先级)
    add limit-at=2M max-limit=$uploadMbps100 name="http_ul($interface)" packet-mark="up_http($interface)" \
        parent="upload_root($interface)" priority=3 queue=PCQ-Upload
    
    # 大文件流量上传(中优先级)
    add limit-at=2M max-limit=$uploadMbps100 name="large_file_ul($interface)" packet-mark="up_large_file($interface)" \
        parent="upload_root($interface)" priority=5 queue=PCQ-Upload
    
    # UDP大包上传(低优先级)
    add limit-at=1M max-limit=$uploadMbps100 name="udp_large_ul($interface)" packet-mark="up_udp_large($interface)" \
        parent="upload_root($interface)" priority=6 queue=PCQ-Upload
    
    # 其他TCP流量上传(中优先级)
    add limit-at=1M max-limit=$uploadMbps100 name="other_tcp_ul($interface)" packet-mark="up_other_tcp($interface)" \
        parent="upload_root($interface)" priority=5 queue=PCQ-Upload
    
    :log info "接口 $interface 的队列树配置创建完成"
}

 

正文完
 0