├── ChangeLog ├── README.md ├── luci-app-nft-qos ├── Makefile ├── luasrc │ ├── controller │ │ └── nft-qos.lua │ ├── model │ │ └── cbi │ │ │ └── nft-qos │ │ │ └── nft-qos.lua │ └── view │ │ └── nft-qos │ │ ├── rate.htm │ │ └── rate.htm.old └── po │ ├── templates │ └── nft-qos.pot │ └── zh-cn │ └── nft-qos.po ├── package ├── Makefile └── files │ ├── lib │ ├── core.sh │ ├── dynamic.sh │ ├── monitor.sh │ ├── priority.sh │ └── static.sh │ ├── nft-qos-dynamic.hotplug │ ├── nft-qos-monitor.hotplug │ ├── nft-qos.config │ └── nft-qos.init └── previews ├── dynamic-qos.png ├── realtime-rate.gif ├── static-qos.png └── traffic-priority.png /ChangeLog: -------------------------------------------------------------------------------- 1 | 2 | ## 2018-11-07 1.0 initial commit 3 | 4 | ## 2018-11-08 1.1 add luci-app-nft-qos 5 | 6 | ## 2018-11-08 1.2 fix rate limit ineffective on remote network 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QoS over Nftables 2 | 3 | ## About 4 | nft-qos and luci-app-nft-qos is a qos implementation over nftables project on OpenWrt and LuCI. 5 | 6 | **NOTE!!!** This packages is merged upstream, please visit [openwrt/packages](https://github.com/openwrt/packages) and [openwrt/luci](https://github.com/openwrt/luci) for more details. 7 | 8 | ## Reference 9 | * [The nftables project](https://netfilter.org/projects/nftables/index.html). 10 | 11 | * [Quick reference nftables in 10 minutes](https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes). 12 | 13 | ## Contact 14 | * Bug Report : https://github.com/rosywrt/nft-qos/issues 15 | 16 | * QQ Gourp : 428742246 17 | 18 | ## License 19 | 20 | Luci-app-nft-qos / nft-qos : Copyright 2018 RosyWrt 21 | 22 | Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 23 | 24 | ## Realtime Rate 25 |
realtime rate
26 | 27 | ## Dynamic QoS 28 |
dynamic qos
29 | 30 | ## Static QoS 31 |
static qos
32 | 33 | ## Traffic priority (1 is the highest) 34 |
traffic priority
35 | -------------------------------------------------------------------------------- /luci-app-nft-qos/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2008-2014 The LuCI Team 3 | # 4 | # This is free software, licensed under the Apache License, Version 2.0 . 5 | # 6 | 7 | include $(TOPDIR)/rules.mk 8 | 9 | LUCI_TITLE:=Qos over Nftables 10 | LUCI_DEPENDS:=+nft-qos 11 | 12 | include ../../luci.mk 13 | 14 | # call BuildPackage - OpenWrt buildroot signature 15 | -------------------------------------------------------------------------------- /luci-app-nft-qos/luasrc/controller/nft-qos.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2018 Rosy Song 2 | -- Licensed to the public under the Apache License 2.0. 3 | 4 | module("luci.controller.nft-qos", package.seeall) 5 | 6 | function index() 7 | if not nixio.fs.access("/etc/config/nft-qos") then 8 | return 9 | end 10 | 11 | entry({"admin", "status", "realtime", "rate"}, 12 | template("nft-qos/rate"), _("Rate"), 5).leaf = true 13 | entry({"admin", "status", "realtime", "rate_status"}, 14 | call("action_rate")).leaf = true 15 | 16 | entry({"admin", "services", "nft-qos"}, cbi("nft-qos/nft-qos"), 17 | _("Qos over Nftables"), 60) 18 | 19 | -- entry({"admin", "services", "nft-qos", "rate-limit"}, 20 | -- cbi("rate-limit"), _("Rate Limit"), 10).leaf = true 21 | 22 | -- entry({"admin", "services", "nft-qos", "dynamic-rate-limit"}, 23 | -- cbi("dynamic-rate-limit"), _("Dynamic Rate Limit"), 20).leaf = true 24 | 25 | -- entry({"admin", "services", "nft-qos", "priority"}, 26 | -- cbi("priority"), _("Traffic Priority"), 30).leaf = true 27 | end 28 | 29 | function action_rate() 30 | luci.http.prepare_content("application/json") 31 | 32 | local bwc = io.popen("nft list ruleset -j 2>/dev/null") 33 | if bwc then 34 | 35 | while true do 36 | local ln = bwc:read("*l") 37 | if not ln then break end 38 | luci.http.write(ln) 39 | end 40 | 41 | bwc:close() 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /luci-app-nft-qos/luasrc/model/cbi/nft-qos/nft-qos.lua: -------------------------------------------------------------------------------- 1 | -- Copyright 2018 Rosy Song 2 | -- Licensed to the public under the Apache License 2.0. 3 | 4 | local uci = require("luci.model.uci").cursor() 5 | local wa = require("luci.tools.webadmin") 6 | local ipc = require("luci.ip") 7 | 8 | local def_rate_dl = uci:get("nft-qos", "default", "static_rate_dl") 9 | local def_rate_ul = uci:get("nft-qos", "default", "static_rate_ul") 10 | local def_unit_dl = uci:get("nft-qos", "default", "static_unit_dl") 11 | local def_unit_ul = uci:get("nft-qos", "default", "static_unit_ul") 12 | 13 | local def_up = uci:get("nft-qos", "default", "dynamic_bw_up") 14 | local def_down = uci:get("nft-qos", "default", "dynamic_bw_down") 15 | 16 | local limit_enable = uci:get("nft-qos", "default", "limit_enable") 17 | local limit_type = uci:get("nft-qos", "default", "limit_type") 18 | local enable_priority = uci:get("nft-qos", "default", "priority_enable") 19 | 20 | m = Map("nft-qos", translate("Qos over Nftables")) 21 | 22 | -- 23 | -- Taboptions 24 | -- 25 | s = m:section(TypedSection, "default", translate("NFT-QoS Settings")) 26 | s.addremove = false 27 | s.anonymous = true 28 | 29 | s:tab("limit", "Limit Rate") 30 | s:tab("priority", "Traffic Priority") 31 | 32 | -- 33 | -- Static 34 | -- 35 | o = s:taboption("limit", Flag, "limit_enable", translate("Limit Enable"), translate("Enable Limit Rate Feature")) 36 | o.default = limit_enable or o.enabled 37 | o.rmempty = false 38 | 39 | o = s:taboption("limit", ListValue, "limit_type", translate("Limit Type"), translate("Type of Limit Rate")) 40 | o.default = limit_static or "static" 41 | o:depends("limit_enable","1") 42 | o:value("static", "Static") 43 | o:value("dynamic", "Dynamic") 44 | 45 | o = s:taboption("limit", Value, "static_rate_dl", translate("Default Download Rate"), translate("Default value for download rate")) 46 | o.datatype = "uinteger" 47 | o.default = def_rate_dl or '50' 48 | o:depends("limit_type","static") 49 | 50 | o = s:taboption("limit", ListValue, "static_unit_dl", translate("Default Download Unit"), translate("Default unit for download rate")) 51 | o.default = def_unit_dl or "kbytes" 52 | o:depends("limit_type","static") 53 | o:value("bytes", "Bytes/s") 54 | o:value("kbytes", "KBytes/s") 55 | o:value("mbytes", "MBytes/s") 56 | 57 | o = s:taboption("limit", Value, "static_rate_ul", translate("Default Upload Rate"), translate("Default value for upload rate")) 58 | o.datatype = "uinteger" 59 | o.default = def_rate_ul or '50' 60 | o:depends("limit_type","static") 61 | 62 | o = s:taboption("limit", ListValue, "static_unit_ul", translate("Default Upload Unit"), translate("Default unit for upload rate")) 63 | o.default = def_unit_ul or "kbytes" 64 | o:depends("limit_type","static") 65 | o:value("bytes", "Bytes/s") 66 | o:value("kbytes", "KBytes/s") 67 | o:value("mbytes", "MBytes/s") 68 | 69 | -- 70 | -- Dynamic 71 | -- 72 | o = s:taboption("limit", Value, "dynamic_bw_down", translate("Download Bandwidth (Mbps)"), translate("Default value for download bandwidth")) 73 | o.default = def_up or '100' 74 | o.datatype = "uinteger" 75 | o:depends("limit_type","dynamic") 76 | 77 | o = s:taboption("limit", Value, "dynamic_bw_up", translate("Upload Bandwidth (Mbps)"), translate("Default value for upload bandwidth")) 78 | o.default = def_down or '100' 79 | o.datatype = "uinteger" 80 | o:depends("limit_type","dynamic") 81 | 82 | o = s:taboption("limit", Value, "dynamic_cidr", translate("Target Network (IPv4/MASK)"), translate("Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc")) 83 | o.datatype = "cidr4" 84 | ipc.routes({ family = 4, type = 1 }, function(rt) o.default = rt.dest end) 85 | o:depends("limit_type","dynamic") 86 | 87 | o = s:taboption("limit", Value, "dynamic_cidr6", translate("Target Network6 (IPv6/MASK)"), translate("Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc")) 88 | o.datatype = "cidr6" 89 | o:depends("limit_type","dynamic") 90 | 91 | o = s:taboption("limit", DynamicList, "limit_whitelist", translate("White List for Limit Rate")) 92 | o.datatype = "ipaddr" 93 | o:depends("limit_enable","1") 94 | 95 | -- 96 | -- Priority 97 | -- 98 | o = s:taboption("priority", Flag, "priority_enable", translate("Enable Traffic Priority"), translate("Enable this feature")) 99 | o.default = enable_priority or o.enabled 100 | o.rmempty = false 101 | 102 | o = s:taboption("priority", ListValue, "priority_netdev", translate("Default Network Interface"), translate("Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc")) 103 | o:depends("priority_enable", "1") 104 | wa.cbi_add_networks(o) 105 | 106 | -- 107 | -- Static Limit Rate - Download Rate 108 | -- 109 | if limit_enable == "1" and limit_type == "static" then 110 | 111 | x = m:section(TypedSection, "download", translate("Static QoS-Download Rate")) 112 | x.anonymous = true 113 | x.addremove = true 114 | x.template = "cbi/tblsection" 115 | 116 | o = x:option(Value, "hostname", translate("Hostname")) 117 | o.datatype = "hostname" 118 | o.default = 'undefined' 119 | 120 | o = x:option(Value, "ipaddr", translate("IP Address")) 121 | o.datatype = "ipaddr" 122 | if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then 123 | o.titleref = luci.dispatcher.build_url("admin", "status", "overview") 124 | end 125 | 126 | o = x:option(Value, "macaddr", translate("MAC (optional)")) 127 | o.rmempty = true 128 | o.datatype = "macaddr" 129 | 130 | o = x:option(Value, "rate", translate("Rate")) 131 | o.default = def_rate_dl or '50' 132 | o.size = 4 133 | o.datatype = "uinteger" 134 | 135 | o = x:option(ListValue, "unit", translate("Unit")) 136 | o.default = def_unit_dl or "kbytes" 137 | o:value("bytes", "Bytes/s") 138 | o:value("kbytes", "KBytes/s") 139 | o:value("mbytes", "MBytes/s") 140 | 141 | -- 142 | -- Static Limit Rate - Upload Rate 143 | -- 144 | y = m:section(TypedSection, "upload", translate("Static QoS-Upload Rate")) 145 | y.anonymous = true 146 | y.addremove = true 147 | y.template = "cbi/tblsection" 148 | 149 | o = y:option(Value, "hostname", translate("Hostname")) 150 | o.datatype = "hostname" 151 | o.default = 'undefined' 152 | 153 | o = y:option(Value, "ipaddr", translate("IP Address")) 154 | o.datatype = "ipaddr" 155 | if nixio.fs.access("/tmp/dhcp.leases") or nixio.fs.access("/var/dhcp6.leases") then 156 | o.titleref = luci.dispatcher.build_url("admin", "status", "overview") 157 | end 158 | 159 | o = y:option(Value, "macaddr", translate("MAC (optional)")) 160 | o.rmempty = true 161 | o.datatype = "macaddr" 162 | 163 | o = y:option(Value, "rate", translate("Rate")) 164 | o.default = def_rate_ul or '50' 165 | o.size = 4 166 | o.datatype = "uinteger" 167 | 168 | o = y:option(ListValue, "unit", translate("Unit")) 169 | o.default = def_unit_ul or "kbytes" 170 | o:value("bytes", "Bytes/s") 171 | o:value("kbytes", "KBytes/s") 172 | o:value("mbytes", "MBytes/s") 173 | 174 | end 175 | 176 | -- 177 | -- Traffic Priority Settings 178 | -- 179 | if enable_priority == "1" then 180 | 181 | s = m:section(TypedSection, "priority", translate("Traffic Priority Settings")) 182 | s.anonymous = true 183 | s.addremove = true 184 | s.template = "cbi/tblsection" 185 | 186 | o = s:option(ListValue, "protocol", translate("Protocol")) 187 | o.default = "tcp" 188 | o:value("tcp", "TCP") 189 | o:value("udp", "UDP") 190 | o:value("udplite", "UDP-Lite") 191 | o:value("sctp", "SCTP") 192 | o:value("dccp", "DCCP") 193 | 194 | o = s:option(ListValue, "priority", translate("Priority")) 195 | o.default = "1" 196 | o:value("-400", "1") 197 | o:value("-300", "2") 198 | o:value("-225", "3") 199 | o:value("-200", "4") 200 | o:value("-150", "5") 201 | o:value("-100", "6") 202 | o:value("0", "7") 203 | o:value("50", "8") 204 | o:value("100", "9") 205 | o:value("225", "10") 206 | o:value("300", "11") 207 | 208 | o = s:option(Value, "service", translate("Service"), translate("e.g. https, 23, (separator is comma)")) 209 | o.default = '?' 210 | 211 | o = s:option(Value, "comment", translate("Comment")) 212 | o.default = '?' 213 | 214 | end 215 | 216 | return m 217 | -------------------------------------------------------------------------------- /luci-app-nft-qos/luasrc/view/nft-qos/rate.htm: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2018 Rosy Song 3 | Licensed to the public under the Apache License 2.0. 4 | -%> 5 | 6 | <%+header%> 7 | 8 | 124 | 125 |

