├── 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 |

26 |
27 | ## Dynamic QoS
28 | 
29 |
30 | ## Static QoS
31 | 
32 |
33 | ## Traffic priority (1 is the highest)
34 | 
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 |
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 |
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
--------------------------------------------------------------------------------