<%:Realtime Rate%>

126 | 127 |
<%:This page gives an overview over currently download/upload rate.%>
128 | 129 |
130 | 131 |
132 |
133 |
134 |
<%:IP Address%>
135 |
<%:Download Rate%>
136 |
<%:Bytes Total%>
137 |
<%:Packets Total%>
138 |
139 | 140 |
141 |
142 | <%:Collecting data...%> 143 |
144 |
145 |
146 |
147 | 148 |
149 |
150 |
151 |
<%:IP Address%>
152 |
<%:Upload Rate%>
153 |
<%:Bytes Total%>
154 |
<%:Packets Total%>
155 |
156 | 157 |
158 |
159 | <%:Collecting data...%> 160 |
161 |
162 |
163 |
164 | 165 |
166 | 167 | <%+footer%> 168 | -------------------------------------------------------------------------------- /luci-app-nft-qos/luasrc/view/nft-qos/rate.htm.old: -------------------------------------------------------------------------------- 1 | <%# 2 | Copyright 2018 Rosy Song 3 | Licensed to the public under the Apache License 2.0. 4 | -%> 5 | 6 | <%+header%> 7 | 8 | 9 | 130 | 131 |

<%:Realtime Rate%>

132 | 133 |
<%:This page gives an overview over currently download/upload rate.%>
134 | 135 |
136 | 137 |
138 |
139 |
140 |
<%:IP Address%>
141 |
<%:Download Rate%>
142 |
<%:Bytes Total%>
143 |
<%:Packets Total%>
144 |
145 | 146 |
<%:Collecting data...%>
147 |
148 |
149 | 150 |
151 |
152 |
<%:IP Address%>
153 |
<%:Upload Rate%>
154 |
<%:Bytes Total%>
155 |
<%:Packets Total%>
156 |
157 | 158 |
<%:Collecting data...%>
159 |
160 |
161 |
162 | 163 |
164 | 165 | <%+footer%> 166 | -------------------------------------------------------------------------------- /luci-app-nft-qos/po/templates/nft-qos.pot: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "Content-Type: text/plain; charset=UTF-8" 3 | 4 | msgid "Bytes Total" 5 | msgstr "" 6 | 7 | msgid "Collecting data..." 8 | msgstr "" 9 | 10 | msgid "Comment" 11 | msgstr "" 12 | 13 | msgid "Default Download Rate" 14 | msgstr "" 15 | 16 | msgid "Default Download Unit" 17 | msgstr "" 18 | 19 | msgid "Default Network Interface" 20 | msgstr "" 21 | 22 | msgid "Default Upload Rate" 23 | msgstr "" 24 | 25 | msgid "Default Upload Unit" 26 | msgstr "" 27 | 28 | msgid "Default unit for download rate" 29 | msgstr "" 30 | 31 | msgid "Default unit for upload rate" 32 | msgstr "" 33 | 34 | msgid "Default value for download bandwidth" 35 | msgstr "" 36 | 37 | msgid "Default value for download rate" 38 | msgstr "" 39 | 40 | msgid "Default value for upload bandwidth" 41 | msgstr "" 42 | 43 | msgid "Default value for upload rate" 44 | msgstr "" 45 | 46 | msgid "Download Bandwidth (Mbps)" 47 | msgstr "" 48 | 49 | msgid "Download Rate" 50 | msgstr "" 51 | 52 | msgid "Dynamic Rate Limit" 53 | msgstr "" 54 | 55 | msgid "Enable Limit Rate Feature" 56 | msgstr "" 57 | 58 | msgid "Enable Traffic Priority" 59 | msgstr "" 60 | 61 | msgid "Enable this feature" 62 | msgstr "" 63 | 64 | msgid "Hostname" 65 | msgstr "" 66 | 67 | msgid "IP Address" 68 | msgstr "" 69 | 70 | msgid "Limit Enable" 71 | msgstr "" 72 | 73 | msgid "Limit Type" 74 | msgstr "" 75 | 76 | msgid "MAC (optional)" 77 | msgstr "" 78 | 79 | msgid "MB" 80 | msgstr "" 81 | 82 | msgid "NFT-QoS Settings" 83 | msgstr "" 84 | 85 | msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" 86 | msgstr "" 87 | 88 | msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" 89 | msgstr "" 90 | 91 | msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" 92 | msgstr "" 93 | 94 | msgid "Packets Total" 95 | msgstr "" 96 | 97 | msgid "Priority" 98 | msgstr "" 99 | 100 | msgid "Protocol" 101 | msgstr "" 102 | 103 | msgid "Qos over Nftables" 104 | msgstr "" 105 | 106 | msgid "Rate" 107 | msgstr "" 108 | 109 | msgid "Rate Limit" 110 | msgstr "" 111 | 112 | msgid "Realtime Rate" 113 | msgstr "" 114 | 115 | msgid "Service" 116 | msgstr "" 117 | 118 | msgid "Static QoS-Download Rate" 119 | msgstr "" 120 | 121 | msgid "Static QoS-Upload Rate" 122 | msgstr "" 123 | 124 | msgid "Target Network (IPv4/MASK)" 125 | msgstr "" 126 | 127 | msgid "Target Network6 (IPv6/MASK)" 128 | msgstr "" 129 | 130 | msgid "This page gives an overview over currently download/upload rate." 131 | msgstr "" 132 | 133 | msgid "Traffic Priority" 134 | msgstr "" 135 | 136 | msgid "Traffic Priority Settings" 137 | msgstr "" 138 | 139 | msgid "Type of Limit Rate" 140 | msgstr "" 141 | 142 | msgid "Unit" 143 | msgstr "" 144 | 145 | msgid "Upload Bandwidth (Mbps)" 146 | msgstr "" 147 | 148 | msgid "Upload Rate" 149 | msgstr "" 150 | 151 | msgid "White List for Limit Rate" 152 | msgstr "" 153 | 154 | msgid "e.g. https, 23, (separator is comma)" 155 | msgstr "" 156 | 157 | msgid "kB" 158 | msgstr "" 159 | -------------------------------------------------------------------------------- /luci-app-nft-qos/po/zh-cn/nft-qos.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Content-Type: text/plain; charset=UTF-8\n" 4 | "Project-Id-Version: \n" 5 | "POT-Creation-Date: \n" 6 | "PO-Revision-Date: \n" 7 | "Language-Team: \n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "X-Generator: Poedit 2.0.3\n" 11 | "Last-Translator: \n" 12 | "Plural-Forms: nplurals=1; plural=0;\n" 13 | "Language: zh_CN\n" 14 | 15 | msgid "Bytes Total" 16 | msgstr "字节总数" 17 | 18 | msgid "Collecting data..." 19 | msgstr "正在收集数据" 20 | 21 | msgid "Comment" 22 | msgstr "注释" 23 | 24 | msgid "Default Download Rate" 25 | msgstr "默认下载速率" 26 | 27 | msgid "Default Download Unit" 28 | msgstr "默认下载速率单位" 29 | 30 | msgid "Default Network Interface" 31 | msgstr "默认网络接口" 32 | 33 | msgid "Default Upload Rate" 34 | msgstr "默认上传速率" 35 | 36 | msgid "Default Upload Unit" 37 | msgstr "默认上传速率单位" 38 | 39 | msgid "Default unit for download rate" 40 | msgstr "默认的下载速率单位" 41 | 42 | msgid "Default unit for upload rate" 43 | msgstr "默认的上传速率单位" 44 | 45 | msgid "Default value for download bandwidth" 46 | msgstr "下载带宽的默认值" 47 | 48 | msgid "Default value for download rate" 49 | msgstr "下载速率的默认值" 50 | 51 | msgid "Default value for upload bandwidth" 52 | msgstr "上传带宽的默认值" 53 | 54 | msgid "Default value for upload rate" 55 | msgstr "上传速率的默认值" 56 | 57 | msgid "Download Bandwidth (Mbps)" 58 | msgstr "下载带宽 (Mbps)" 59 | 60 | msgid "Download Rate" 61 | msgstr "下载速率" 62 | 63 | msgid "Dynamic Rate Limit" 64 | msgstr "动态QoS" 65 | 66 | msgid "Enable Limit Rate Feature" 67 | msgstr "开启速率限制功能" 68 | 69 | msgid "Enable Traffic Priority" 70 | msgstr "开启流量优先级" 71 | 72 | msgid "Enable this feature" 73 | msgstr "开启这个功能" 74 | 75 | msgid "Hostname" 76 | msgstr "主机名" 77 | 78 | msgid "IP Address" 79 | msgstr "IP地址" 80 | 81 | msgid "Limit Enable" 82 | msgstr "限速开启" 83 | 84 | msgid "Limit Type" 85 | msgstr "限速类型" 86 | 87 | msgid "MAC (optional)" 88 | msgstr "物理地址(可选)" 89 | 90 | msgid "MB" 91 | msgstr "MB" 92 | 93 | msgid "NFT-QoS Settings" 94 | msgstr "NFT-QoS 设置" 95 | 96 | msgid "Network Interface for Traffic Shaping, e.g. br-lan, eth0.1, eth0, etc" 97 | msgstr "流量整形的目标网络接口, 例如, br-lan, eth0.1, eth0, etc" 98 | 99 | msgid "Network to be apply, e.g. 192.168.1.0/24, 10.2.0.0/16, etc" 100 | msgstr "将要应用规则的网络, 例如, 192.168.1.0/24, 10.2.0.0/16, 等等" 101 | 102 | msgid "Network to be apply, e.g. AAAA::BBBB/64, CCCC::1/128, etc" 103 | msgstr "将要应用规则的网络, 例如, AAAA::BBBB/64, CCCC::1/128, 等等" 104 | 105 | msgid "Packets Total" 106 | msgstr "数据包总数" 107 | 108 | msgid "Priority" 109 | msgstr "优先级" 110 | 111 | msgid "Protocol" 112 | msgstr "协议" 113 | 114 | msgid "Qos over Nftables" 115 | msgstr "QoS Nftables版" 116 | 117 | msgid "Rate" 118 | msgstr "速率" 119 | 120 | msgid "Rate Limit" 121 | msgstr "速率限制" 122 | 123 | msgid "Realtime Rate" 124 | msgstr "实时速率显示" 125 | 126 | msgid "Service" 127 | msgstr "服务/端口" 128 | 129 | msgid "Static QoS-Download Rate" 130 | msgstr "静态QoS-下载速率" 131 | 132 | msgid "Static QoS-Upload Rate" 133 | msgstr "静态QoS-上传速率" 134 | 135 | msgid "Target Network (IPv4/MASK)" 136 | msgstr "目标网络(IPv4地址/掩码)" 137 | 138 | msgid "Target Network6 (IPv6/MASK)" 139 | msgstr "目标网络v6(IPv6地址/掩码)" 140 | 141 | msgid "This page gives an overview over currently download/upload rate." 142 | msgstr "该页面提供了当前上传和下载速率的一个总览" 143 | 144 | msgid "Traffic Priority" 145 | msgstr "流量优先级" 146 | 147 | msgid "Traffic Priority Settings" 148 | msgstr "流量优先级设置" 149 | 150 | msgid "Type of Limit Rate" 151 | msgstr "限速的类型" 152 | 153 | msgid "Unit" 154 | msgstr "单位" 155 | 156 | msgid "Upload Bandwidth (Mbps)" 157 | msgstr "上传带宽 (Mbps)" 158 | 159 | msgid "Upload Rate" 160 | msgstr "上传速率" 161 | 162 | msgid "White List for Limit Rate" 163 | msgstr "限速白名单" 164 | 165 | msgid "e.g. https, 23, (separator is comma)" 166 | msgstr "例如, https, 23 (用逗号分隔)" 167 | 168 | msgid "kB" 169 | msgstr "kB" 170 | -------------------------------------------------------------------------------- /package/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 rosysong@rosinson.com 3 | # 4 | # This is free software, licensed under the GNU General Public License v2. 5 | # See /LICENSE for more information. 6 | # 7 | 8 | include $(TOPDIR)/rules.mk 9 | 10 | PKG_NAME:=nft-qos 11 | PKG_VERSION:=1.0.0 12 | PKG_RELEASE:=1 13 | PKG_LICENSE:=GPL-2.0 14 | 15 | PKG_MAINTAINER:=Rosy Song 16 | 17 | PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 18 | 19 | include $(INCLUDE_DIR)/package.mk 20 | 21 | define Package/nft-qos 22 | SECTION:=utils 23 | CATEGORY:=Base system 24 | DEPENDS:=+nftables +kmod-nft-netdev +kmod-nft-bridge 25 | TITLE:=QoS scripts over nftables 26 | endef 27 | 28 | define Package/nft-qos/description 29 | This package provides implementation for qos over nftables. 30 | Currently, static/dynamic qos and traffic shaping are supported. 31 | endef 32 | 33 | define Package/nft-qos/conffiles 34 | /etc/config/nft-qos 35 | endef 36 | 37 | define Build/Prepare 38 | endef 39 | 40 | define Build/Configure 41 | endef 42 | 43 | define Build/Compile 44 | endef 45 | 46 | define Package/nft-qos/install 47 | $(INSTALL_DIR) $(1)/lib/nft-qos 48 | $(INSTALL_DATA) ./files/lib/* $(1)/lib/nft-qos/ 49 | $(INSTALL_DIR) $(1)/etc/config 50 | $(INSTALL_CONF) ./files/nft-qos.config $(1)/etc/config/nft-qos 51 | $(INSTALL_DIR) $(1)/etc/init.d 52 | $(INSTALL_BIN) ./files/nft-qos.init $(1)/etc/init.d/nft-qos 53 | $(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp 54 | $(INSTALL_BIN) ./files/nft-qos-monitor.hotplug $(1)/etc/hotplug.d/dhcp/00-nft-qos-monitor 55 | $(INSTALL_BIN) ./files/nft-qos-dynamic.hotplug $(1)/etc/hotplug.d/dhcp/01-nft-qos-dynamic 56 | endef 57 | 58 | $(eval $(call BuildPackage,nft-qos)) 59 | -------------------------------------------------------------------------------- /package/files/lib/core.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | # for uci_validate_section() 7 | . /lib/functions/procd.sh 8 | 9 | NFT_QOS_HAS_BRIDGE= 10 | NFT_QOS_INET_FAMILY=ip 11 | NFT_QOS_SCRIPT_TEXT= 12 | NFT_QOS_SCRIPT_FILE=/tmp/qos.nft 13 | 14 | qosdef_appendx() { # 15 | NFT_QOS_SCRIPT_TEXT="$NFT_QOS_SCRIPT_TEXT""$1" 16 | } 17 | 18 | qosdef_append_chain_def() { # 19 | qosdef_appendx "\t\ttype $1 hook $2 priority $3; policy $4;\n" 20 | } 21 | 22 | qosdef_append_chain_ingress() { # 23 | qosdef_appendx "\t\ttype $1 hook ingress device $2 priority $3; policy $4;\n" 24 | } 25 | 26 | # qosdef_append_rule_{MATCH}_{STATEMENT} 27 | qosdef_append_rule_ip_limit() { # 28 | local ipaddr=$1 29 | local operator=$2 30 | local unit=$3 31 | local rate=$4 32 | 33 | qosdef_appendx \ 34 | "\t\tip $operator $ipaddr limit rate over $rate $unit/second drop\n" 35 | } 36 | 37 | # qosdef_append_rule_{MATCH}_{POLICY} 38 | qosdef_append_rule_ip_policy() { # 39 | qosdef_appendx "\t\tip $1 $2 $3\n" 40 | } 41 | 42 | _handle_limit_whitelist() { # 43 | local ipaddr=$1 44 | local operator 45 | 46 | [ -z "$ipaddr" ] && return 47 | 48 | case "$2" in 49 | download) operator="daddr";; 50 | upload) operator="saddr";; 51 | esac 52 | 53 | qosdef_append_rule_ip_policy $operator $ipaddr accept 54 | } 55 | 56 | qosdef_append_rule_limit_whitelist() { # 57 | config_list_foreach default limit_whitelist _handle_limit_whitelist $1 58 | } 59 | 60 | qosdef_flush_table() { # 61 | nft flush table $1 $2 2>/dev/null 62 | } 63 | 64 | qosdef_remove_table() { #
65 | nft delete table $1 $2 2>/dev/null 66 | } 67 | 68 | qosdef_init_header() { # add header for nft script 69 | qosdef_appendx "#!/usr/sbin/nft -f\n" 70 | qosdef_appendx "# Copyright (C) 2018 rosysong@rosinson.com\n" 71 | qosdef_appendx "#\n\n" 72 | } 73 | 74 | qosdef_init_env() { 75 | # check interface type of lan 76 | local lt="$(uci_get "network.lan.type")" 77 | [ "$lt" = "bridge" ] && export NFT_QOS_HAS_BRIDGE="y" 78 | 79 | # check if ipv6 support 80 | [ -e /proc/sys/net/ipv6 ] && export NFT_QOS_INET_FAMILY="inet" 81 | } 82 | 83 | qosdef_clean_cache() { 84 | rm -f $NFT_QOS_SCRIPT_FILE 85 | } 86 | 87 | qosdef_init_done() { 88 | echo -e $NFT_QOS_SCRIPT_TEXT > $NFT_QOS_SCRIPT_FILE 2>/dev/null 89 | } 90 | 91 | qosdef_start() { 92 | nft -f $NFT_QOS_SCRIPT_FILE 2>/dev/null 93 | } 94 | -------------------------------------------------------------------------------- /package/files/lib/dynamic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/nft-qos/core.sh 7 | 8 | # return average rate for dhcp leases 9 | qosdef_dynamic_rate() { # 10 | local c=0 c6=0 11 | 12 | [ ! -e /tmp/dhcp.leases -a \ 13 | ! -e /var/dhcp6.leases ] && return 14 | 15 | [ -e /tmp/dhcp.leases ] && \ 16 | c=$(wc -l < /tmp/dhcp.leases 2>/dev/null) 17 | [ -e /var/dhcp6.leases ] && \ 18 | c6=$(wc -l < /var/dhcp6.leases 2>/dev/null) 19 | [ $c -eq 0 -a $c6 -eq 0 ] && \ 20 | { echo 12500; return; } 21 | 22 | echo $(($1 / ($c + $c6))) 23 | } 24 | 25 | qosdef_append_chain_dym() { # 26 | local cidr cidr6 27 | local operator rate 28 | local hook=$1 name=$2 bandwidth=$3 29 | 30 | config_get cidr default 'dynamic_cidr' 31 | config_get cidr6 default 'dynamic_cidr6' 32 | 33 | [ -z "$cidr" -a -z "$cidr6" ] && return 34 | 35 | case "$2" in 36 | download) operator=daddr;; 37 | upload) operator=saddr;; 38 | esac 39 | 40 | rate=$(qosdef_dynamic_rate $bandwidth) 41 | 42 | qosdef_appendx "\tchain $name {\n" 43 | qosdef_append_chain_def filter $hook 0 accept 44 | qosdef_append_rule_limit_whitelist $name 45 | [ -n "$cidr" ] && \ 46 | qosdef_append_rule_ip_limit $cidr $operator kbytes $rate 47 | [ -n "$cidr6" ] && \ 48 | qosdef_append_rule_ip_limit $cidr6 $operator kbytes $rate 49 | qosdef_appendx "\t}\n" 50 | } 51 | 52 | qosdef_flush_dynamic() { 53 | qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-dynamic 54 | } 55 | 56 | # init dynamic qos 57 | qosdef_init_dynamic() { 58 | local dynamic_bw_up dynamic_bw_down limit_enable limit_type 59 | local hook_ul="input" hook_dl="postrouting" 60 | 61 | uci_validate_section nft-qos default default \ 62 | 'limit_enable:bool:0' \ 63 | 'limit_type:maxlength(8)' \ 64 | 'dynamic_bw_up:uinteger:100' \ 65 | 'dynamic_bw_down:uinteger:100' 66 | 67 | [ $? -ne 0 ] && { 68 | logger -t nft-qos-dynamic "validation failed" 69 | return 1 70 | } 71 | 72 | [ $limit_enable -eq 0 -o \ 73 | "$limit_type" = "static" ] && return 1 74 | 75 | # Transfer mbits/s to mbytes/s 76 | # e.g. 100,000 kbits == 12,500 kbytes 77 | dynamic_bw_up=$(($dynamic_bw_up * 1000 / 8)) 78 | dynamic_bw_down=$(($dynamic_bw_down * 1000 / 8)) 79 | 80 | [ -z "$NFT_QOS_HAS_BRIDGE" ] && { 81 | hook_ul="postrouting" 82 | hook_dl="input" 83 | } 84 | 85 | qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-dynamic {\n" 86 | qosdef_append_chain_dym $hook_ul upload $dynamic_bw_up 87 | qosdef_append_chain_dym $hook_dl download $dynamic_bw_down 88 | qosdef_appendx "}\n" 89 | } 90 | -------------------------------------------------------------------------------- /package/files/lib/monitor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/nft-qos/core.sh 7 | 8 | qosdef_monitor_get_ip_handle() { # 9 | echo $(nft list chain $1 nft-qos-monitor $2 -a 2>/dev/null | grep $3 | awk '{print $11}') 10 | } 11 | 12 | qosdef_monitor_add() { # 13 | handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2) 14 | [ -z "$handle_dl" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor download ip daddr $2 counter 15 | handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2) 16 | [ -z "$handle_ul" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor upload ip saddr $2 counter 17 | } 18 | 19 | qosdef_monitor_del() { # 20 | local handle_dl handle_ul 21 | handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2) 22 | handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2) 23 | [ -n "$handle_dl" ] && nft delete handle $handle_dl 24 | [ -n "$handle_ul" ] && nft delete handle $handle_ul 25 | } 26 | 27 | # init qos monitor 28 | qosdef_init_monitor() { 29 | local hook_ul="input" hook_dl="postrouting" 30 | 31 | [ -z "$NFT_QOS_HAS_BRIDGE" ] && { 32 | hook_ul="postrouting" 33 | hook_dl="input" 34 | } 35 | 36 | nft add table $NFT_QOS_INET_FAMILY nft-qos-monitor 37 | nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor upload { type filter hook $hook_ul priority 0\; } 38 | nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor download { type filter hook $hook_dl priority 0\; } 39 | } 40 | -------------------------------------------------------------------------------- /package/files/lib/priority.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/functions/network.sh 7 | . /lib/nft-qos/core.sh 8 | 9 | P1=""; P2=""; P3=""; P4=""; P5=""; P6=""; 10 | P7=""; P8=""; P9=""; P10=""; P11=""; 11 | 12 | _qosdef_handle_protox() { # 13 | case "$1" in 14 | -400) P1="$P1""$2";; 15 | -300) P2="$P2""$2";; 16 | -225) P3="$P3""$2";; 17 | -200) P4="$P4""$2";; 18 | -150) P5="$P5""$2";; 19 | -100) P6="$P6""$2";; 20 | 0) P7="$P7""$2";; 21 | 50) P8="$P8""$2";; 22 | 100) P9="$P9""$2";; 23 | 225) P10="$P10""$2";; 24 | 300) P11="$P11""$2";; 25 | esac 26 | } 27 | 28 | qosdef_handle_protox() { #
29 | local proto prio srv 30 | 31 | config_get proto $1 'protocol' 32 | config_get prio $1 'priority' 33 | config_get srv $1 'service' 34 | 35 | [ -z "$proto" -o \ 36 | -z "$prio" -o \ 37 | -z "$srv" ] && return 38 | 39 | _qosdef_handle_protox $prio \ 40 | "\t\t$proto dport { $srv } accept\n" 41 | } 42 | 43 | qosdef_append_rule_protox() { #
44 | config_foreach qosdef_handle_protox $1 45 | qosdef_appendx \ 46 | "${P1}${P2}${P3}${P4}${P5}${P6}${P7}${P8}${P9}${P10}${P11}" 47 | } 48 | 49 | qosdef_append_chain_priority() { #
50 | local name=$1 device=$3 51 | 52 | qosdef_appendx "\tchain $name {\n" 53 | qosdef_append_chain_ingress filter $device 0 accept 54 | qosdef_append_rule_protox $2 55 | qosdef_appendx "\t}\n" 56 | } 57 | 58 | qosdef_remove_priority() { 59 | qosdef_remove_table netdev nft-qos-priority 60 | } 61 | 62 | # init traffic priority 63 | qosdef_init_priority() { 64 | local priority_enable priority_netdev ifname="br-lan" 65 | 66 | uci_validate_section nft-qos default default \ 67 | 'priority_enable:bool:0' \ 68 | 'priority_netdev:maxlength(8)' 69 | 70 | [ $? -ne 0 ] && { 71 | logger -t nft-qos-priority "validation failed" 72 | return 1 73 | } 74 | 75 | [ $priority_enable -eq 0 ] && return 1 76 | 77 | case "$priority_netdev" in 78 | lan) [ "$(uci_get network.lan.type)" != "bridge" ] && { 79 | network_get_device ifname "$priority_netdev" || \ 80 | ifname="$(uci_get network.lan.ifname)" 81 | } 82 | ;; 83 | wan*) network_get_device ifname "$priority_netdev" || \ 84 | ifname="$(uci_get network.$priority_netdev.ifname)" 85 | esac 86 | 87 | qosdef_appendx "table netdev nft-qos-priority {\n" 88 | qosdef_append_chain_priority filter priority $ifname 89 | qosdef_appendx "}\n" 90 | } 91 | -------------------------------------------------------------------------------- /package/files/lib/static.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/nft-qos/core.sh 7 | 8 | # append rule for static qos 9 | qosdef_append_rule_sta() { #
10 | local ipaddr unit rate 11 | local operator=$2 12 | 13 | config_get ipaddr $1 ipaddr 14 | config_get unit $1 unit $3 15 | config_get rate $1 rate $4 16 | 17 | [ -z "$ipaddr" ] && return 18 | 19 | qosdef_append_rule_ip_limit $ipaddr $operator $unit $rate 20 | } 21 | 22 | # append chain for static qos 23 | qosdef_append_chain_sta() { #
24 | local hook=$1 name=$2 25 | local config=$3 operator 26 | 27 | case "$name" in 28 | download) operator="daddr";; 29 | upload) operator="saddr";; 30 | esac 31 | 32 | qosdef_appendx "\tchain $name {\n" 33 | qosdef_append_chain_def filter $hook 0 accept 34 | qosdef_append_rule_limit_whitelist $name 35 | config_foreach qosdef_append_rule_sta $config $operator $4 $5 36 | qosdef_appendx "\t}\n" 37 | } 38 | 39 | qosdef_flush_static() { 40 | qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-static 41 | } 42 | 43 | # static limit rate init 44 | qosdef_init_static() { 45 | local unit_dl unit_ul rate_dl rate_ul 46 | local limit_enable limit_type hook_ul="prerouting" hook_dl="postrouting" 47 | 48 | uci_validate_section nft-qos default default \ 49 | 'limit_enable:bool:0' \ 50 | 'limit_type:maxlength(8)' \ 51 | 'static_unit_dl:string:kbytes' \ 52 | 'static_unit_ul:string:kbytes' \ 53 | 'static_rate_dl:uinteger:50' \ 54 | 'static_rate_ul:uinteger:50' 55 | 56 | [ $? -ne 0 ] && { 57 | logger -t nft-qos-static "validation failed" 58 | return 1 59 | } 60 | 61 | [ $limit_enable -eq 0 -o \ 62 | $limit_type = "dynamic" ] && return 1 63 | 64 | [ -z "$NFT_QOS_HAS_BRIDGE" ] && { 65 | hook_ul="postrouting" 66 | hook_dl="prerouting" 67 | } 68 | 69 | qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-static {\n" 70 | qosdef_append_chain_sta $hook_ul upload upload $unit_ul $rate_ul 71 | qosdef_append_chain_sta $hook_dl download download $unit_dl $rate_dl 72 | qosdef_appendx "}\n" 73 | } 74 | -------------------------------------------------------------------------------- /package/files/nft-qos-dynamic.hotplug: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/functions.sh 7 | . /lib/nft-qos/core.sh 8 | . /lib/nft-qos/dynamic.sh 9 | 10 | NFT_QOS_DYNAMIC_ON= 11 | 12 | qosdef_validate_section_dynamic() { 13 | local limit_enable limit_type 14 | 15 | uci_validate_section nft-qos default default \ 16 | 'limit_enable:bool:0' \ 17 | 'limit_type:maxlength(8)' 18 | 19 | [ $limit_enable -eq 1 -a \ 20 | "$limit_type" = "dynamic" ] && \ 21 | NFT_QOS_DYNAMIC_ON="y" 22 | } 23 | 24 | 25 | logger -t nft-qos-dynamic "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME" 26 | 27 | case "$ACTION" in 28 | add | update | remove) 29 | qosdef_validate_section_dynamic 30 | [ -z "$NFT_QOS_DYNAMIC_ON" ] && return 31 | 32 | qosdef_init_env 33 | qosdef_flush_dynamic 34 | 35 | qosdef_init_header 36 | qosdef_init_dynamic 37 | qosdef_init_done 38 | qosdef_start 39 | ;; 40 | esac 41 | -------------------------------------------------------------------------------- /package/files/nft-qos-monitor.hotplug: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/nft-qos/monitor.sh 7 | 8 | logger -t nft-qos-monitor "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME" 9 | 10 | case "$ACTION" in 11 | add | update) qosdef_init_env && qosdef_monitor_add $MACADDR $IPADDR $HOSTNAME;; 12 | remove) qosdef_init_env && qosdef_monitor_del $MACADDR $IPADDR $HOSTNAME;; 13 | esac 14 | -------------------------------------------------------------------------------- /package/files/nft-qos.config: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 rosysong@rosinson.com 3 | # 4 | # This is the sample for nft-qos configuration file, 5 | # which will generate a nftables script in /tmp/qos.nft 6 | # 7 | 8 | # Getting Started 9 | # Official site : 10 | # https://netfilter.org/projects/nftables/index.html 11 | # What is nftables : 12 | # https://wiki.nftables.org/wiki-nftables/index.php/Main_Page 13 | # 14 | 15 | # Basic Operations 16 | # Configuring Tables : 17 | # https://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables 18 | # Configuring Chains : 19 | # https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains 20 | # Configuring Rules : 21 | # https://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management 22 | # Quick Reference (recommended) : 23 | # https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes 24 | # https://netfilter.org/projects/nftables/manpage.html 25 | # 26 | 27 | config default default 28 | # Enable Flag for limit rate 29 | option limit_enable '1' 30 | 31 | # Options for enable Static QoS (rate limit) 32 | option limit_type 'static' 33 | # Options for Static QoS (rate limit) 34 | option static_unit_dl 'kbytes' 35 | option static_unit_ul 'kbytes' 36 | option static_rate_dl '50' 37 | option static_rate_ul '50' 38 | 39 | # Options for enable Dynamic QoS 40 | # This option can not compatible with Static QoS 41 | # option limit_type 'dynamic' 42 | 43 | # For Dynamic QoS Samples (unit of bandwidth is Mbps): 44 | option dynamic_cidr '192.168.1.0/24' 45 | option dynamic_cidr6 'AAAA:BBBB::1/64' 46 | option dynamic_bw_up '100' 47 | option dynamic_bw_down '100' 48 | 49 | # White list for static/dynamic limit 50 | # list limit_whitelist '192.168.1.225' 51 | # list limit_whitelist '192.168.1.0/24' 52 | # list limit_whitelist 'ABCD:CDEF::1/64' 53 | 54 | # Options for Traffic Priority 55 | option priority_enable '0' 56 | option priority_netdev 'lan' 57 | 58 | 59 | # 60 | # For Static QoS Rate Limit Samples : 61 | # 62 | # For Download : 63 | #config download 64 | # option hostname 'My PC' 65 | # option unit 'kbytes' 66 | # option ipaddr '192.168.1.224' 67 | # option rate '128' 68 | # 69 | # For Upload : 70 | #config upload 71 | # option hostname 'office-pc' 72 | # option unit 'mbytes' 73 | # option ipaddr 'ABCD:FFED::1/64' 74 | # option rate '1024' 75 | # 76 | # 77 | # Traffic Priority Samples : 78 | # 79 | # protocol : tcp, udp, udplite, sctp, dccp, tcp is default 80 | # priority : integer between 1-11, 1 is default 81 | # service : you can input a integer or service name, e.g. '22', '11-22', 'telnet', 'ssh, http, ftp', etc 82 | # 83 | #config priority 84 | # option protocol 'tcp' 85 | # option priority '-400' 86 | # option service '23' 87 | # option comment '?' 88 | # 89 | #config priority 90 | # option protocol 'udp' 91 | # option priority '-400' 92 | # option service 'https' 93 | # option comment '?' 94 | # 95 | #config priority 96 | # option protocol 'dccp' 97 | # option priority '0' 98 | # option service '22-35' 99 | # option comment '?' 100 | # 101 | #config priority 102 | # option protocol 'dccp' 103 | # option priority '300' 104 | # option service 'ftp,ssh,http' 105 | # option comment '?' 106 | # 107 | -------------------------------------------------------------------------------- /package/files/nft-qos.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | # 3 | # Copyright (C) 2018 rosysong@rosinson.com 4 | # 5 | 6 | . /lib/nft-qos/core.sh 7 | . /lib/nft-qos/monitor.sh 8 | . /lib/nft-qos/dynamic.sh 9 | . /lib/nft-qos/static.sh 10 | . /lib/nft-qos/priority.sh 11 | 12 | START=99 13 | USE_PROCD=1 14 | 15 | service_triggers() { 16 | procd_add_reload_trigger nft-qos 17 | } 18 | 19 | start_service() { 20 | config_load nft-qos 21 | 22 | qosdef_init_env 23 | qosdef_flush_static 24 | qosdef_flush_dynamic 25 | qosdef_remove_priority 26 | 27 | qosdef_init_header 28 | qosdef_init_monitor 29 | qosdef_init_dynamic 30 | qosdef_init_static 31 | qosdef_init_priority 32 | qosdef_init_done 33 | qosdef_start 34 | } 35 | 36 | stop_service() { 37 | qosdef_flush_dynamic 38 | qosdef_flush_static 39 | qosdef_remove_priority 40 | qosdef_clean_cache 41 | } 42 | -------------------------------------------------------------------------------- /previews/dynamic-qos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosywrt/nft-qos/2458d96e93964df4366cc01aa02a4b2296188eb6/previews/dynamic-qos.png -------------------------------------------------------------------------------- /previews/realtime-rate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosywrt/nft-qos/2458d96e93964df4366cc01aa02a4b2296188eb6/previews/realtime-rate.gif -------------------------------------------------------------------------------- /previews/static-qos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosywrt/nft-qos/2458d96e93964df4366cc01aa02a4b2296188eb6/previews/static-qos.png -------------------------------------------------------------------------------- /previews/traffic-priority.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosywrt/nft-qos/2458d96e93964df4366cc01aa02a4b2296188eb6/previews/traffic-priority.png --------------------------------------------------------------------------------